[svn-commits] sruffell: linux/trunk r8003 - in /linux/trunk: drivers/dahdi/voicebus/ driver...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Feb 8 16:49:39 CST 2010


Author: sruffell
Date: Mon Feb  8 16:49:32 2010
New Revision: 8003

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8003
Log:
vpmadt032,wcte12xp: Use a timeout on the read/write commands and during load.

It is possible for poorly behaving hardware (and driver bugs) to lockup the
modprobe process by having it wait indefinitely for a command to complete that
never will.  DAHDI-451.

Modified:
    linux/trunk/drivers/dahdi/voicebus/GpakCust.c
    linux/trunk/drivers/dahdi/voicebus/voicebus.c
    linux/trunk/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c
    linux/trunk/drivers/dahdi/wcte12xp/base.c
    linux/trunk/include/dahdi/kernel.h

Modified: linux/trunk/drivers/dahdi/voicebus/GpakCust.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/voicebus/GpakCust.c?view=diff&rev=8003&r1=8002&r2=8003
==============================================================================
--- linux/trunk/drivers/dahdi/voicebus/GpakCust.c (original)
+++ linux/trunk/drivers/dahdi/voicebus/GpakCust.c Mon Feb  8 16:49:32 2010
@@ -133,9 +133,18 @@
 	u16 addr, u16 *outbuf, struct vpmadt032_cmd *cmd)
 {
 	unsigned long flags;
-	int ret = -EIO;
+	unsigned long ret;
 	BUG_ON(!cmd);
-	wait_for_completion(&cmd->complete);
+
+	/* We'll wait for 200ms */
+	ret = wait_for_completion_timeout(&cmd->complete, HZ/5);
+	if (unlikely(!ret)) {
+		spin_lock_irqsave(&vpm->list_lock, flags);
+		list_add_tail(&cmd->node, &vpm->free_cmds);
+		spin_unlock_irqrestore(&vpm->list_lock, flags);
+		return -EIO;
+	}
+
 	if (cmd->desc & __VPM150M_FIN) {
 		*outbuf = cmd->data;
 		cmd->desc = 0;
@@ -146,7 +155,7 @@
 	spin_lock_irqsave(&vpm->list_lock, flags);
 	list_add_tail(&cmd->node, &vpm->free_cmds);
 	spin_unlock_irqrestore(&vpm->list_lock, flags);
-	return ret;
+	return 0;
 }
 
 /* Read one of the registers on the VPMADT032 */

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=8003&r1=8002&r2=8003
==============================================================================
--- linux/trunk/drivers/dahdi/voicebus/voicebus.c (original)
+++ linux/trunk/drivers/dahdi/voicebus/voicebus.c Mon Feb  8 16:49:32 2010
@@ -997,23 +997,6 @@
 	VBUNLOCK(vb);
 }
 
