Hi all,

This is a new version of the patch to fix a problem on modprobe of the ib_ipath module when no InfiniPath device is actually present. This version should be multithread-probe safe.

Roland: can you queue this up for 2.6.19, please?

OFED folks: it's not critical that this get into OFED-1.1: there's already a version of this in 1.1-RC7 that should work just fine. This is just a slightly safer variant. If you think there's time to get it in and you're OK with that, then my all means do.

Regards,
 Robert.
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 initted.  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 <[EMAIL PROTECTED]>

diff -r c68975ef442a drivers/infiniband/hw/ipath/ipath_diag.c
--- a/drivers/infiniband/hw/ipath/ipath_diag.c  Tue Oct 10 14:10:34 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_diag.c  Tue Oct 10 14:26:07 2006 -0700
@@ -66,19 +66,54 @@ static struct file_operations diag_file_
        .release = ipath_diag_release
 };
 
+static ssize_t ipath_diagpkt_write(struct file *fp,
+                                  const char __user *data,
+                                  size_t count, loff_t *off);
+
+static struct file_operations diagpkt_file_ops = {
+       .owner = THIS_MODULE,
+       .write = ipath_diagpkt_write,
+};
+
+static atomic_t diagpkt_count = ATOMIC_INIT(0);
+static struct cdev *diagpkt_cdev;
+static struct class_device *diagpkt_class_dev;
+
 int ipath_diag_add(struct ipath_devdata *dd)
 {
        char name[16];
+       int ret = 0;
+
+       if (atomic_inc_return(&diagpkt_count) == 1) {
+               ret = ipath_cdev_init(IPATH_DIAGPKT_MINOR,
+                                     "ipath_diagpkt", &diagpkt_file_ops,
+                                     &diagpkt_cdev, &diagpkt_class_dev);
+
+               if (ret) {
+                        ipath_dev_err(dd, "Couldn't create ipath_diagpkt "
+                                     "device: %d", ret);
+                       goto done;
+               }
+       }
 
        snprintf(name, sizeof(name), "ipath_diag%d", dd->ipath_unit);
 
-       return ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name,
-                              &diag_file_ops, &dd->diag_cdev,
-                              &dd->diag_class_dev);
+       ret = ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name,
+                             &diag_file_ops, &dd->diag_cdev,
+                             &dd->diag_class_dev);
+       if (ret)
+               ipath_dev_err(dd, "Couldn't create %s device: %d",
+                             name, ret);
+
+done:
+       return ret;
 }
 
 void ipath_diag_remove(struct ipath_devdata *dd)
 {
+       if (atomic_dec_and_test(&diagpkt_count))
+               ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev);
+
        ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_class_dev);
 }
 
@@ -272,30 +307,6 @@ bail:
        mutex_unlock(&ipath_mutex);
 
        return ret;
-}
-
-static ssize_t ipath_diagpkt_write(struct file *fp,
-                                  const char __user *data,
-                                  size_t count, loff_t *off);
-
-static struct file_operations diagpkt_file_ops = {
-       .owner = THIS_MODULE,
-       .write = ipath_diagpkt_write,
-};
-
-static struct cdev *diagpkt_cdev;
-static struct class_device *diagpkt_class_dev;
-
-int __init ipath_diagpkt_add(void)
-{
-       return ipath_cdev_init(IPATH_DIAGPKT_MINOR,
-                              "ipath_diagpkt", &diagpkt_file_ops,
-                              &diagpkt_cdev, &diagpkt_class_dev);
-}
-
-void __exit ipath_diagpkt_remove(void)
-{
-       ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev);
 }
 
 /**
diff -r c68975ef442a drivers/infiniband/hw/ipath/ipath_driver.c
--- a/drivers/infiniband/hw/ipath/ipath_driver.c        Tue Oct 10 14:10:34 
2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c        Tue Oct 10 14:25:44 
2006 -0700
@@ -2021,17 +2021,7 @@ static int __init infinipath_init(void)
                goto bail_group;
        }
 
-       ret = ipath_diagpkt_add();
-       if (ret < 0) {
-               printk(KERN_ERR IPATH_DRV_NAME ": Unable to create "
-                      "diag data device: error %d\n", -ret);
-               goto bail_ipathfs;
-       }
- 
        goto bail;
-
-bail_ipathfs:
-       ipath_exit_ipathfs();
 
 bail_group:
        ipath_driver_remove_group(&ipath_driver.driver);
diff -r c68975ef442a drivers/infiniband/hw/ipath/ipath_kernel.h
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h        Tue Oct 10 14:10:34 
2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h        Tue Oct 10 14:25:45 
2006 -0700
@@ -869,9 +869,6 @@ void ipath_device_remove_group(struct de
 void ipath_device_remove_group(struct device *, struct ipath_devdata *);
 int ipath_expose_reset(struct device *);
 
-int ipath_diagpkt_add(void);
-void ipath_diagpkt_remove(void);
-
 int ipath_init_ipathfs(void);
 void ipath_exit_ipathfs(void);
 int ipathfs_add_device(struct ipath_devdata *);
_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to