|
@@ -816,6 +816,22 @@ static struct attribute_group iw_stats_group = {
|
|
.attrs = iw_proto_stats_attrs,
|
|
.attrs = iw_proto_stats_attrs,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static void free_port_list_attributes(struct ib_device *device)
|
|
|
|
+{
|
|
|
|
+ struct kobject *p, *t;
|
|
|
|
+
|
|
|
|
+ list_for_each_entry_safe(p, t, &device->port_list, entry) {
|
|
|
|
+ struct ib_port *port = container_of(p, struct ib_port, kobj);
|
|
|
|
+ list_del(&p->entry);
|
|
|
|
+ sysfs_remove_group(p, &pma_group);
|
|
|
|
+ sysfs_remove_group(p, &port->pkey_group);
|
|
|
|
+ sysfs_remove_group(p, &port->gid_group);
|
|
|
|
+ kobject_put(p);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ kobject_put(device->ports_parent);
|
|
|
|
+}
|
|
|
|
+
|
|
int ib_device_register_sysfs(struct ib_device *device,
|
|
int ib_device_register_sysfs(struct ib_device *device,
|
|
int (*port_callback)(struct ib_device *,
|
|
int (*port_callback)(struct ib_device *,
|
|
u8, struct kobject *))
|
|
u8, struct kobject *))
|
|
@@ -869,19 +885,7 @@ int ib_device_register_sysfs(struct ib_device *device,
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
err_put:
|
|
err_put:
|
|
- {
|
|
|
|
- struct kobject *p, *t;
|
|
|
|
- struct ib_port *port;
|
|
|
|
-
|
|
|
|
- list_for_each_entry_safe(p, t, &device->port_list, entry) {
|
|
|
|
- list_del(&p->entry);
|
|
|
|
- port = container_of(p, struct ib_port, kobj);
|
|
|
|
- sysfs_remove_group(p, &pma_group);
|
|
|
|
- sysfs_remove_group(p, &port->pkey_group);
|
|
|
|
- sysfs_remove_group(p, &port->gid_group);
|
|
|
|
- kobject_put(p);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ free_port_list_attributes(device);
|
|
|
|
|
|
err_unregister:
|
|
err_unregister:
|
|
device_unregister(class_dev);
|
|
device_unregister(class_dev);
|
|
@@ -892,22 +896,18 @@ err:
|
|
|
|
|
|
void ib_device_unregister_sysfs(struct ib_device *device)
|
|
void ib_device_unregister_sysfs(struct ib_device *device)
|
|
{
|
|
{
|
|
- struct kobject *p, *t;
|
|
|
|
- struct ib_port *port;
|
|
|
|
-
|
|
|
|
/* Hold kobject until ib_dealloc_device() */
|
|
/* Hold kobject until ib_dealloc_device() */
|
|
- kobject_get(&device->dev.kobj);
|
|
|
|
|
|
+ struct kobject *kobj_dev = kobject_get(&device->dev.kobj);
|
|
|
|
+ int i;
|
|
|
|
|
|
- list_for_each_entry_safe(p, t, &device->port_list, entry) {
|
|
|
|
- list_del(&p->entry);
|
|
|
|
- port = container_of(p, struct ib_port, kobj);
|
|
|
|
- sysfs_remove_group(p, &pma_group);
|
|
|
|
- sysfs_remove_group(p, &port->pkey_group);
|
|
|
|
- sysfs_remove_group(p, &port->gid_group);
|
|
|
|
- kobject_put(p);
|
|
|
|
- }
|
|
|
|
|
|
+ if (device->node_type == RDMA_NODE_RNIC && device->get_protocol_stats)
|
|
|
|
+ sysfs_remove_group(kobj_dev, &iw_stats_group);
|
|
|
|
+
|
|
|
|
+ free_port_list_attributes(device);
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(ib_class_attributes); ++i)
|
|
|
|
+ device_remove_file(&device->dev, ib_class_attributes[i]);
|
|
|
|
|
|
- kobject_put(device->ports_parent);
|
|
|
|
device_unregister(&device->dev);
|
|
device_unregister(&device->dev);
|
|
}
|
|
}
|
|
|
|
|