[openib-general] Proposed device enumeration & async event APIs
Roland Dreier
roland at topspin.com
Mon Sep 13 13:16:07 PDT 2004
Grant> We don't know which client instances are bound to a
Grant> particular device?
Nope... think of class_devices and class_interfaces in the current
driver model.
Grant> But I don't want to turn the IB world upside down to make
Grant> that work. If if doesn't make sense, do it the way you
Grant> proposed originally.
It's easy... like this:
Index: infiniband/core/ib_device.c
===================================================================
--- infiniband/core/ib_device.c (revision 803)
+++ infiniband/core/ib_device.c (working copy)
@@ -161,6 +161,28 @@
}
EXPORT_SYMBOL(ib_dealloc_device);
+static int add_client_context(struct ib_device *device, struct ib_client *client)
+{
+ struct ib_client_data *context;
+ unsigned long flags;
+
+ context = kmalloc(sizeof *context, GFP_KERNEL);
+ if (!context) {
+ printk(KERN_WARNING "Couldn't allocate client context for %s/%s\n",
+ device->name, client->name);
+ return -ENOMEM;
+ }
+
+ context->client = client;
+ context->data = NULL;
+
+ spin_lock_irqsave(&device->client_data_lock, flags);
+ list_add(&context->list, &device->client_data_list);
+ spin_unlock_irqrestore(&device->client_data_lock, flags);
+
+ return 0;
+}
+
int ib_register_device(struct ib_device *device)
{
struct ib_device_private *priv;
@@ -234,17 +256,10 @@
goto out_free_port;
}
- ret = ib_proc_setup(device, device->node_type == IB_NODE_SWITCH);
- if (ret) {
- printk(KERN_WARNING "Couldn't create /proc dir for %s\n",
- device->name);
- goto out_free_cache;
- }
-
if (ib_device_register_sysfs(device)) {
printk(KERN_WARNING "Couldn't register device %s with driver model\n",
device->name);
- goto out_proc;
+ goto out_free_cache;
}
list_add_tail(&device->core_list, &device_list);
@@ -255,16 +270,13 @@
struct ib_client *client;
list_for_each_entry(client, &client_list, list)
- if (client->add)
+ if (client->add && !add_client_context(device, client))
client->add(device);
}
up(&device_sem);
return 0;
- out_proc:
- ib_proc_cleanup(device);
-
out_free_cache:
ib_cache_cleanup(device);
@@ -302,7 +314,6 @@
kfree(context);
spin_unlock_irqrestore(&device->client_data_lock, flags);
- ib_proc_cleanup(device);
ib_cache_cleanup(device);
kfree(priv->port_data);
@@ -355,7 +366,7 @@
list_add_tail(&client->list, &client_list);
list_for_each_entry(device, &device_list, core_list)
- if (client->add)
+ if (client->add && !add_client_context(device, client))
client->add(device);
up(&device_sem);
@@ -408,34 +419,23 @@
}
EXPORT_SYMBOL(ib_get_client_data);
-int ib_set_client_data(struct ib_device *device, struct ib_client *client,
- void *data)
+void ib_set_client_data(struct ib_device *device, struct ib_client *client,
+ void *data)
{
struct ib_client_data *context;
- int ret = 0;
unsigned long flags;
spin_lock_irqsave(&device->client_data_lock, flags);
list_for_each_entry(context, &device->client_data_list, list)
if (context->client == client) {
context->data = data;
- spin_unlock_irqrestore(&device->client_data_lock, flags);
- return 0;
+ break;
}
spin_unlock_irqrestore(&device->client_data_lock, flags);
- context = kmalloc(sizeof *context, GFP_KERNEL);
- if (!context)
- return -ENOMEM;
- context->client = client;
- context->data = data;
-
- spin_lock_irqsave(&device->client_data_lock, flags);
- list_add(&context->list, &device->client_data_list);
- spin_unlock_irqrestore(&device->client_data_lock, flags);
-
- return 0;
+ printk(KERN_WARNING "No client context found for %s/%s\n",
+ device->name, client->name);
}
EXPORT_SYMBOL(ib_set_client_data);
More information about the general
mailing list