diff options
Diffstat (limited to 'drivers/infiniband/core/sysfs.c')
-rw-r--r-- | drivers/infiniband/core/sysfs.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 5982d687a00..15121cb5a1f 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -112,7 +112,7 @@ static ssize_t state_show(struct ib_port *p, struct port_attribute *unused, | |||
112 | return ret; | 112 | return ret; |
113 | 113 | ||
114 | return sprintf(buf, "%d: %s\n", attr.state, | 114 | return sprintf(buf, "%d: %s\n", attr.state, |
115 | attr.state >= 0 && attr.state <= ARRAY_SIZE(state_name) ? | 115 | attr.state >= 0 && attr.state < ARRAY_SIZE(state_name) ? |
116 | state_name[attr.state] : "UNKNOWN"); | 116 | state_name[attr.state] : "UNKNOWN"); |
117 | } | 117 | } |
118 | 118 | ||
@@ -472,8 +472,10 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *, | |||
472 | goto err; | 472 | goto err; |
473 | 473 | ||
474 | if (snprintf(element->name, sizeof(element->name), | 474 | if (snprintf(element->name, sizeof(element->name), |
475 | "%d", i) >= sizeof(element->name)) | 475 | "%d", i) >= sizeof(element->name)) { |
476 | kfree(element); | ||
476 | goto err; | 477 | goto err; |
478 | } | ||
477 | 479 | ||
478 | element->attr.attr.name = element->name; | 480 | element->attr.attr.name = element->name; |
479 | element->attr.attr.mode = S_IRUGO; | 481 | element->attr.attr.mode = S_IRUGO; |
@@ -628,14 +630,42 @@ static ssize_t show_node_guid(struct class_device *cdev, char *buf) | |||
628 | be16_to_cpu(((__be16 *) &dev->node_guid)[3])); | 630 | be16_to_cpu(((__be16 *) &dev->node_guid)[3])); |
629 | } | 631 | } |
630 | 632 | ||
633 | static ssize_t show_node_desc(struct class_device *cdev, char *buf) | ||
634 | { | ||
635 | struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); | ||
636 | |||
637 | return sprintf(buf, "%.64s\n", dev->node_desc); | ||
638 | } | ||
639 | |||
640 | static ssize_t set_node_desc(struct class_device *cdev, const char *buf, | ||
641 | size_t count) | ||
642 | { | ||
643 | struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); | ||
644 | struct ib_device_modify desc = {}; | ||
645 | int ret; | ||
646 | |||
647 | if (!dev->modify_device) | ||
648 | return -EIO; | ||
649 | |||
650 | memcpy(desc.node_desc, buf, min_t(int, count, 64)); | ||
651 | ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc); | ||
652 | if (ret) | ||
653 | return ret; | ||
654 | |||
655 | return count; | ||
656 | } | ||
657 | |||
631 | static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); | 658 | static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); |
632 | static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL); | 659 | static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL); |
633 | static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL); | 660 | static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL); |
661 | static CLASS_DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc, | ||
662 | set_node_desc); | ||
634 | 663 | ||
635 | static struct class_device_attribute *ib_class_attributes[] = { | 664 | static struct class_device_attribute *ib_class_attributes[] = { |
636 | &class_device_attr_node_type, | 665 | &class_device_attr_node_type, |
637 | &class_device_attr_sys_image_guid, | 666 | &class_device_attr_sys_image_guid, |
638 | &class_device_attr_node_guid | 667 | &class_device_attr_node_guid, |
668 | &class_device_attr_node_desc | ||
639 | }; | 669 | }; |
640 | 670 | ||
641 | static struct class ib_class = { | 671 | static struct class ib_class = { |