forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/infiniband/core/user_mad.c
....@@ -55,6 +55,7 @@
5555
5656 #include <rdma/ib_mad.h>
5757 #include <rdma/ib_user_mad.h>
58
+#include <rdma/rdma_netlink.h>
5859
5960 #include "core_priv.h"
6061
....@@ -89,10 +90,9 @@
8990
9091 struct ib_umad_port {
9192 struct cdev cdev;
92
- struct device *dev;
93
-
93
+ struct device dev;
9494 struct cdev sm_cdev;
95
- struct device *sm_dev;
95
+ struct device sm_dev;
9696 struct semaphore sm_sem;
9797
9898 struct mutex file_mutex;
....@@ -105,8 +105,8 @@
105105 };
106106
107107 struct ib_umad_device {
108
- struct kobject kobj;
109
- struct ib_umad_port port[0];
108
+ struct kref kref;
109
+ struct ib_umad_port ports[];
110110 };
111111
112112 struct ib_umad_file {
....@@ -131,7 +131,8 @@
131131 struct ib_user_mad mad;
132132 };
133133
134
-static struct class *umad_class;
134
+#define CREATE_TRACE_POINTS
135
+#include <trace/events/ib_umad.h>
135136
136137 static const dev_t base_umad_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);
137138 static const dev_t base_issm_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE) +
....@@ -139,22 +140,28 @@
139140 static dev_t dynamic_umad_dev;
140141 static dev_t dynamic_issm_dev;
141142
142
-static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS);
143
+static DEFINE_IDA(umad_ida);
143144
144
-static void ib_umad_add_one(struct ib_device *device);
145
+static int ib_umad_add_one(struct ib_device *device);
145146 static void ib_umad_remove_one(struct ib_device *device, void *client_data);
146147
147
-static void ib_umad_release_dev(struct kobject *kobj)
148
+static void ib_umad_dev_free(struct kref *kref)
148149 {
149150 struct ib_umad_device *dev =
150
- container_of(kobj, struct ib_umad_device, kobj);
151
+ container_of(kref, struct ib_umad_device, kref);
151152
152153 kfree(dev);
153154 }
154155
155
-static struct kobj_type ib_umad_dev_ktype = {
156
- .release = ib_umad_release_dev,
157
-};
156
+static void ib_umad_dev_get(struct ib_umad_device *dev)
157
+{
158
+ kref_get(&dev->kref);
159
+}
160
+
161
+static void ib_umad_dev_put(struct ib_umad_device *dev)
162
+{
163
+ kref_put(&dev->kref, ib_umad_dev_free);
164
+}
158165
159166 static int hdr_size(struct ib_umad_file *file)
160167 {
....@@ -206,7 +213,7 @@
206213 struct ib_umad_packet *packet = send_wc->send_buf->context[0];
207214
208215 dequeue_send(file, packet);
209
- rdma_destroy_ah(packet->msg->ah);
216
+ rdma_destroy_ah(packet->msg->ah, RDMA_DESTROY_AH_SLEEPABLE);
210217 ib_free_send_mad(packet->msg);
211218
212219 if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
....@@ -332,6 +339,9 @@
332339 return -EFAULT;
333340 }
334341 }
342
+
343
+ trace_ib_umad_read_recv(file, &packet->mad.hdr, &recv_buf->mad->mad_hdr);
344
+
335345 return hdr_size(file) + packet->length;
336346 }
337347
....@@ -350,6 +360,9 @@
350360
351361 if (copy_to_user(buf, packet->mad.data, packet->length))
352362 return -EFAULT;
363
+
364
+ trace_ib_umad_read_send(file, &packet->mad.hdr,
365
+ (struct ib_mad_hdr *)&packet->mad.data);
353366
354367 return size;
355368 }
....@@ -516,6 +529,9 @@
516529
517530 mutex_lock(&file->mutex);
518531
532
+ trace_ib_umad_write(file, &packet->mad.hdr,
533
+ (struct ib_mad_hdr *)&packet->mad.data);
534
+
519535 agent = __get_agent(file, packet->mad.hdr.id);
520536 if (!agent) {
521537 ret = -EIO;
....@@ -632,7 +648,7 @@
632648 err_msg:
633649 ib_free_send_mad(packet->msg);
634650 err_ah:
635
- rdma_destroy_ah(ah);
651
+ rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
636652 err_up:
637653 mutex_unlock(&file->mutex);
638654 err:
....@@ -672,7 +688,7 @@
672688 mutex_lock(&file->mutex);
673689
674690 if (!file->port->ib_dev) {
675
- dev_notice(file->port->dev,
691
+ dev_notice(&file->port->dev,
676692 "ib_umad_reg_agent: invalid device\n");
677693 ret = -EPIPE;
678694 goto out;
....@@ -684,7 +700,7 @@
684700 }
685701
686702 if (ureq.qpn != 0 && ureq.qpn != 1) {
687
- dev_notice(file->port->dev,
703
+ dev_notice(&file->port->dev,
688704 "ib_umad_reg_agent: invalid QPN %d specified\n",
689705 ureq.qpn);
690706 ret = -EINVAL;
....@@ -695,7 +711,7 @@
695711 if (!__get_agent(file, agent_id))
696712 goto found;
697713
698
- dev_notice(file->port->dev,
714
+ dev_notice(&file->port->dev,
699715 "ib_umad_reg_agent: Max Agents (%u) reached\n",
700716 IB_UMAD_MAX_AGENTS);
701717 ret = -ENOMEM;
....@@ -740,11 +756,11 @@
740756 if (!file->already_used) {
741757 file->already_used = 1;
742758 if (!file->use_pkey_index) {
743
- dev_warn(file->port->dev,
759
+ dev_warn(&file->port->dev,
744760 "process %s did not enable P_Key index support.\n",
745761 current->comm);
746
- dev_warn(file->port->dev,
747
- " Documentation/infiniband/user_mad.txt has info on the new ABI.\n");
762
+ dev_warn(&file->port->dev,
763
+ " Documentation/infiniband/user_mad.rst has info on the new ABI.\n");
748764 }
749765 }
750766
....@@ -774,7 +790,7 @@
774790 mutex_lock(&file->mutex);
775791
776792 if (!file->port->ib_dev) {
777
- dev_notice(file->port->dev,
793
+ dev_notice(&file->port->dev,
778794 "ib_umad_reg_agent2: invalid device\n");
779795 ret = -EPIPE;
780796 goto out;
....@@ -786,7 +802,7 @@
786802 }
787803
788804 if (ureq.qpn != 0 && ureq.qpn != 1) {
789
- dev_notice(file->port->dev,
805
+ dev_notice(&file->port->dev,
790806 "ib_umad_reg_agent2: invalid QPN %d specified\n",
791807 ureq.qpn);
792808 ret = -EINVAL;
....@@ -794,7 +810,7 @@
794810 }
795811
796812 if (ureq.flags & ~IB_USER_MAD_REG_FLAGS_CAP) {
797
- dev_notice(file->port->dev,
813
+ dev_notice(&file->port->dev,
798814 "ib_umad_reg_agent2 failed: invalid registration flags specified 0x%x; supported 0x%x\n",
799815 ureq.flags, IB_USER_MAD_REG_FLAGS_CAP);
800816 ret = -EINVAL;
....@@ -811,7 +827,7 @@
811827 if (!__get_agent(file, agent_id))
812828 goto found;
813829
814
- dev_notice(file->port->dev,
830
+ dev_notice(&file->port->dev,
815831 "ib_umad_reg_agent2: Max Agents (%u) reached\n",
816832 IB_UMAD_MAX_AGENTS);
817833 ret = -ENOMEM;
....@@ -823,7 +839,7 @@
823839 req.mgmt_class = ureq.mgmt_class;
824840 req.mgmt_class_version = ureq.mgmt_class_version;
825841 if (ureq.oui & 0xff000000) {
826
- dev_notice(file->port->dev,
842
+ dev_notice(&file->port->dev,
827843 "ib_umad_reg_agent2 failed: oui invalid 0x%08x\n",
828844 ureq.oui);
829845 ret = -EINVAL;
....@@ -972,19 +988,27 @@
972988 {
973989 struct ib_umad_port *port;
974990 struct ib_umad_file *file;
975
- int ret = -ENXIO;
991
+ int ret = 0;
976992
977993 port = container_of(inode->i_cdev, struct ib_umad_port, cdev);
978994
979995 mutex_lock(&port->file_mutex);
980996
981
- if (!port->ib_dev)
997
+ if (!port->ib_dev) {
998
+ ret = -ENXIO;
982999 goto out;
1000
+ }
9831001
984
- ret = -ENOMEM;
985
- file = kzalloc(sizeof *file, GFP_KERNEL);
986
- if (!file)
1002
+ if (!rdma_dev_access_netns(port->ib_dev, current->nsproxy->net_ns)) {
1003
+ ret = -EPERM;
9871004 goto out;
1005
+ }
1006
+
1007
+ file = kzalloc(sizeof(*file), GFP_KERNEL);
1008
+ if (!file) {
1009
+ ret = -ENOMEM;
1010
+ goto out;
1011
+ }
9881012
9891013 mutex_init(&file->mutex);
9901014 spin_lock_init(&file->send_lock);
....@@ -997,15 +1021,7 @@
9971021
9981022 list_add_tail(&file->port_list, &port->file_list);
9991023
1000
- ret = nonseekable_open(inode, filp);
1001
- if (ret) {
1002
- list_del(&file->port_list);
1003
- kfree(file);
1004
- goto out;
1005
- }
1006
-
1007
- kobject_get(&port->umad_dev->kobj);
1008
-
1024
+ stream_open(inode, filp);
10091025 out:
10101026 mutex_unlock(&port->file_mutex);
10111027 return ret;
....@@ -1014,7 +1030,6 @@
10141030 static int ib_umad_close(struct inode *inode, struct file *filp)
10151031 {
10161032 struct ib_umad_file *file = filp->private_data;
1017
- struct ib_umad_device *dev = file->port->umad_dev;
10181033 struct ib_umad_packet *packet, *tmp;
10191034 int already_dead;
10201035 int i;
....@@ -1041,10 +1056,8 @@
10411056 ib_unregister_mad_agent(file->agent[i]);
10421057
10431058 mutex_unlock(&file->port->file_mutex);
1044
-
1059
+ mutex_destroy(&file->mutex);
10451060 kfree(file);
1046
- kobject_put(&dev->kobj);
1047
-
10481061 return 0;
10491062 }
10501063
....@@ -1084,23 +1097,19 @@
10841097 }
10851098 }
10861099
1100
+ if (!rdma_dev_access_netns(port->ib_dev, current->nsproxy->net_ns)) {
1101
+ ret = -EPERM;
1102
+ goto err_up_sem;
1103
+ }
1104
+
10871105 ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
10881106 if (ret)
10891107 goto err_up_sem;
10901108
10911109 filp->private_data = port;
10921110
1093
- ret = nonseekable_open(inode, filp);
1094
- if (ret)
1095
- goto err_clr_sm_cap;
1096
-
1097
- kobject_get(&port->umad_dev->kobj);
1098
-
1111
+ nonseekable_open(inode, filp);
10991112 return 0;
1100
-
1101
-err_clr_sm_cap:
1102
- swap(props.set_port_cap_mask, props.clr_port_cap_mask);
1103
- ib_modify_port(port->ib_dev, port->port_num, 0, &props);
11041113
11051114 err_up_sem:
11061115 up(&port->sm_sem);
....@@ -1124,8 +1133,6 @@
11241133
11251134 up(&port->sm_sem);
11261135
1127
- kobject_put(&port->umad_dev->kobj);
1128
-
11291136 return ret;
11301137 }
11311138
....@@ -1136,13 +1143,61 @@
11361143 .llseek = no_llseek,
11371144 };
11381145
1146
+static struct ib_umad_port *get_port(struct ib_device *ibdev,
1147
+ struct ib_umad_device *umad_dev,
1148
+ unsigned int port)
1149
+{
1150
+ if (!umad_dev)
1151
+ return ERR_PTR(-EOPNOTSUPP);
1152
+ if (!rdma_is_port_valid(ibdev, port))
1153
+ return ERR_PTR(-EINVAL);
1154
+ if (!rdma_cap_ib_mad(ibdev, port))
1155
+ return ERR_PTR(-EOPNOTSUPP);
1156
+
1157
+ return &umad_dev->ports[port - rdma_start_port(ibdev)];
1158
+}
1159
+
1160
+static int ib_umad_get_nl_info(struct ib_device *ibdev, void *client_data,
1161
+ struct ib_client_nl_info *res)
1162
+{
1163
+ struct ib_umad_port *port = get_port(ibdev, client_data, res->port);
1164
+
1165
+ if (IS_ERR(port))
1166
+ return PTR_ERR(port);
1167
+
1168
+ res->abi = IB_USER_MAD_ABI_VERSION;
1169
+ res->cdev = &port->dev;
1170
+ return 0;
1171
+}
1172
+
11391173 static struct ib_client umad_client = {
11401174 .name = "umad",
11411175 .add = ib_umad_add_one,
1142
- .remove = ib_umad_remove_one
1176
+ .remove = ib_umad_remove_one,
1177
+ .get_nl_info = ib_umad_get_nl_info,
11431178 };
1179
+MODULE_ALIAS_RDMA_CLIENT("umad");
11441180
1145
-static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr,
1181
+static int ib_issm_get_nl_info(struct ib_device *ibdev, void *client_data,
1182
+ struct ib_client_nl_info *res)
1183
+{
1184
+ struct ib_umad_port *port = get_port(ibdev, client_data, res->port);
1185
+
1186
+ if (IS_ERR(port))
1187
+ return PTR_ERR(port);
1188
+
1189
+ res->abi = IB_USER_MAD_ABI_VERSION;
1190
+ res->cdev = &port->sm_dev;
1191
+ return 0;
1192
+}
1193
+
1194
+static struct ib_client issm_client = {
1195
+ .name = "issm",
1196
+ .get_nl_info = ib_issm_get_nl_info,
1197
+};
1198
+MODULE_ALIAS_RDMA_CLIENT("issm");
1199
+
1200
+static ssize_t ibdev_show(struct device *dev, struct device_attribute *attr,
11461201 char *buf)
11471202 {
11481203 struct ib_umad_port *port = dev_get_drvdata(dev);
....@@ -1150,11 +1205,11 @@
11501205 if (!port)
11511206 return -ENODEV;
11521207
1153
- return sprintf(buf, "%s\n", port->ib_dev->name);
1208
+ return sprintf(buf, "%s\n", dev_name(&port->ib_dev->dev));
11541209 }
1155
-static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
1210
+static DEVICE_ATTR_RO(ibdev);
11561211
1157
-static ssize_t show_port(struct device *dev, struct device_attribute *attr,
1212
+static ssize_t port_show(struct device *dev, struct device_attribute *attr,
11581213 char *buf)
11591214 {
11601215 struct ib_umad_port *port = dev_get_drvdata(dev);
....@@ -1164,10 +1219,59 @@
11641219
11651220 return sprintf(buf, "%d\n", port->port_num);
11661221 }
1167
-static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
1222
+static DEVICE_ATTR_RO(port);
11681223
1169
-static CLASS_ATTR_STRING(abi_version, S_IRUGO,
1170
- __stringify(IB_USER_MAD_ABI_VERSION));
1224
+static struct attribute *umad_class_dev_attrs[] = {
1225
+ &dev_attr_ibdev.attr,
1226
+ &dev_attr_port.attr,
1227
+ NULL,
1228
+};
1229
+ATTRIBUTE_GROUPS(umad_class_dev);
1230
+
1231
+static char *umad_devnode(struct device *dev, umode_t *mode)
1232
+{
1233
+ return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
1234
+}
1235
+
1236
+static ssize_t abi_version_show(struct class *class,
1237
+ struct class_attribute *attr, char *buf)
1238
+{
1239
+ return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
1240
+}
1241
+static CLASS_ATTR_RO(abi_version);
1242
+
1243
+static struct attribute *umad_class_attrs[] = {
1244
+ &class_attr_abi_version.attr,
1245
+ NULL,
1246
+};
1247
+ATTRIBUTE_GROUPS(umad_class);
1248
+
1249
+static struct class umad_class = {
1250
+ .name = "infiniband_mad",
1251
+ .devnode = umad_devnode,
1252
+ .class_groups = umad_class_groups,
1253
+ .dev_groups = umad_class_dev_groups,
1254
+};
1255
+
1256
+static void ib_umad_release_port(struct device *device)
1257
+{
1258
+ struct ib_umad_port *port = dev_get_drvdata(device);
1259
+ struct ib_umad_device *umad_dev = port->umad_dev;
1260
+
1261
+ ib_umad_dev_put(umad_dev);
1262
+}
1263
+
1264
+static void ib_umad_init_port_dev(struct device *dev,
1265
+ struct ib_umad_port *port,
1266
+ const struct ib_device *device)
1267
+{
1268
+ device_initialize(dev);
1269
+ ib_umad_dev_get(port->umad_dev);
1270
+ dev->class = &umad_class;
1271
+ dev->parent = device->dev.parent;
1272
+ dev_set_drvdata(dev, port);
1273
+ dev->release = ib_umad_release_port;
1274
+}
11711275
11721276 static int ib_umad_init_port(struct ib_device *device, int port_num,
11731277 struct ib_umad_device *umad_dev,
....@@ -1176,12 +1280,12 @@
11761280 int devnum;
11771281 dev_t base_umad;
11781282 dev_t base_issm;
1283
+ int ret;
11791284
1180
- devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
1181
- if (devnum >= IB_UMAD_MAX_PORTS)
1285
+ devnum = ida_alloc_max(&umad_ida, IB_UMAD_MAX_PORTS - 1, GFP_KERNEL);
1286
+ if (devnum < 0)
11821287 return -1;
11831288 port->dev_num = devnum;
1184
- set_bit(devnum, dev_map);
11851289 if (devnum >= IB_UMAD_NUM_FIXED_MINOR) {
11861290 base_umad = dynamic_umad_dev + devnum - IB_UMAD_NUM_FIXED_MINOR;
11871291 base_issm = dynamic_issm_dev + devnum - IB_UMAD_NUM_FIXED_MINOR;
....@@ -1191,63 +1295,41 @@
11911295 }
11921296
11931297 port->ib_dev = device;
1298
+ port->umad_dev = umad_dev;
11941299 port->port_num = port_num;
11951300 sema_init(&port->sm_sem, 1);
11961301 mutex_init(&port->file_mutex);
11971302 INIT_LIST_HEAD(&port->file_list);
11981303
1304
+ ib_umad_init_port_dev(&port->dev, port, device);
1305
+ port->dev.devt = base_umad;
1306
+ dev_set_name(&port->dev, "umad%d", port->dev_num);
11991307 cdev_init(&port->cdev, &umad_fops);
12001308 port->cdev.owner = THIS_MODULE;
1201
- cdev_set_parent(&port->cdev, &umad_dev->kobj);
1202
- kobject_set_name(&port->cdev.kobj, "umad%d", port->dev_num);
1203
- if (cdev_add(&port->cdev, base_umad, 1))
1309
+
1310
+ ret = cdev_device_add(&port->cdev, &port->dev);
1311
+ if (ret)
12041312 goto err_cdev;
12051313
1206
- port->dev = device_create(umad_class, device->dev.parent,
1207
- port->cdev.dev, port,
1208
- "umad%d", port->dev_num);
1209
- if (IS_ERR(port->dev))
1210
- goto err_cdev;
1211
-
1212
- if (device_create_file(port->dev, &dev_attr_ibdev))
1213
- goto err_dev;
1214
- if (device_create_file(port->dev, &dev_attr_port))
1215
- goto err_dev;
1216
-
1314
+ ib_umad_init_port_dev(&port->sm_dev, port, device);
1315
+ port->sm_dev.devt = base_issm;
1316
+ dev_set_name(&port->sm_dev, "issm%d", port->dev_num);
12171317 cdev_init(&port->sm_cdev, &umad_sm_fops);
12181318 port->sm_cdev.owner = THIS_MODULE;
1219
- cdev_set_parent(&port->sm_cdev, &umad_dev->kobj);
1220
- kobject_set_name(&port->sm_cdev.kobj, "issm%d", port->dev_num);
1221
- if (cdev_add(&port->sm_cdev, base_issm, 1))
1222
- goto err_sm_cdev;
12231319
1224
- port->sm_dev = device_create(umad_class, device->dev.parent,
1225
- port->sm_cdev.dev, port,
1226
- "issm%d", port->dev_num);
1227
- if (IS_ERR(port->sm_dev))
1228
- goto err_sm_cdev;
1229
-
1230
- if (device_create_file(port->sm_dev, &dev_attr_ibdev))
1231
- goto err_sm_dev;
1232
- if (device_create_file(port->sm_dev, &dev_attr_port))
1233
- goto err_sm_dev;
1320
+ ret = cdev_device_add(&port->sm_cdev, &port->sm_dev);
1321
+ if (ret)
1322
+ goto err_dev;
12341323
12351324 return 0;
12361325
1237
-err_sm_dev:
1238
- device_destroy(umad_class, port->sm_cdev.dev);
1239
-
1240
-err_sm_cdev:
1241
- cdev_del(&port->sm_cdev);
1242
-
12431326 err_dev:
1244
- device_destroy(umad_class, port->cdev.dev);
1245
-
1327
+ put_device(&port->sm_dev);
1328
+ cdev_device_del(&port->cdev, &port->dev);
12461329 err_cdev:
1247
- cdev_del(&port->cdev);
1248
- clear_bit(devnum, dev_map);
1249
-
1250
- return -1;
1330
+ put_device(&port->dev);
1331
+ ida_free(&umad_ida, devnum);
1332
+ return ret;
12511333 }
12521334
12531335 static void ib_umad_kill_port(struct ib_umad_port *port)
....@@ -1255,17 +1337,14 @@
12551337 struct ib_umad_file *file;
12561338 int id;
12571339
1258
- dev_set_drvdata(port->dev, NULL);
1259
- dev_set_drvdata(port->sm_dev, NULL);
1260
-
1261
- device_destroy(umad_class, port->cdev.dev);
1262
- device_destroy(umad_class, port->sm_cdev.dev);
1263
-
1264
- cdev_del(&port->cdev);
1265
- cdev_del(&port->sm_cdev);
1340
+ cdev_device_del(&port->sm_cdev, &port->sm_dev);
1341
+ cdev_device_del(&port->cdev, &port->dev);
12661342
12671343 mutex_lock(&port->file_mutex);
12681344
1345
+ /* Mark ib_dev NULL and block ioctl or other file ops to progress
1346
+ * further.
1347
+ */
12691348 port->ib_dev = NULL;
12701349
12711350 list_for_each_entry(file, &port->file_list, port_list) {
....@@ -1280,76 +1359,75 @@
12801359 }
12811360
12821361 mutex_unlock(&port->file_mutex);
1283
- clear_bit(port->dev_num, dev_map);
1362
+
1363
+ ida_free(&umad_ida, port->dev_num);
1364
+
1365
+ /* balances device_initialize() */
1366
+ put_device(&port->sm_dev);
1367
+ put_device(&port->dev);
12841368 }
12851369
1286
-static void ib_umad_add_one(struct ib_device *device)
1370
+static int ib_umad_add_one(struct ib_device *device)
12871371 {
12881372 struct ib_umad_device *umad_dev;
12891373 int s, e, i;
12901374 int count = 0;
1375
+ int ret;
12911376
12921377 s = rdma_start_port(device);
12931378 e = rdma_end_port(device);
12941379
1295
- umad_dev = kzalloc(sizeof *umad_dev +
1296
- (e - s + 1) * sizeof (struct ib_umad_port),
1297
- GFP_KERNEL);
1380
+ umad_dev = kzalloc(struct_size(umad_dev, ports, e - s + 1), GFP_KERNEL);
12981381 if (!umad_dev)
1299
- return;
1382
+ return -ENOMEM;
13001383
1301
- kobject_init(&umad_dev->kobj, &ib_umad_dev_ktype);
1302
-
1384
+ kref_init(&umad_dev->kref);
13031385 for (i = s; i <= e; ++i) {
13041386 if (!rdma_cap_ib_mad(device, i))
13051387 continue;
13061388
1307
- umad_dev->port[i - s].umad_dev = umad_dev;
1308
-
1309
- if (ib_umad_init_port(device, i, umad_dev,
1310
- &umad_dev->port[i - s]))
1389
+ ret = ib_umad_init_port(device, i, umad_dev,
1390
+ &umad_dev->ports[i - s]);
1391
+ if (ret)
13111392 goto err;
13121393
13131394 count++;
13141395 }
13151396
1316
- if (!count)
1397
+ if (!count) {
1398
+ ret = -EOPNOTSUPP;
13171399 goto free;
1400
+ }
13181401
13191402 ib_set_client_data(device, &umad_client, umad_dev);
13201403
1321
- return;
1404
+ return 0;
13221405
13231406 err:
13241407 while (--i >= s) {
13251408 if (!rdma_cap_ib_mad(device, i))
13261409 continue;
13271410
1328
- ib_umad_kill_port(&umad_dev->port[i - s]);
1411
+ ib_umad_kill_port(&umad_dev->ports[i - s]);
13291412 }
13301413 free:
1331
- kobject_put(&umad_dev->kobj);
1414
+ /* balances kref_init */
1415
+ ib_umad_dev_put(umad_dev);
1416
+ return ret;
13321417 }
13331418
13341419 static void ib_umad_remove_one(struct ib_device *device, void *client_data)
13351420 {
13361421 struct ib_umad_device *umad_dev = client_data;
1337
- int i;
1422
+ unsigned int i;
13381423
1339
- if (!umad_dev)
1340
- return;
1341
-
1342
- for (i = 0; i <= rdma_end_port(device) - rdma_start_port(device); ++i) {
1343
- if (rdma_cap_ib_mad(device, i + rdma_start_port(device)))
1344
- ib_umad_kill_port(&umad_dev->port[i]);
1424
+ rdma_for_each_port (device, i) {
1425
+ if (rdma_cap_ib_mad(device, i))
1426
+ ib_umad_kill_port(
1427
+ &umad_dev->ports[i - rdma_start_port(device)]);
13451428 }
1346
-
1347
- kobject_put(&umad_dev->kobj);
1348
-}
1349
-
1350
-static char *umad_devnode(struct device *dev, umode_t *mode)
1351
-{
1352
- return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
1429
+ /* balances kref_init() */
1430
+ ib_umad_dev_put(umad_dev);
13531431 }
13541432
13551433 static int __init ib_umad_init(void)
....@@ -1358,7 +1436,7 @@
13581436
13591437 ret = register_chrdev_region(base_umad_dev,
13601438 IB_UMAD_NUM_FIXED_MINOR * 2,
1361
- "infiniband_mad");
1439
+ umad_class.name);
13621440 if (ret) {
13631441 pr_err("couldn't register device number\n");
13641442 goto out;
....@@ -1366,38 +1444,33 @@
13661444
13671445 ret = alloc_chrdev_region(&dynamic_umad_dev, 0,
13681446 IB_UMAD_NUM_DYNAMIC_MINOR * 2,
1369
- "infiniband_mad");
1447
+ umad_class.name);
13701448 if (ret) {
13711449 pr_err("couldn't register dynamic device number\n");
13721450 goto out_alloc;
13731451 }
13741452 dynamic_issm_dev = dynamic_umad_dev + IB_UMAD_NUM_DYNAMIC_MINOR;
13751453
1376
- umad_class = class_create(THIS_MODULE, "infiniband_mad");
1377
- if (IS_ERR(umad_class)) {
1378
- ret = PTR_ERR(umad_class);
1454
+ ret = class_register(&umad_class);
1455
+ if (ret) {
13791456 pr_err("couldn't create class infiniband_mad\n");
13801457 goto out_chrdev;
13811458 }
13821459
1383
- umad_class->devnode = umad_devnode;
1384
-
1385
- ret = class_create_file(umad_class, &class_attr_abi_version.attr);
1386
- if (ret) {
1387
- pr_err("couldn't create abi_version attribute\n");
1388
- goto out_class;
1389
- }
1390
-
13911460 ret = ib_register_client(&umad_client);
1392
- if (ret) {
1393
- pr_err("couldn't register ib_umad client\n");
1461
+ if (ret)
13941462 goto out_class;
1395
- }
1463
+
1464
+ ret = ib_register_client(&issm_client);
1465
+ if (ret)
1466
+ goto out_client;
13961467
13971468 return 0;
13981469
1470
+out_client:
1471
+ ib_unregister_client(&umad_client);
13991472 out_class:
1400
- class_destroy(umad_class);
1473
+ class_unregister(&umad_class);
14011474
14021475 out_chrdev:
14031476 unregister_chrdev_region(dynamic_umad_dev,
....@@ -1413,8 +1486,9 @@
14131486
14141487 static void __exit ib_umad_cleanup(void)
14151488 {
1489
+ ib_unregister_client(&issm_client);
14161490 ib_unregister_client(&umad_client);
1417
- class_destroy(umad_class);
1491
+ class_unregister(&umad_class);
14181492 unregister_chrdev_region(base_umad_dev,
14191493 IB_UMAD_NUM_FIXED_MINOR * 2);
14201494 unregister_chrdev_region(dynamic_umad_dev,