[svn-commits] sruffell: linux/trunk r8094 - in /linux/trunk/drivers/dahdi: voicebus/ wctdm2...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Feb 25 11:33:56 CST 2010


Author: sruffell
Date: Thu Feb 25 11:33:53 2010
New Revision: 8094

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8094
Log:
wctdm24xxp: Provide option to initialize boards in parallel on kernels > 2.6.30

The 2.6.30 kernel provides support for asynchronous initialization.  If running
on a kernel that supports this feature, let's add an option to use it in order
to speed up driver load times.  Keep it off by default.

Modified:
    linux/trunk/drivers/dahdi/voicebus/voicebus.c
    linux/trunk/drivers/dahdi/wctdm24xxp/base.c

Modified: linux/trunk/drivers/dahdi/voicebus/voicebus.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/voicebus/voicebus.c?view=diff&rev=8094&r1=8093&r2=8094
==============================================================================
--- linux/trunk/drivers/dahdi/voicebus/voicebus.c (original)
+++ linux/trunk/drivers/dahdi/voicebus/voicebus.c Thu Feb 25 11:33:53 2010
@@ -1656,6 +1656,7 @@
 	struct vpmadt_loader *loader;
 	int ret = 0;
 	int loader_present = 0;
+	unsigned long stop;
 	might_sleep();
 
 	/* First check to see if a loader is already loaded into memory. */
@@ -1664,9 +1665,23 @@
 	spin_unlock(&loader_list_lock);
 
 	if (!loader_present) {
-		ret = request_module("dahdi_vpmadt032_loader");
+		/* If we use the blocking 'request_module' here and we are
+		 * loading the client boards with async_schedule we will hang
+		 * here. The module loader will wait for our asynchronous tasks
+		 * to finish, but we can't because we're waiting for the load
+		 * the finish. */
+		ret = request_module_nowait("dahdi_vpmadt032_loader");
 		if (ret)
 			return ret;
+		stop = jiffies + HZ;
+		while (time_after(stop, jiffies)) {
+			spin_lock(&loader_list_lock);
+			loader_present = !(list_empty(&binary_loader_list));
+			spin_unlock(&loader_list_lock);
+			if (loader_present)
+				break;
+			msleep(10);
+		}
 	}
 
 	spin_lock(&loader_list_lock);

Modified: linux/trunk/drivers/dahdi/wctdm24xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=8094&r1=8093&r2=8094
==============================================================================
--- linux/trunk/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wctdm24xxp/base.c Thu Feb 25 11:33:53 2010
@@ -50,6 +50,16 @@
 #include <linux/semaphore.h>
 #else
 #include <asm/semaphore.h>
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
+/* Define this if you would like to load the modules in parallel.  While this
+ * can speed up loads when multiple cards handled by this driver are installed,
+ * it also makes it impossible to abort module loads with ctrl-c */
+#undef USE_ASYNC_INIT
+#include <linux/async.h>
+#else
+#undef USE_ASYNC_INIT
 #endif
 
 #include <dahdi/kernel.h>
@@ -3743,7 +3753,18 @@
 	.handle_transmit = handle_transmit,
 };
 
-static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+#ifdef USE_ASYNC_INIT
+struct async_data {
+	struct pci_dev *pdev;
+	const struct pci_device_id *ent;
+};
+static int __devinit
+__wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent,
+		 async_cookie_t cookie)
+#else
+static int __devinit
+__wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+#endif
 {
 	struct wctdm *wc;
 	int i;
@@ -3836,6 +3857,10 @@
 	/* Final initialization */
 	wctdm_post_initialize(wc);
 	
+#ifdef USE_ASYNC_INIT
+	async_synchronize_cookie(cookie);
+#endif
+
 	/* We should be ready for DAHDI to come in now. */
 	if (dahdi_register(&wc->span, 0)) {
 		dev_info(&wc->vb.pdev->dev,
@@ -3853,6 +3878,41 @@
 	voicebus_unlock_latency(&wc->vb);
 	return 0;
 }
+
+#ifdef USE_ASYNC_INIT
+static __devinit void
+wctdm_init_one_async(void *data, async_cookie_t cookie)
+{
+	struct async_data *dat = data;
+	__wctdm_init_one(dat->pdev, dat->ent, cookie);
+	kfree(dat);
+}
+
+static int __devinit
+wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct async_data *dat;
+
+	dat = kmalloc(sizeof(*dat), GFP_KERNEL);
+	/* If we can't allocate the memory for the async_data, odds are we won't
+	 * be able to initialize the device either, but let's try synchronously
+	 * anyway... */
+	if (!dat)
+		return __wctdm_init_one(pdev, ent, 0);
+
+	dat->pdev = pdev;
+	dat->ent = ent;
+	async_schedule(wctdm_init_one_async, dat);
+	return 0;
+}
+#else
+static int __devinit
+wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	return __wctdm_init_one(pdev, ent);
+}
+#endif
+
 
 static void wctdm_release(struct wctdm *wc)
 {
@@ -3965,6 +4025,10 @@
 	res = dahdi_pci_module(&wctdm_driver);
 	if (res)
 		return -ENODEV;
+
+#ifdef USE_ASYNC_INIT
+	async_synchronize_full();
+#endif
 	return 0;
 }
 




More information about the svn-commits mailing list