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.

From: Robert Walsh <robert.walsh@qlogic.com>

diff -r 2ed7140d5700 drivers/infiniband/hw/ipath/ipath_diag.c
--- a/drivers/infiniband/hw/ipath/ipath_diag.c	Mon Oct 02 16:56:55 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_diag.c	Mon Oct 02 16:58:29 2006 -0700
@@ -286,17 +286,23 @@ static struct file_operations diagpkt_fi
 
 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);
+static int diagpkt_count;
+
+void ipath_diagpkt_add(void)
+{
+	if (diagpkt_count == 0)
+		ipath_cdev_init(IPATH_DIAGPKT_MINOR,
+				"ipath_diagpkt", &diagpkt_file_ops,
+				&diagpkt_cdev, &diagpkt_class_dev);
+
+	diagpkt_count++;
+}
+
+void ipath_diagpkt_remove(void)
+{
+	diagpkt_count--;
+	if (diagpkt_count == 0)
+		ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev);
 }
 
 /**
diff -r 2ed7140d5700 drivers/infiniband/hw/ipath/ipath_driver.c
--- a/drivers/infiniband/hw/ipath/ipath_driver.c	Mon Oct 02 16:56:55 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c	Mon Oct 02 17:00:39 2006 -0700
@@ -559,6 +559,7 @@ static int __devinit ipath_init_one(stru
 	ipathfs_add_device(dd);
 	ipath_user_add(dd);
 	ipath_diag_add(dd);
+	ipath_diagpkt_add();
 	ipath_register_ib_device(dd);
 
 	/* Check that we have a LID in LID_TIMEOUT seconds. */
@@ -700,6 +701,7 @@ static void __devexit ipath_remove_one(s
 	if (dd->verbs_dev)
 		ipath_unregister_ib_device(dd->verbs_dev);
 
+	ipath_diagpkt_remove();
 	ipath_diag_remove(dd);
 	ipath_user_remove(dd);
 	ipathfs_remove_device(dd);
@@ -2183,17 +2185,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 2ed7140d5700 drivers/infiniband/hw/ipath/ipath_kernel.h
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h	Mon Oct 02 16:56:55 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h	Mon Oct 02 16:58:29 2006 -0700
@@ -889,7 +889,7 @@ 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_add(void);
 void ipath_diagpkt_remove(void);
 
 int ipath_init_ipathfs(void);
