diff options
author | Robert Walsh <rjwalsh@pathscale.com> | 2006-10-10 17:55:45 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-10-16 13:06:07 -0400 |
commit | 6ef93dddfe11a72ab98a37ac4ef20ad681b008b0 (patch) | |
tree | 4d8ed1a54364463366a60e9a3352a6361058121e /drivers | |
parent | fb7711e71ea7cd0d3e77e969df59162388c8a1f9 (diff) |
IB/ipath: Initialize diagpkt file on device init only
Don't attempt to set up the diagpkt device in the module init code.
Instead, wait until a piece of hardware is initialized. Fixes a
problem when loading the ib_ipath module when no InfiniPath hardware
is present: modprobe would go into the D state and stay there.
Signed-off-by: Robert Walsh <robert.walsh@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_diag.c | 65 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_driver.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_kernel.h | 3 |
3 files changed, 38 insertions, 40 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c index 29958b6e0214..28c087b824c2 100644 --- a/drivers/infiniband/hw/ipath/ipath_diag.c +++ b/drivers/infiniband/hw/ipath/ipath_diag.c | |||
@@ -67,19 +67,54 @@ static struct file_operations diag_file_ops = { | |||
67 | .release = ipath_diag_release | 67 | .release = ipath_diag_release |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static ssize_t ipath_diagpkt_write(struct file *fp, | ||
71 | const char __user *data, | ||
72 | size_t count, loff_t *off); | ||
73 | |||
74 | static struct file_operations diagpkt_file_ops = { | ||
75 | .owner = THIS_MODULE, | ||
76 | .write = ipath_diagpkt_write, | ||
77 | }; | ||
78 | |||
79 | static atomic_t diagpkt_count = ATOMIC_INIT(0); | ||
80 | static struct cdev *diagpkt_cdev; | ||
81 | static struct class_device *diagpkt_class_dev; | ||
82 | |||
70 | int ipath_diag_add(struct ipath_devdata *dd) | 83 | int ipath_diag_add(struct ipath_devdata *dd) |
71 | { | 84 | { |
72 | char name[16]; | 85 | char name[16]; |
86 | int ret = 0; | ||
87 | |||
88 | if (atomic_inc_return(&diagpkt_count) == 1) { | ||
89 | ret = ipath_cdev_init(IPATH_DIAGPKT_MINOR, | ||
90 | "ipath_diagpkt", &diagpkt_file_ops, | ||
91 | &diagpkt_cdev, &diagpkt_class_dev); | ||
92 | |||
93 | if (ret) { | ||
94 | ipath_dev_err(dd, "Couldn't create ipath_diagpkt " | ||
95 | "device: %d", ret); | ||
96 | goto done; | ||
97 | } | ||
98 | } | ||
73 | 99 | ||
74 | snprintf(name, sizeof(name), "ipath_diag%d", dd->ipath_unit); | 100 | snprintf(name, sizeof(name), "ipath_diag%d", dd->ipath_unit); |
75 | 101 | ||
76 | return ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name, | 102 | ret = ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name, |
77 | &diag_file_ops, &dd->diag_cdev, | 103 | &diag_file_ops, &dd->diag_cdev, |
78 | &dd->diag_class_dev); | 104 | &dd->diag_class_dev); |
105 | if (ret) | ||
106 | ipath_dev_err(dd, "Couldn't create %s device: %d", | ||
107 | name, ret); | ||
108 | |||
109 | done: | ||
110 | return ret; | ||
79 | } | 111 | } |
80 | 112 | ||
81 | void ipath_diag_remove(struct ipath_devdata *dd) | 113 | void ipath_diag_remove(struct ipath_devdata *dd) |
82 | { | 114 | { |
115 | if (atomic_dec_and_test(&diagpkt_count)) | ||
116 | ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev); | ||
117 | |||
83 | ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_class_dev); | 118 | ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_class_dev); |
84 | } | 119 | } |
85 | 120 | ||
@@ -275,30 +310,6 @@ bail: | |||
275 | return ret; | 310 | return ret; |
276 | } | 311 | } |
277 | 312 | ||
278 | static ssize_t ipath_diagpkt_write(struct file *fp, | ||
279 | const char __user *data, | ||
280 | size_t count, loff_t *off); | ||
281 | |||
282 | static struct file_operations diagpkt_file_ops = { | ||
283 | .owner = THIS_MODULE, | ||
284 | .write = ipath_diagpkt_write, | ||
285 | }; | ||
286 | |||
287 | static struct cdev *diagpkt_cdev; | ||
288 | static struct class_device *diagpkt_class_dev; | ||
289 | |||
290 | int __init ipath_diagpkt_add(void) | ||
291 | { | ||
292 | return ipath_cdev_init(IPATH_DIAGPKT_MINOR, | ||
293 | "ipath_diagpkt", &diagpkt_file_ops, | ||
294 | &diagpkt_cdev, &diagpkt_class_dev); | ||
295 | } | ||
296 | |||
297 | void __exit ipath_diagpkt_remove(void) | ||
298 | { | ||
299 | ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev); | ||
300 | } | ||
301 | |||
302 | /** | 313 | /** |
303 | * ipath_diagpkt_write - write an IB packet | 314 | * ipath_diagpkt_write - write an IB packet |
304 | * @fp: the diag data device file pointer | 315 | * @fp: the diag data device file pointer |
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 12cefa658f3b..b4ffaa7bcbb7 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -2005,18 +2005,8 @@ static int __init infinipath_init(void) | |||
2005 | goto bail_group; | 2005 | goto bail_group; |
2006 | } | 2006 | } |
2007 | 2007 | ||
2008 | ret = ipath_diagpkt_add(); | ||
2009 | if (ret < 0) { | ||
2010 | printk(KERN_ERR IPATH_DRV_NAME ": Unable to create " | ||
2011 | "diag data device: error %d\n", -ret); | ||
2012 | goto bail_ipathfs; | ||
2013 | } | ||
2014 | |||
2015 | goto bail; | 2008 | goto bail; |
2016 | 2009 | ||
2017 | bail_ipathfs: | ||
2018 | ipath_exit_ipathfs(); | ||
2019 | |||
2020 | bail_group: | 2010 | bail_group: |
2021 | ipath_driver_remove_group(&ipath_driver.driver); | 2011 | ipath_driver_remove_group(&ipath_driver.driver); |
2022 | 2012 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 7c436697d0e4..06d5020a2f60 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
@@ -869,9 +869,6 @@ int ipath_device_create_group(struct device *, struct ipath_devdata *); | |||
869 | void ipath_device_remove_group(struct device *, struct ipath_devdata *); | 869 | void ipath_device_remove_group(struct device *, struct ipath_devdata *); |
870 | int ipath_expose_reset(struct device *); | 870 | int ipath_expose_reset(struct device *); |
871 | 871 | ||
872 | int ipath_diagpkt_add(void); | ||
873 | void ipath_diagpkt_remove(void); | ||
874 | |||
875 | int ipath_init_ipathfs(void); | 872 | int ipath_init_ipathfs(void); |
876 | void ipath_exit_ipathfs(void); | 873 | void ipath_exit_ipathfs(void); |
877 | int ipathfs_add_device(struct ipath_devdata *); | 874 | int ipathfs_add_device(struct ipath_devdata *); |