[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