.. | .. |
---|
222 | 222 | |
---|
223 | 223 | channel->glink = glink; |
---|
224 | 224 | channel->name = kstrdup(name, GFP_KERNEL); |
---|
| 225 | + if (!channel->name) { |
---|
| 226 | + kfree(channel); |
---|
| 227 | + return ERR_PTR(-ENOMEM); |
---|
| 228 | + } |
---|
225 | 229 | |
---|
226 | 230 | init_completion(&channel->open_req); |
---|
227 | 231 | init_completion(&channel->open_ack); |
---|
.. | .. |
---|
553 | 557 | break; |
---|
554 | 558 | case GLINK_VERSION_1: |
---|
555 | 559 | glink->features &= features; |
---|
556 | | - /* FALLTHROUGH */ |
---|
| 560 | + fallthrough; |
---|
557 | 561 | default: |
---|
558 | 562 | qcom_glink_send_version_ack(glink); |
---|
559 | 563 | break; |
---|
.. | .. |
---|
584 | 588 | break; |
---|
585 | 589 | |
---|
586 | 590 | glink->features &= features; |
---|
587 | | - /* FALLTHROUGH */ |
---|
| 591 | + fallthrough; |
---|
588 | 592 | default: |
---|
589 | 593 | qcom_glink_send_version(glink); |
---|
590 | 594 | break; |
---|
.. | .. |
---|
914 | 918 | struct intent_pair intents[]; |
---|
915 | 919 | } __packed * msg; |
---|
916 | 920 | |
---|
917 | | - const size_t msglen = sizeof(*msg) + sizeof(struct intent_pair) * count; |
---|
| 921 | + const size_t msglen = struct_size(msg, intents, count); |
---|
918 | 922 | int ret; |
---|
919 | 923 | int i; |
---|
920 | 924 | unsigned long flags; |
---|
.. | .. |
---|
929 | 933 | spin_unlock_irqrestore(&glink->idr_lock, flags); |
---|
930 | 934 | if (!channel) { |
---|
931 | 935 | dev_err(glink->dev, "intents for non-existing channel\n"); |
---|
| 936 | + qcom_glink_rx_advance(glink, ALIGN(msglen, 8)); |
---|
932 | 937 | return; |
---|
933 | 938 | } |
---|
934 | 939 | |
---|
.. | .. |
---|
1472 | 1477 | cancel_work_sync(&channel->intent_work); |
---|
1473 | 1478 | |
---|
1474 | 1479 | if (channel->rpdev) { |
---|
1475 | | - strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); |
---|
| 1480 | + strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); |
---|
1476 | 1481 | chinfo.src = RPMSG_ADDR_ANY; |
---|
1477 | 1482 | chinfo.dst = RPMSG_ADDR_ANY; |
---|
1478 | 1483 | |
---|
.. | .. |
---|
1575 | 1580 | kfree(dcmd); |
---|
1576 | 1581 | } |
---|
1577 | 1582 | |
---|
| 1583 | +static ssize_t rpmsg_name_show(struct device *dev, |
---|
| 1584 | + struct device_attribute *attr, char *buf) |
---|
| 1585 | +{ |
---|
| 1586 | + int ret = 0; |
---|
| 1587 | + const char *name; |
---|
| 1588 | + |
---|
| 1589 | + ret = of_property_read_string(dev->of_node, "label", &name); |
---|
| 1590 | + if (ret < 0) |
---|
| 1591 | + name = dev->of_node->name; |
---|
| 1592 | + |
---|
| 1593 | + return snprintf(buf, RPMSG_NAME_SIZE, "%s\n", name); |
---|
| 1594 | +} |
---|
| 1595 | +static DEVICE_ATTR_RO(rpmsg_name); |
---|
| 1596 | + |
---|
| 1597 | +static struct attribute *qcom_glink_attrs[] = { |
---|
| 1598 | + &dev_attr_rpmsg_name.attr, |
---|
| 1599 | + NULL |
---|
| 1600 | +}; |
---|
| 1601 | +ATTRIBUTE_GROUPS(qcom_glink); |
---|
| 1602 | + |
---|
| 1603 | +static void qcom_glink_device_release(struct device *dev) |
---|
| 1604 | +{ |
---|
| 1605 | + struct rpmsg_device *rpdev = to_rpmsg_device(dev); |
---|
| 1606 | + struct glink_channel *channel = to_glink_channel(rpdev->ept); |
---|
| 1607 | + |
---|
| 1608 | + /* Release qcom_glink_alloc_channel() reference */ |
---|
| 1609 | + kref_put(&channel->refcount, qcom_glink_channel_release); |
---|
| 1610 | + kfree(rpdev); |
---|
| 1611 | +} |
---|
| 1612 | + |
---|
| 1613 | +static int qcom_glink_create_chrdev(struct qcom_glink *glink) |
---|
| 1614 | +{ |
---|
| 1615 | + struct rpmsg_device *rpdev; |
---|
| 1616 | + struct glink_channel *channel; |
---|
| 1617 | + |
---|
| 1618 | + rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL); |
---|
| 1619 | + if (!rpdev) |
---|
| 1620 | + return -ENOMEM; |
---|
| 1621 | + |
---|
| 1622 | + channel = qcom_glink_alloc_channel(glink, "rpmsg_chrdev"); |
---|
| 1623 | + if (IS_ERR(channel)) { |
---|
| 1624 | + kfree(rpdev); |
---|
| 1625 | + return PTR_ERR(channel); |
---|
| 1626 | + } |
---|
| 1627 | + channel->rpdev = rpdev; |
---|
| 1628 | + |
---|
| 1629 | + rpdev->ept = &channel->ept; |
---|
| 1630 | + rpdev->ops = &glink_device_ops; |
---|
| 1631 | + rpdev->dev.parent = glink->dev; |
---|
| 1632 | + rpdev->dev.release = qcom_glink_device_release; |
---|
| 1633 | + |
---|
| 1634 | + return rpmsg_chrdev_register_device(rpdev); |
---|
| 1635 | +} |
---|
| 1636 | + |
---|
1578 | 1637 | struct qcom_glink *qcom_glink_native_probe(struct device *dev, |
---|
1579 | 1638 | unsigned long features, |
---|
1580 | 1639 | struct qcom_glink_pipe *rx, |
---|
.. | .. |
---|
1605 | 1664 | idr_init(&glink->lcids); |
---|
1606 | 1665 | idr_init(&glink->rcids); |
---|
1607 | 1666 | |
---|
| 1667 | + glink->dev->groups = qcom_glink_groups; |
---|
| 1668 | + |
---|
| 1669 | + ret = device_add_groups(dev, qcom_glink_groups); |
---|
| 1670 | + if (ret) |
---|
| 1671 | + dev_err(dev, "failed to add groups\n"); |
---|
| 1672 | + |
---|
1608 | 1673 | ret = of_property_read_string(dev->of_node, "label", &glink->name); |
---|
1609 | 1674 | if (ret < 0) |
---|
1610 | 1675 | glink->name = dev->of_node->name; |
---|
.. | .. |
---|
1634 | 1699 | if (ret) |
---|
1635 | 1700 | return ERR_PTR(ret); |
---|
1636 | 1701 | |
---|
| 1702 | + ret = qcom_glink_create_chrdev(glink); |
---|
| 1703 | + if (ret) |
---|
| 1704 | + dev_err(glink->dev, "failed to register chrdev\n"); |
---|
| 1705 | + |
---|
1637 | 1706 | return glink; |
---|
1638 | 1707 | } |
---|
1639 | 1708 | EXPORT_SYMBOL_GPL(qcom_glink_native_probe); |
---|