Pull sbs into release branch
[powerpc.git] / drivers / infiniband / core / sysfs.c
index 1f1743c..000c086 100644 (file)
@@ -68,7 +68,7 @@ struct port_table_attribute {
        int                     index;
 };
 
-static inline int ibdev_is_alive(const struct ib_device *dev) 
+static inline int ibdev_is_alive(const struct ib_device *dev)
 {
        return dev->reg_state == IB_DEV_REGISTERED;
 }
@@ -112,7 +112,7 @@ static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
                return ret;
 
        return sprintf(buf, "%d: %s\n", attr.state,
-                      attr.state >= 0 && attr.state <= ARRAY_SIZE(state_name) ?
+                      attr.state >= 0 && attr.state < ARRAY_SIZE(state_name) ?
                       state_name[attr.state] : "UNKNOWN");
 }
 
@@ -336,7 +336,7 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
        switch (width) {
        case 4:
                ret = sprintf(buf, "%u\n", (out_mad->data[40 + offset / 8] >>
-                                           (offset % 4)) & 0xf);
+                                           (4 - (offset % 8))) & 0xf);
                break;
        case 8:
                ret = sprintf(buf, "%u\n", out_mad->data[40 + offset / 8]);
@@ -445,13 +445,7 @@ static int ib_device_uevent(struct class_device *cdev, char **envp,
                return -ENOMEM;
 
        /*
-        * It might be nice to pass the node GUID with the event, but
-        * right now the only way to get it is to query the device
-        * provider, and this can crash during device removal because
-        * we are will be running after driver removal has started.
-        * We could add a node_guid field to struct ib_device, or we
-        * could just let userspace read the node GUID from sysfs when
-        * devices are added.
+        * It would be nice to pass the node GUID with the event...
         */
 
        envp[i] = NULL;
@@ -478,8 +472,10 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *,
                        goto err;
 
                if (snprintf(element->name, sizeof(element->name),
-                            "%d", i) >= sizeof(element->name))
+                            "%d", i) >= sizeof(element->name)) {
+                       kfree(element);
                        goto err;
+               }
 
                element->attr.attr.name  = element->name;
                element->attr.attr.mode  = S_IRUGO;
@@ -593,10 +589,11 @@ static ssize_t show_node_type(struct class_device *cdev, char *buf)
                return -ENODEV;
 
        switch (dev->node_type) {
-       case IB_NODE_CA:     return sprintf(buf, "%d: CA\n", dev->node_type);
-       case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
-       case IB_NODE_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);
-       default:             return sprintf(buf, "%d: <unknown>\n", dev->node_type);
+       case RDMA_NODE_IB_CA:     return sprintf(buf, "%d: CA\n", dev->node_type);
+       case RDMA_NODE_RNIC:      return sprintf(buf, "%d: RNIC\n", dev->node_type);
+       case RDMA_NODE_IB_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
+       case RDMA_NODE_IB_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);
+       default:                  return sprintf(buf, "%d: <unknown>\n", dev->node_type);
        }
 }
 
@@ -623,31 +620,53 @@ static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
 static ssize_t show_node_guid(struct class_device *cdev, char *buf)
 {
        struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
-       struct ib_device_attr attr;
-       ssize_t ret;
 
        if (!ibdev_is_alive(dev))
                return -ENODEV;
 
-       ret = ib_query_device(dev, &attr);
+       return sprintf(buf, "%04x:%04x:%04x:%04x\n",
+                      be16_to_cpu(((__be16 *) &dev->node_guid)[0]),
+                      be16_to_cpu(((__be16 *) &dev->node_guid)[1]),
+                      be16_to_cpu(((__be16 *) &dev->node_guid)[2]),
+                      be16_to_cpu(((__be16 *) &dev->node_guid)[3]));
+}
+
+static ssize_t show_node_desc(struct class_device *cdev, char *buf)
+{
+       struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+
+       return sprintf(buf, "%.64s\n", dev->node_desc);
+}
+
+static ssize_t set_node_desc(struct class_device *cdev, const char *buf,
+                             size_t count)
+{
+       struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+       struct ib_device_modify desc = {};
+       int ret;
+
+       if (!dev->modify_device)
+               return -EIO;
+
+       memcpy(desc.node_desc, buf, min_t(int, count, 64));
+       ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc);
        if (ret)
                return ret;
 
-       return sprintf(buf, "%04x:%04x:%04x:%04x\n",
-                      be16_to_cpu(((__be16 *) &attr.node_guid)[0]),
-                      be16_to_cpu(((__be16 *) &attr.node_guid)[1]),
-                      be16_to_cpu(((__be16 *) &attr.node_guid)[2]),
-                      be16_to_cpu(((__be16 *) &attr.node_guid)[3]));
+       return count;
 }
 
 static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
 static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
 static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
+static CLASS_DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc,
+                        set_node_desc);
 
 static struct class_device_attribute *ib_class_attributes[] = {
        &class_device_attr_node_type,
        &class_device_attr_sys_image_guid,
-       &class_device_attr_node_guid
+       &class_device_attr_node_guid,
+       &class_device_attr_node_desc
 };
 
 static struct class ib_class = {
@@ -690,13 +709,11 @@ int ib_device_register_sysfs(struct ib_device *device)
        if (ret)
                goto err_put;
 
-       if (device->node_type == IB_NODE_SWITCH) {
+       if (device->node_type == RDMA_NODE_IB_SWITCH) {
                ret = add_port(device, 0);
                if (ret)
                        goto err_put;
        } else {
-               int i;
-
                for (i = 1; i <= device->phys_port_cnt; ++i) {
                        ret = add_port(device, i);
                        if (ret)