On 1/5/21 2:08 AM, Bjorn Andersson wrote:
> On Tue 22 Dec 04:57 CST 2020, Arnaud Pouliquen wrote:
> 
>> Add the new ops introduced by the rpmsg_ns series and used
>> by the rpmsg_ctrl driver to instantiate a new rpmsg channel.
>>
> 
> This is nice for completeness sake, but I don't think it makes sense for
> transports that has the nameserver "builtin" to the transport itself.
> 
> I.e. if we have the NS sitting on top of GLINK and the remote firmware
> sends a "create channel" message, then this code would cause Linux to
> send a in-transport "create channel" message back to the remote side in
> hope that it would be willing to talk on that channel - but that would
> imply that the remote side needs to have registered a rpmsg device
> related to that service name - in which case it already sent a
> in-transport "create channel" message.

That was one of my main concerns about this series. I'm not familiar enough with
these drivers to make sure my proposal was 100% compatible...
How is the mapping between between the local and remote endpoints when the DST
address is not specified by the Linux application?

Regards,
Arnaud

> 
> Regards,
> Bjorn
> 
>> Signed-off-by: Arnaud Pouliquen <arnaud.pouliq...@foss.st.com>
>> ---
>>  drivers/rpmsg/qcom_glink_native.c | 94 ++++++++++++++++++++++++-------
>>  1 file changed, 75 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/rpmsg/qcom_glink_native.c 
>> b/drivers/rpmsg/qcom_glink_native.c
>> index 27a05167c18c..d74c338de077 100644
>> --- a/drivers/rpmsg/qcom_glink_native.c
>> +++ b/drivers/rpmsg/qcom_glink_native.c
>> @@ -205,6 +205,9 @@ static const struct rpmsg_endpoint_ops 
>> glink_endpoint_ops;
>>  #define GLINK_FEATURE_INTENTLESS    BIT(1)
>>  
>>  static void qcom_glink_rx_done_work(struct work_struct *work);
>> +static struct rpmsg_device *
>> +qcom_glink_create_rpdev(struct qcom_glink *glink,
>> +                    struct rpmsg_channel_info *chinfo);
>>  
>>  static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink 
>> *glink,
>>                                                    const char *name)
>> @@ -1203,6 +1206,37 @@ static int qcom_glink_announce_create(struct 
>> rpmsg_device *rpdev)
>>      return 0;
>>  }
>>  
>> +static struct rpmsg_device *
>> +qcom_glink_create_channel(struct rpmsg_device *rp_parent,
>> +                      struct rpmsg_channel_info *chinfo)
>> +{
>> +    struct glink_channel *channel = to_glink_channel(rp_parent->ept);
>> +    struct qcom_glink *glink = channel->glink;
>> +    struct rpmsg_device *rpdev;
>> +    const char *name = chinfo->name;
>> +
>> +    channel = qcom_glink_alloc_channel(glink, name);
>> +    if (IS_ERR(channel))
>> +            return ERR_PTR(PTR_ERR(channel));
>> +
>> +    rpdev = qcom_glink_create_rpdev(glink, chinfo);
>> +    if (!IS_ERR(rpdev)) {
>> +            rpdev->ept = &channel->ept;
>> +            channel->rpdev = rpdev;
>> +    }
>> +
>> +    return rpdev;
>> +}
>> +
>> +static int qcom_glink_release_channel(struct rpmsg_device *rpdev,
>> +                                  struct rpmsg_channel_info *chinfo)
>> +{
>> +    struct glink_channel *channel = to_glink_channel(rpdev->ept);
>> +    struct qcom_glink *glink = channel->glink;
>> +
>> +    return rpmsg_unregister_device(glink->dev, chinfo);
>> +}
>> +
>>  static void qcom_glink_destroy_ept(struct rpmsg_endpoint *ept)
>>  {
>>      struct glink_channel *channel = to_glink_channel(ept);
>> @@ -1359,6 +1393,8 @@ static struct device_node 
>> *qcom_glink_match_channel(struct device_node *node,
>>  static const struct rpmsg_device_ops glink_device_ops = {
>>      .create_ept = qcom_glink_create_ept,
>>      .announce_create = qcom_glink_announce_create,
>> +    .create_channel = qcom_glink_create_channel,
>> +    .release_channel = qcom_glink_release_channel,
>>  };
>>  
>>  static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
>> @@ -1376,13 +1412,45 @@ static void qcom_glink_rpdev_release(struct device 
>> *dev)
>>      kfree(rpdev);
>>  }
>>  
>> +static struct rpmsg_device *
>> +qcom_glink_create_rpdev(struct qcom_glink *glink,
>> +                    struct rpmsg_channel_info *chinfo)
>> +{
>> +    struct rpmsg_device *rpdev;
>> +    struct device_node *node;
>> +    int ret;
>> +
>> +    rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL);
>> +    if (!rpdev)
>> +            return ERR_PTR(-ENOMEM);
>> +
>> +    strncpy(rpdev->id.name, chinfo->name, RPMSG_NAME_SIZE);
>> +    rpdev->src = chinfo->src;
>> +    rpdev->dst = chinfo->dst;
>> +    rpdev->ops = &glink_device_ops;
>> +
>> +    node = qcom_glink_match_channel(glink->dev->of_node, chinfo->name);
>> +    rpdev->dev.of_node = node;
>> +    rpdev->dev.parent = glink->dev;
>> +    rpdev->dev.release = qcom_glink_rpdev_release;
>> +    rpdev->driver_override = (char *)chinfo->driver_override;
>> +
>> +    ret = rpmsg_register_device(rpdev);
>> +    if (ret) {
>> +            kfree(rpdev);
>> +            return ERR_PTR(ret);
>> +    }
>> +
>> +    return rpdev;
>> +}
>> +
>>  static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid,
>>                            char *name)
>>  {
>>      struct glink_channel *channel;
>>      struct rpmsg_device *rpdev;
>>      bool create_device = false;
>> -    struct device_node *node;
>> +    struct rpmsg_channel_info chinfo;
>>      int lcid;
>>      int ret;
>>      unsigned long flags;
>> @@ -1416,27 +1484,15 @@ static int qcom_glink_rx_open(struct qcom_glink 
>> *glink, unsigned int rcid,
>>      complete_all(&channel->open_req);
>>  
>>      if (create_device) {
>> -            rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL);
>> -            if (!rpdev) {
>> -                    ret = -ENOMEM;
>> +            strncpy(chinfo.name, channel->name, sizeof(chinfo.name));
>> +            chinfo.src = RPMSG_ADDR_ANY;
>> +            chinfo.dst = RPMSG_ADDR_ANY;
>> +            rpdev = qcom_glink_create_rpdev(glink, &chinfo);
>> +            if (IS_ERR(rpdev)) {
>> +                    ret = PTR_ERR(rpdev);
>>                      goto rcid_remove;
>>              }
>> -
>>              rpdev->ept = &channel->ept;
>> -            strncpy(rpdev->id.name, name, RPMSG_NAME_SIZE);
>> -            rpdev->src = RPMSG_ADDR_ANY;
>> -            rpdev->dst = RPMSG_ADDR_ANY;
>> -            rpdev->ops = &glink_device_ops;
>> -
>> -            node = qcom_glink_match_channel(glink->dev->of_node, name);
>> -            rpdev->dev.of_node = node;
>> -            rpdev->dev.parent = glink->dev;
>> -            rpdev->dev.release = qcom_glink_rpdev_release;
>> -
>> -            ret = rpmsg_register_device(rpdev);
>> -            if (ret)
>> -                    goto rcid_remove;
>> -
>>              channel->rpdev = rpdev;
>>      }
>>  
>> -- 
>> 2.17.1
>>

Reply via email to