hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/infiniband/core/sysfs.c
....@@ -43,6 +43,7 @@
4343 #include <rdma/ib_mad.h>
4444 #include <rdma/ib_pma.h>
4545 #include <rdma/ib_cache.h>
46
+#include <rdma/rdma_counter.h>
4647
4748 struct ib_port;
4849
....@@ -57,8 +58,8 @@
5758 struct ib_device *ibdev;
5859 struct gid_attr_group *gid_attr_group;
5960 struct attribute_group gid_group;
60
- struct attribute_group pkey_group;
61
- struct attribute_group *pma_table;
61
+ struct attribute_group *pkey_group;
62
+ const struct attribute_group *pma_table;
6263 struct attribute_group *hw_stats_ag;
6364 struct rdma_hw_stats *hw_stats;
6465 u8 port_num;
....@@ -288,6 +289,24 @@
288289 ib_width_enum_to_int(attr.active_width), speed);
289290 }
290291
292
+static const char *phys_state_to_str(enum ib_port_phys_state phys_state)
293
+{
294
+ static const char * phys_state_str[] = {
295
+ "<unknown>",
296
+ "Sleep",
297
+ "Polling",
298
+ "Disabled",
299
+ "PortConfigurationTraining",
300
+ "LinkUp",
301
+ "LinkErrorRecovery",
302
+ "Phy Test",
303
+ };
304
+
305
+ if (phys_state < ARRAY_SIZE(phys_state_str))
306
+ return phys_state_str[phys_state];
307
+ return "<unknown>";
308
+}
309
+
291310 static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
292311 char *buf)
293312 {
....@@ -299,16 +318,8 @@
299318 if (ret)
300319 return ret;
301320
302
- switch (attr.phys_state) {
303
- case 1: return sprintf(buf, "1: Sleep\n");
304
- case 2: return sprintf(buf, "2: Polling\n");
305
- case 3: return sprintf(buf, "3: Disabled\n");
306
- case 4: return sprintf(buf, "4: PortConfigurationTraining\n");
307
- case 5: return sprintf(buf, "5: LinkUp\n");
308
- case 6: return sprintf(buf, "6: LinkErrorRecovery\n");
309
- case 7: return sprintf(buf, "7: Phy Test\n");
310
- default: return sprintf(buf, "%d: <unknown>\n", attr.phys_state);
311
- }
321
+ return sprintf(buf, "%d: %s\n", attr.phys_state,
322
+ phys_state_to_str(attr.phys_state));
312323 }
313324
314325 static ssize_t link_layer_show(struct ib_port *p, struct port_attribute *unused,
....@@ -349,10 +360,15 @@
349360
350361 static size_t print_ndev(const struct ib_gid_attr *gid_attr, char *buf)
351362 {
352
- if (!gid_attr->ndev)
353
- return -EINVAL;
363
+ struct net_device *ndev;
364
+ size_t ret = -EINVAL;
354365
355
- return sprintf(buf, "%s\n", gid_attr->ndev->name);
366
+ rcu_read_lock();
367
+ ndev = rcu_dereference(gid_attr->ndev);
368
+ if (ndev)
369
+ ret = sprintf(buf, "%s\n", ndev->name);
370
+ rcu_read_unlock();
371
+ return ret;
356372 }
357373
358374 static size_t print_gid_type(const struct ib_gid_attr *gid_attr, char *buf)
....@@ -371,7 +387,8 @@
371387
372388 gid_attr = rdma_get_gid_attr(p->ibdev, p->port_num, tab_attr->index);
373389 if (IS_ERR(gid_attr))
374
- return PTR_ERR(gid_attr);
390
+ /* -EINVAL is returned for user space compatibility reasons. */
391
+ return -EINVAL;
375392
376393 ret = print(gid_attr, buf);
377394 rdma_put_gid_attr(gid_attr);
....@@ -462,11 +479,11 @@
462479 u16 out_mad_pkey_index = 0;
463480 ssize_t ret;
464481
465
- if (!dev->process_mad)
482
+ if (!dev->ops.process_mad)
466483 return -ENOSYS;
467484
468
- in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL);
469
- out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
485
+ in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
486
+ out_mad = kzalloc(sizeof(*out_mad), GFP_KERNEL);
470487 if (!in_mad || !out_mad) {
471488 ret = -ENOMEM;
472489 goto out;
....@@ -481,11 +498,9 @@
481498 if (attr != IB_PMA_CLASS_PORT_INFO)
482499 in_mad->data[41] = port_num; /* PortSelect field */
483500
484
- if ((dev->process_mad(dev, IB_MAD_IGNORE_MKEY,
485
- port_num, NULL, NULL,
486
- (const struct ib_mad_hdr *)in_mad, mad_size,
487
- (struct ib_mad_hdr *)out_mad, &mad_size,
488
- &out_mad_pkey_index) &
501
+ if ((dev->ops.process_mad(dev, IB_MAD_IGNORE_MKEY, port_num, NULL, NULL,
502
+ in_mad, out_mad, &mad_size,
503
+ &out_mad_pkey_index) &
489504 (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) !=
490505 (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) {
491506 ret = -EINVAL;
....@@ -639,17 +654,17 @@
639654 NULL
640655 };
641656
642
-static struct attribute_group pma_group = {
657
+static const struct attribute_group pma_group = {
643658 .name = "counters",
644659 .attrs = pma_attrs
645660 };
646661
647
-static struct attribute_group pma_group_ext = {
662
+static const struct attribute_group pma_group_ext = {
648663 .name = "counters",
649664 .attrs = pma_attrs_ext
650665 };
651666
652
-static struct attribute_group pma_group_noietf = {
667
+static const struct attribute_group pma_group_noietf = {
653668 .name = "counters",
654669 .attrs = pma_attrs_noietf
655670 };
....@@ -667,11 +682,16 @@
667682 kfree(p->gid_group.attrs);
668683 }
669684
670
- if (p->pkey_group.attrs) {
671
- for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
672
- kfree(a);
685
+ if (p->pkey_group) {
686
+ if (p->pkey_group->attrs) {
687
+ for (i = 0; (a = p->pkey_group->attrs[i]); ++i)
688
+ kfree(a);
673689
674
- kfree(p->pkey_group.attrs);
690
+ kfree(p->pkey_group->attrs);
691
+ }
692
+
693
+ kfree(p->pkey_group);
694
+ p->pkey_group = NULL;
675695 }
676696
677697 kfree(p);
....@@ -759,8 +779,8 @@
759779 * Figure out which counter table to use depending on
760780 * the device capabilities.
761781 */
762
-static struct attribute_group *get_counter_table(struct ib_device *dev,
763
- int port_num)
782
+static const struct attribute_group *get_counter_table(struct ib_device *dev,
783
+ int port_num)
764784 {
765785 struct ib_class_port_info cpi;
766786
....@@ -786,7 +806,7 @@
786806
787807 if (time_is_after_eq_jiffies(stats->timestamp + stats->lifespan))
788808 return 0;
789
- ret = dev->get_hw_stats(dev, stats, port_num, index);
809
+ ret = dev->ops.get_hw_stats(dev, stats, port_num, index);
790810 if (ret < 0)
791811 return ret;
792812 if (ret == stats->num_counters)
....@@ -795,9 +815,12 @@
795815 return 0;
796816 }
797817
798
-static ssize_t print_hw_stat(struct rdma_hw_stats *stats, int index, char *buf)
818
+static ssize_t print_hw_stat(struct ib_device *dev, int port_num,
819
+ struct rdma_hw_stats *stats, int index, char *buf)
799820 {
800
- return sprintf(buf, "%llu\n", stats->value[index]);
821
+ u64 v = rdma_counter_get_hwstat_value(dev, port_num, index);
822
+
823
+ return sprintf(buf, "%llu\n", stats->value[index] + v);
801824 }
802825
803826 static ssize_t show_hw_stats(struct kobject *kobj, struct attribute *attr,
....@@ -823,7 +846,7 @@
823846 ret = update_hw_stats(dev, stats, hsa->port_num, hsa->index);
824847 if (ret)
825848 goto unlock;
826
- ret = print_hw_stat(stats, hsa->index, buf);
849
+ ret = print_hw_stat(dev, hsa->port_num, stats, hsa->index, buf);
827850 unlock:
828851 mutex_unlock(&stats->lock);
829852
....@@ -946,7 +969,7 @@
946969 struct rdma_hw_stats *stats;
947970 int i, ret;
948971
949
- stats = device->alloc_hw_stats(device, port_num);
972
+ stats = device->ops.alloc_hw_stats(device, port_num);
950973
951974 if (!stats)
952975 return;
....@@ -964,8 +987,8 @@
964987 if (!hsag)
965988 goto err_free_stats;
966989
967
- ret = device->get_hw_stats(device, stats, port_num,
968
- stats->num_counters);
990
+ ret = device->ops.get_hw_stats(device, stats, port_num,
991
+ stats->num_counters);
969992 if (ret != stats->num_counters)
970993 goto err_free_hsag;
971994
....@@ -994,6 +1017,8 @@
9941017 goto err;
9951018 port->hw_stats_ag = hsag;
9961019 port->hw_stats = stats;
1020
+ if (device->port_data)
1021
+ device->port_data[port_num].hw_stats = stats;
9971022 } else {
9981023 struct kobject *kobj = &device->dev.kobj;
9991024 ret = sysfs_create_group(kobj, hsag);
....@@ -1015,10 +1040,10 @@
10151040 return;
10161041 }
10171042
1018
-static int add_port(struct ib_device *device, int port_num,
1019
- int (*port_callback)(struct ib_device *,
1020
- u8, struct kobject *))
1043
+static int add_port(struct ib_core_device *coredev, int port_num)
10211044 {
1045
+ struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
1046
+ bool is_full_dev = &device->coredev == coredev;
10221047 struct ib_port *p;
10231048 struct ib_port_attr attr;
10241049 int i;
....@@ -1036,11 +1061,10 @@
10361061 p->port_num = port_num;
10371062
10381063 ret = kobject_init_and_add(&p->kobj, &port_type,
1039
- device->ports_parent,
1064
+ coredev->ports_kobj,
10401065 "%d", port_num);
10411066 if (ret) {
1042
- kfree(p);
1043
- return ret;
1067
+ goto err_put;
10441068 }
10451069
10461070 p->gid_attr_group = kzalloc(sizeof(*p->gid_attr_group), GFP_KERNEL);
....@@ -1053,11 +1077,10 @@
10531077 ret = kobject_init_and_add(&p->gid_attr_group->kobj, &gid_attr_type,
10541078 &p->kobj, "gid_attrs");
10551079 if (ret) {
1056
- kfree(p->gid_attr_group);
1057
- goto err_put;
1080
+ goto err_put_gid_attrs;
10581081 }
10591082
1060
- if (device->process_mad) {
1083
+ if (device->ops.process_mad && is_full_dev) {
10611084 p->pma_table = get_counter_table(device, port_num);
10621085 ret = sysfs_create_group(&p->kobj, p->pma_table);
10631086 if (ret)
....@@ -1101,46 +1124,61 @@
11011124 if (ret)
11021125 goto err_free_gid_type;
11031126
1104
- p->pkey_group.name = "pkeys";
1105
- p->pkey_group.attrs = alloc_group_attrs(show_port_pkey,
1106
- attr.pkey_tbl_len);
1107
- if (!p->pkey_group.attrs) {
1108
- ret = -ENOMEM;
1109
- goto err_remove_gid_type;
1127
+ if (attr.pkey_tbl_len) {
1128
+ p->pkey_group = kzalloc(sizeof(*p->pkey_group), GFP_KERNEL);
1129
+ if (!p->pkey_group) {
1130
+ ret = -ENOMEM;
1131
+ goto err_remove_gid_type;
1132
+ }
1133
+
1134
+ p->pkey_group->name = "pkeys";
1135
+ p->pkey_group->attrs = alloc_group_attrs(show_port_pkey,
1136
+ attr.pkey_tbl_len);
1137
+ if (!p->pkey_group->attrs) {
1138
+ ret = -ENOMEM;
1139
+ goto err_free_pkey_group;
1140
+ }
1141
+
1142
+ ret = sysfs_create_group(&p->kobj, p->pkey_group);
1143
+ if (ret)
1144
+ goto err_free_pkey;
11101145 }
11111146
1112
- ret = sysfs_create_group(&p->kobj, &p->pkey_group);
1113
- if (ret)
1114
- goto err_free_pkey;
11151147
1116
- if (port_callback) {
1117
- ret = port_callback(device, port_num, &p->kobj);
1148
+ if (device->ops.init_port && is_full_dev) {
1149
+ ret = device->ops.init_port(device, port_num, &p->kobj);
11181150 if (ret)
11191151 goto err_remove_pkey;
11201152 }
11211153
11221154 /*
1123
- * If port == 0, it means we have only one port and the parent
1124
- * device, not this port device, should be the holder of the
1125
- * hw_counters
1155
+ * If port == 0, it means hw_counters are per device and not per
1156
+ * port, so holder should be device. Therefore skip per port conunter
1157
+ * initialization.
11261158 */
1127
- if (device->alloc_hw_stats && port_num)
1159
+ if (device->ops.alloc_hw_stats && port_num && is_full_dev)
11281160 setup_hw_stats(device, p, port_num);
11291161
1130
- list_add_tail(&p->kobj.entry, &device->port_list);
1162
+ list_add_tail(&p->kobj.entry, &coredev->port_list);
11311163
11321164 kobject_uevent(&p->kobj, KOBJ_ADD);
11331165 return 0;
11341166
11351167 err_remove_pkey:
1136
- sysfs_remove_group(&p->kobj, &p->pkey_group);
1168
+ if (p->pkey_group)
1169
+ sysfs_remove_group(&p->kobj, p->pkey_group);
11371170
11381171 err_free_pkey:
1139
- for (i = 0; i < attr.pkey_tbl_len; ++i)
1140
- kfree(p->pkey_group.attrs[i]);
1172
+ if (p->pkey_group) {
1173
+ for (i = 0; i < attr.pkey_tbl_len; ++i)
1174
+ kfree(p->pkey_group->attrs[i]);
11411175
1142
- kfree(p->pkey_group.attrs);
1143
- p->pkey_group.attrs = NULL;
1176
+ kfree(p->pkey_group->attrs);
1177
+ p->pkey_group->attrs = NULL;
1178
+ }
1179
+
1180
+err_free_pkey_group:
1181
+ kfree(p->pkey_group);
11441182
11451183 err_remove_gid_type:
11461184 sysfs_remove_group(&p->gid_attr_group->kobj,
....@@ -1186,26 +1224,28 @@
11861224 return ret;
11871225 }
11881226
1189
-static ssize_t show_node_type(struct device *device,
1227
+static ssize_t node_type_show(struct device *device,
11901228 struct device_attribute *attr, char *buf)
11911229 {
1192
- struct ib_device *dev = container_of(device, struct ib_device, dev);
1230
+ struct ib_device *dev = rdma_device_to_ibdev(device);
11931231
11941232 switch (dev->node_type) {
11951233 case RDMA_NODE_IB_CA: return sprintf(buf, "%d: CA\n", dev->node_type);
11961234 case RDMA_NODE_RNIC: return sprintf(buf, "%d: RNIC\n", dev->node_type);
11971235 case RDMA_NODE_USNIC: return sprintf(buf, "%d: usNIC\n", dev->node_type);
11981236 case RDMA_NODE_USNIC_UDP: return sprintf(buf, "%d: usNIC UDP\n", dev->node_type);
1237
+ case RDMA_NODE_UNSPECIFIED: return sprintf(buf, "%d: unspecified\n", dev->node_type);
11991238 case RDMA_NODE_IB_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
12001239 case RDMA_NODE_IB_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);
12011240 default: return sprintf(buf, "%d: <unknown>\n", dev->node_type);
12021241 }
12031242 }
1243
+static DEVICE_ATTR_RO(node_type);
12041244
1205
-static ssize_t show_sys_image_guid(struct device *device,
1245
+static ssize_t sys_image_guid_show(struct device *device,
12061246 struct device_attribute *dev_attr, char *buf)
12071247 {
1208
- struct ib_device *dev = container_of(device, struct ib_device, dev);
1248
+ struct ib_device *dev = rdma_device_to_ibdev(device);
12091249
12101250 return sprintf(buf, "%04x:%04x:%04x:%04x\n",
12111251 be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[0]),
....@@ -1213,11 +1253,12 @@
12131253 be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[2]),
12141254 be16_to_cpu(((__be16 *) &dev->attrs.sys_image_guid)[3]));
12151255 }
1256
+static DEVICE_ATTR_RO(sys_image_guid);
12161257
1217
-static ssize_t show_node_guid(struct device *device,
1258
+static ssize_t node_guid_show(struct device *device,
12181259 struct device_attribute *attr, char *buf)
12191260 {
1220
- struct ib_device *dev = container_of(device, struct ib_device, dev);
1261
+ struct ib_device *dev = rdma_device_to_ibdev(device);
12211262
12221263 return sprintf(buf, "%04x:%04x:%04x:%04x\n",
12231264 be16_to_cpu(((__be16 *) &dev->node_guid)[0]),
....@@ -1225,25 +1266,26 @@
12251266 be16_to_cpu(((__be16 *) &dev->node_guid)[2]),
12261267 be16_to_cpu(((__be16 *) &dev->node_guid)[3]));
12271268 }
1269
+static DEVICE_ATTR_RO(node_guid);
12281270
1229
-static ssize_t show_node_desc(struct device *device,
1271
+static ssize_t node_desc_show(struct device *device,
12301272 struct device_attribute *attr, char *buf)
12311273 {
1232
- struct ib_device *dev = container_of(device, struct ib_device, dev);
1274
+ struct ib_device *dev = rdma_device_to_ibdev(device);
12331275
12341276 return sprintf(buf, "%.64s\n", dev->node_desc);
12351277 }
12361278
1237
-static ssize_t set_node_desc(struct device *device,
1238
- struct device_attribute *attr,
1239
- const char *buf, size_t count)
1279
+static ssize_t node_desc_store(struct device *device,
1280
+ struct device_attribute *attr,
1281
+ const char *buf, size_t count)
12401282 {
1241
- struct ib_device *dev = container_of(device, struct ib_device, dev);
1283
+ struct ib_device *dev = rdma_device_to_ibdev(device);
12421284 struct ib_device_modify desc = {};
12431285 int ret;
12441286
1245
- if (!dev->modify_device)
1246
- return -EIO;
1287
+ if (!dev->ops.modify_device)
1288
+ return -EOPNOTSUPP;
12471289
12481290 memcpy(desc.node_desc, buf, min_t(int, count, IB_DEVICE_NODE_DESC_MAX));
12491291 ret = ib_modify_device(dev, IB_DEVICE_MODIFY_NODE_DESC, &desc);
....@@ -1252,46 +1294,52 @@
12521294
12531295 return count;
12541296 }
1297
+static DEVICE_ATTR_RW(node_desc);
12551298
1256
-static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
1299
+static ssize_t fw_ver_show(struct device *device, struct device_attribute *attr,
12571300 char *buf)
12581301 {
1259
- struct ib_device *dev = container_of(device, struct ib_device, dev);
1302
+ struct ib_device *dev = rdma_device_to_ibdev(device);
12601303
12611304 ib_get_device_fw_str(dev, buf);
12621305 strlcat(buf, "\n", IB_FW_VERSION_NAME_MAX);
12631306 return strlen(buf);
12641307 }
1308
+static DEVICE_ATTR_RO(fw_ver);
12651309
1266
-static DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
1267
-static DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
1268
-static DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
1269
-static DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc, set_node_desc);
1270
-static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
1271
-
1272
-static struct device_attribute *ib_class_attributes[] = {
1273
- &dev_attr_node_type,
1274
- &dev_attr_sys_image_guid,
1275
- &dev_attr_node_guid,
1276
- &dev_attr_node_desc,
1277
- &dev_attr_fw_ver,
1310
+static struct attribute *ib_dev_attrs[] = {
1311
+ &dev_attr_node_type.attr,
1312
+ &dev_attr_node_guid.attr,
1313
+ &dev_attr_sys_image_guid.attr,
1314
+ &dev_attr_fw_ver.attr,
1315
+ &dev_attr_node_desc.attr,
1316
+ NULL,
12781317 };
12791318
1280
-static void free_port_list_attributes(struct ib_device *device)
1319
+const struct attribute_group ib_dev_attr_group = {
1320
+ .attrs = ib_dev_attrs,
1321
+};
1322
+
1323
+void ib_free_port_attrs(struct ib_core_device *coredev)
12811324 {
1325
+ struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
1326
+ bool is_full_dev = &device->coredev == coredev;
12821327 struct kobject *p, *t;
12831328
1284
- list_for_each_entry_safe(p, t, &device->port_list, entry) {
1329
+ list_for_each_entry_safe(p, t, &coredev->port_list, entry) {
12851330 struct ib_port *port = container_of(p, struct ib_port, kobj);
1331
+
12861332 list_del(&p->entry);
1287
- if (port->hw_stats) {
1288
- kfree(port->hw_stats);
1333
+ if (port->hw_stats_ag)
12891334 free_hsag(&port->kobj, port->hw_stats_ag);
1290
- }
1335
+ kfree(port->hw_stats);
1336
+ if (device->port_data && is_full_dev)
1337
+ device->port_data[port->port_num].hw_stats = NULL;
12911338
12921339 if (port->pma_table)
12931340 sysfs_remove_group(p, port->pma_table);
1294
- sysfs_remove_group(p, &port->pkey_group);
1341
+ if (port->pkey_group)
1342
+ sysfs_remove_group(p, port->pkey_group);
12951343 sysfs_remove_group(p, &port->gid_group);
12961344 sysfs_remove_group(&port->gid_attr_group->kobj,
12971345 &port->gid_attr_group->ndev);
....@@ -1301,81 +1349,97 @@
13011349 kobject_put(p);
13021350 }
13031351
1304
- kobject_put(device->ports_parent);
1352
+ kobject_put(coredev->ports_kobj);
13051353 }
13061354
1307
-int ib_device_register_sysfs(struct ib_device *device,
1308
- int (*port_callback)(struct ib_device *,
1309
- u8, struct kobject *))
1355
+int ib_setup_port_attrs(struct ib_core_device *coredev)
13101356 {
1311
- struct device *class_dev = &device->dev;
1357
+ struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
1358
+ unsigned int port;
13121359 int ret;
1313
- int i;
13141360
1315
- ret = dev_set_name(class_dev, "%s", device->name);
1316
- if (ret)
1317
- return ret;
1361
+ coredev->ports_kobj = kobject_create_and_add("ports",
1362
+ &coredev->dev.kobj);
1363
+ if (!coredev->ports_kobj)
1364
+ return -ENOMEM;
13181365
1319
- ret = device_add(class_dev);
1320
- if (ret)
1321
- goto err;
1322
-
1323
- for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i) {
1324
- ret = device_create_file(class_dev, ib_class_attributes[i]);
1325
- if (ret)
1326
- goto err_unregister;
1327
- }
1328
-
1329
- device->ports_parent = kobject_create_and_add("ports",
1330
- &class_dev->kobj);
1331
- if (!device->ports_parent) {
1332
- ret = -ENOMEM;
1333
- goto err_put;
1334
- }
1335
-
1336
- if (rdma_cap_ib_switch(device)) {
1337
- ret = add_port(device, 0, port_callback);
1366
+ rdma_for_each_port (device, port) {
1367
+ ret = add_port(coredev, port);
13381368 if (ret)
13391369 goto err_put;
1340
- } else {
1341
- for (i = 1; i <= device->phys_port_cnt; ++i) {
1342
- ret = add_port(device, i, port_callback);
1343
- if (ret)
1344
- goto err_put;
1345
- }
13461370 }
1347
-
1348
- if (device->alloc_hw_stats)
1349
- setup_hw_stats(device, NULL, 0);
13501371
13511372 return 0;
13521373
13531374 err_put:
1354
- free_port_list_attributes(device);
1355
-
1356
-err_unregister:
1357
- device_del(class_dev);
1358
-
1359
-err:
1375
+ ib_free_port_attrs(coredev);
13601376 return ret;
1377
+}
1378
+
1379
+int ib_device_register_sysfs(struct ib_device *device)
1380
+{
1381
+ int ret;
1382
+
1383
+ ret = ib_setup_port_attrs(&device->coredev);
1384
+ if (ret)
1385
+ return ret;
1386
+
1387
+ if (device->ops.alloc_hw_stats)
1388
+ setup_hw_stats(device, NULL, 0);
1389
+
1390
+ return 0;
13611391 }
13621392
13631393 void ib_device_unregister_sysfs(struct ib_device *device)
13641394 {
1365
- int i;
1366
-
1367
- /* Hold kobject until ib_dealloc_device() */
1368
- kobject_get(&device->dev.kobj);
1369
-
1370
- free_port_list_attributes(device);
1371
-
1372
- if (device->hw_stats) {
1373
- kfree(device->hw_stats);
1395
+ if (device->hw_stats_ag)
13741396 free_hsag(&device->dev.kobj, device->hw_stats_ag);
1397
+ kfree(device->hw_stats);
1398
+
1399
+ ib_free_port_attrs(&device->coredev);
1400
+}
1401
+
1402
+/**
1403
+ * ib_port_register_module_stat - add module counters under relevant port
1404
+ * of IB device.
1405
+ *
1406
+ * @device: IB device to add counters
1407
+ * @port_num: valid port number
1408
+ * @kobj: pointer to the kobject to initialize
1409
+ * @ktype: pointer to the ktype for this kobject.
1410
+ * @name: the name of the kobject
1411
+ */
1412
+int ib_port_register_module_stat(struct ib_device *device, u8 port_num,
1413
+ struct kobject *kobj, struct kobj_type *ktype,
1414
+ const char *name)
1415
+{
1416
+ struct kobject *p, *t;
1417
+ int ret;
1418
+
1419
+ list_for_each_entry_safe(p, t, &device->coredev.port_list, entry) {
1420
+ struct ib_port *port = container_of(p, struct ib_port, kobj);
1421
+
1422
+ if (port->port_num != port_num)
1423
+ continue;
1424
+
1425
+ ret = kobject_init_and_add(kobj, ktype, &port->kobj, "%s",
1426
+ name);
1427
+ if (ret) {
1428
+ kobject_put(kobj);
1429
+ return ret;
1430
+ }
13751431 }
13761432
1377
- for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i)
1378
- device_remove_file(&device->dev, ib_class_attributes[i]);
1379
-
1380
- device_unregister(&device->dev);
1433
+ return 0;
13811434 }
1435
+EXPORT_SYMBOL(ib_port_register_module_stat);
1436
+
1437
+/**
1438
+ * ib_port_unregister_module_stat - release module counters
1439
+ * @kobj: pointer to the kobject to release
1440
+ */
1441
+void ib_port_unregister_module_stat(struct kobject *kobj)
1442
+{
1443
+ kobject_put(kobj);
1444
+}
1445
+EXPORT_SYMBOL(ib_port_unregister_module_stat);