aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2010-05-06 20:03:25 -0400
committerRoland Dreier <rolandd@cisco.com>2010-05-21 13:34:44 -0400
commit9a6edb60ec10d86b1025a0cdad68fd89f1ddaf02 (patch)
tree8727118d511e8336f038e618cfc6d4aa6b73aaaf /drivers/infiniband/core
parenta0fe3cc5d36a5f5b4f60abfe1a4b1caf4a5cce5a (diff)
IB/core: Allow device-specific per-port sysfs files
Add a new parameter to ib_register_device() so that low-level device drivers can pass in a pointer to a callback function that will be called for each port that is registered in sysfs. This allows low-level device drivers to create files in /sys/class/infiniband/<hca>/ports/<N>/ without having to poke through the internals of the RDMA sysfs handling. There is no need for an unregister function since the kobject reference will go to zero when ib_unregister_device() is called. Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/core_priv.h4
-rw-r--r--drivers/infiniband/core/device.c6
-rw-r--r--drivers/infiniband/core/sysfs.c21
3 files changed, 24 insertions, 7 deletions
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 05ac36e6acdb..a565af5c2d2e 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -38,7 +38,9 @@
38 38
39#include <rdma/ib_verbs.h> 39#include <rdma/ib_verbs.h>
40 40
41int ib_device_register_sysfs(struct ib_device *device); 41int ib_device_register_sysfs(struct ib_device *device,
42 int (*port_callback)(struct ib_device *,
43 u8, struct kobject *));
42void ib_device_unregister_sysfs(struct ib_device *device); 44void ib_device_unregister_sysfs(struct ib_device *device);
43 45
44int ib_sysfs_setup(void); 46int ib_sysfs_setup(void);
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index d1fba4153332..a19effad0811 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -267,7 +267,9 @@ out:
267 * callback for each device that is added. @device must be allocated 267 * callback for each device that is added. @device must be allocated
268 * with ib_alloc_device(). 268 * with ib_alloc_device().
269 */ 269 */
270int ib_register_device(struct ib_device *device) 270int ib_register_device(struct ib_device *device,
271 int (*port_callback)(struct ib_device *,
272 u8, struct kobject *))
271{ 273{
272 int ret; 274 int ret;
273 275
@@ -296,7 +298,7 @@ int ib_register_device(struct ib_device *device)
296 goto out; 298 goto out;
297 } 299 }
298 300
299 ret = ib_device_register_sysfs(device); 301 ret = ib_device_register_sysfs(device, port_callback);
300 if (ret) { 302 if (ret) {
301 printk(KERN_WARNING "Couldn't register device %s with driver model\n", 303 printk(KERN_WARNING "Couldn't register device %s with driver model\n",
302 device->name); 304 device->name);
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index f901957abc8b..3627300e2a10 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -475,7 +475,9 @@ err:
475 return NULL; 475 return NULL;
476} 476}
477 477
478static int add_port(struct ib_device *device, int port_num) 478static int add_port(struct ib_device *device, int port_num,
479 int (*port_callback)(struct ib_device *,
480 u8, struct kobject *))
479{ 481{
480 struct ib_port *p; 482 struct ib_port *p;
481 struct ib_port_attr attr; 483 struct ib_port_attr attr;
@@ -522,11 +524,20 @@ static int add_port(struct ib_device *device, int port_num)
522 if (ret) 524 if (ret)
523 goto err_free_pkey; 525 goto err_free_pkey;
524 526
527 if (port_callback) {
528 ret = port_callback(device, port_num, &p->kobj);
529 if (ret)
530 goto err_remove_pkey;
531 }
532
525 list_add_tail(&p->kobj.entry, &device->port_list); 533 list_add_tail(&p->kobj.entry, &device->port_list);
526 534
527 kobject_uevent(&p->kobj, KOBJ_ADD); 535 kobject_uevent(&p->kobj, KOBJ_ADD);
528 return 0; 536 return 0;
529 537
538err_remove_pkey:
539 sysfs_remove_group(&p->kobj, &p->pkey_group);
540
530err_free_pkey: 541err_free_pkey:
531 for (i = 0; i < attr.pkey_tbl_len; ++i) 542 for (i = 0; i < attr.pkey_tbl_len; ++i)
532 kfree(p->pkey_group.attrs[i]); 543 kfree(p->pkey_group.attrs[i]);
@@ -754,7 +765,9 @@ static struct attribute_group iw_stats_group = {
754 .attrs = iw_proto_stats_attrs, 765 .attrs = iw_proto_stats_attrs,
755}; 766};
756 767
757int ib_device_register_sysfs(struct ib_device *device) 768int ib_device_register_sysfs(struct ib_device *device,
769 int (*port_callback)(struct ib_device *,
770 u8, struct kobject *))
758{ 771{
759 struct device *class_dev = &device->dev; 772 struct device *class_dev = &device->dev;
760 int ret; 773 int ret;
@@ -785,12 +798,12 @@ int ib_device_register_sysfs(struct ib_device *device)
785 } 798 }
786 799
787 if (device->node_type == RDMA_NODE_IB_SWITCH) { 800 if (device->node_type == RDMA_NODE_IB_SWITCH) {
788 ret = add_port(device, 0); 801 ret = add_port(device, 0, port_callback);
789 if (ret) 802 if (ret)
790 goto err_put; 803 goto err_put;
791 } else { 804 } else {
792 for (i = 1; i <= device->phys_port_cnt; ++i) { 805 for (i = 1; i <= device->phys_port_cnt; ++i) {
793 ret = add_port(device, i); 806 ret = add_port(device, i, port_callback);
794 if (ret) 807 if (ret)
795 goto err_put; 808 goto err_put;
796 } 809 }