-static unsigned long
-vb_wait_for_completion_timeout(struct completion *x, unsigned long timeout)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
-	/* There is a race condition here.  If x->done is reset to 0
-	 * before the call to wait_for_completion after this thread wakes.
-	 */
-	timeout = wait_event_timeout(x->wait, x->done, timeout);
-	if (timeout)
-		wait_for_completion(x);
-
-	return timeout;
-#else
-	return wait_for_completion_timeout(x, timeout);
-#endif
-}
-
 /*!
  * \brief Stops the VoiceBus interface.
  *
@@ -1036,7 +1019,7 @@
 	set_bit(STOP, &vb->flags);
 	vb_clear_start_transmit_bit(vb);
 	vb_clear_start_receive_bit(vb);
-	if (vb_wait_for_completion_timeout(&vb->stopped_completion, HZ)) {
+	if (wait_for_completion_timeout(&vb->stopped_completion, HZ)) {
 		BUG_ON(!vb_is_stopped(vb));
 	} else {
 		dev_warn(&vb->pdev->dev, "Timeout while waiting for board to "

Modified: linux/trunk/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c?view=diff&rev=8003&r1=8002&r2=8003
==============================================================================
--- linux/trunk/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c (original)
+++ linux/trunk/drivers/dahdi/vpmadt032_loader/dahdi_vpmadt032_loader.c Mon Feb  8 16:49:32 2010
@@ -116,13 +116,17 @@
 	pci_set_drvdata(vb->pdev, ctx);
 	old = vb->ops;
 	vb->ops = &loader_operations;
-	wait_for_completion(&ctx->done);
+	if (wait_for_completion_timeout(&ctx->done, HZ*2)) {
+		dev_err(&vb->pdev->dev,
+			"Timeout waiting for load in %s.\n", __func__);
+		ret = -EIO;
+	}
 	vb->ops = old;
 	pci_set_drvdata(vb->pdev, old_drvdata);
 	__vpmadt032_cleanup(ctx->pvt);
 error_exit:
 	kfree(ctx);
-	return 0;
+	return ret;
 }
 
 static struct vpmadt_loader loader = {

Modified: linux/trunk/drivers/dahdi/wcte12xp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wcte12xp/base.c?view=diff&rev=8003&r1=8002&r2=8003
==============================================================================
--- linux/trunk/drivers/dahdi/wcte12xp/base.c (original)
+++ linux/trunk/drivers/dahdi/wcte12xp/base.c Mon Feb  8 16:49:32 2010
@@ -559,7 +559,7 @@
 static int t1_getreg(struct t1 *wc, int addr)
 {
 	struct command *cmd =  NULL;
-	int ret;
+	unsigned long ret;
 
 	might_sleep();
 
@@ -570,7 +570,15 @@
 	cmd->data = 0x00;
 	cmd->flags = __CMD_RD;
 	submit_cmd(wc, cmd);
-	wait_for_completion(&cmd->complete);
+	ret = wait_for_completion_timeout(&cmd->complete, HZ/5);
+	if (unlikely(ret)) {
+		if (printk_ratelimit()) {
+			dev_warn(&wc->vb.pdev->dev,
+				 "Timeout in %s\n", __func__);
+		}
+		free_cmd(wc, cmd);
+		return -EIO;
+	}
 	ret = cmd->data;
 	free_cmd(wc, cmd);
 	return ret;
@@ -592,8 +600,8 @@
 
 static inline int t1_getpins(struct t1 *wc, int inisr)
 {
-	int ret = 0;
 	struct command *cmd;
+	unsigned long ret;
 
 	cmd = get_free_cmd(wc);
 	BUG_ON(!cmd);
@@ -602,10 +610,18 @@
 	cmd->data = 0x00;
 	cmd->flags = __CMD_PINS;
 	submit_cmd(wc, cmd);
-	wait_for_completion(&cmd->complete);
+	ret = wait_for_completion_timeout(&cmd->complete, HZ/5);
+	if (unlikely(ret)) {
+		if (printk_ratelimit()) {
+			dev_warn(&wc->vb.pdev->dev,
+				 "Timeout in %s\n", __func__);
+		}
+		free_cmd(wc, cmd);
+		return -EIO;
+	}
 	ret = cmd->data;
 	free_cmd(wc, cmd);
-	return ret;
+	return 0;
 }
 
 static void __t1xxp_set_clear(struct t1 *wc, int channo)

Modified: linux/trunk/include/dahdi/kernel.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/include/dahdi/kernel.h?view=diff&rev=8003&r1=8002&r2=8003
==============================================================================
--- linux/trunk/include/dahdi/kernel.h (original)
+++ linux/trunk/include/dahdi/kernel.h Mon Feb  8 16:49:32 2010
@@ -1174,10 +1174,8 @@
 /*! Maximum audio mask */
 #define DAHDI_FORMAT_AUDIO_MASK	((1 << 16) - 1)
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
-#define kzalloc(a, b) kcalloc(1, a, b)
-#endif
-
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
+#define KERN_CONT ""
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
 static inline void list_replace(struct list_head *old, struct list_head *new)
 {
@@ -1186,7 +1184,25 @@
         new->prev = old->prev;
         new->prev->next = new;
 }
-#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
+#define kzalloc(a, b) kcalloc(1, a, b)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
+static inline unsigned long
+wait_for_completion_timeout(struct completion *x, unsigned long timeout)
+{
+	/* There is a race condition here.  If x->done is reset to 0
+	 * before the call to wait_for_completion after this thread wakes.
+	 */
+	timeout = wait_event_timeout(x->wait, x->done, timeout);
+	if (timeout)
+		wait_for_completion(x);
+
+	return timeout;
+}
+#endif /* 2.6.11 */
+#endif /* 2.6.14 */
+#endif /* 2.6.18 */
+#endif /* 2.6.31 */
 
 #ifndef DMA_BIT_MASK
 #define DMA_BIT_MASK(n)	(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))




More information about the svn-commits mailing list