aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorRobert Walsh <rjwalsh@pathscale.com>2006-10-10 17:55:45 -0400
committerRoland Dreier <rolandd@cisco.com>2006-10-16 13:06:07 -0400
commit6ef93dddfe11a72ab98a37ac4ef20ad681b008b0 (patch)
tree4d8ed1a54364463366a60e9a3352a6361058121e /drivers/infiniband/hw
parentfb7711e71ea7cd0d3e77e969df59162388c8a1f9 (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/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_diag.c65
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c10
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h3
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
70static ssize_t ipath_diagpkt_write(struct file *fp,
71 const char __user *data,
72 size_t count, loff_t *off);
73
74static struct file_operations diagpkt_file_ops = {
75 .owner = THIS_MODULE,
76 .write = ipath_diagpkt_write,
77};
78
79static atomic_t diagpkt_count = ATOMIC_INIT(0);
80static struct cdev *diagpkt_cdev;
81static struct class_device *diagpkt_class_dev;
82
70int ipath_diag_add(struct ipath_devdata *dd) 83int 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
109done:
110 return ret;
79} 111}
80 112
81void ipath_diag_remove(struct ipath_devdata *dd) 113void 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
278static ssize_t ipath_diagpkt_write(struct file *fp,
279 const char __user *data,
280 size_t count, loff_t *off);
281
282static struct file_operations diagpkt_file_ops = {
283 .owner = THIS_MODULE,
284 .write = ipath_diagpkt_write,
285};
286
287static struct cdev *diagpkt_cdev;
288static struct class_device *diagpkt_class_dev;
289
290int __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
297void __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
2017bail_ipathfs:
2018 ipath_exit_ipathfs();
2019
2020bail_group: 2010bail_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 *);
869void ipath_device_remove_group(struct device *, struct ipath_devdata *); 869void ipath_device_remove_group(struct device *, struct ipath_devdata *);
870int ipath_expose_reset(struct device *); 870int ipath_expose_reset(struct device *);
871 871
872int ipath_diagpkt_add(void);
873void ipath_diagpkt_remove(void);
874
875int ipath_init_ipathfs(void); 872int ipath_init_ipathfs(void);
876void ipath_exit_ipathfs(void); 873void ipath_exit_ipathfs(void);
877int ipathfs_add_device(struct ipath_devdata *); 874int ipathfs_add_device(struct ipath_devdata *);