[dahdi-commits] sruffell: branch linux/2.4 r10084 - /linux/branches/2.4/drivers/dahdi/wctc4xxp/

SVN commits to the DAHDI project dahdi-commits at lists.digium.com
Wed Jul 27 11:27:50 CDT 2011


Author: sruffell
Date: Wed Jul 27 11:27:47 2011
New Revision: 10084

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=10084
Log:
wctc4xxp: Cleanup in-flight commands when halting due to hardware error.

On one system I was seeing the board reset in the middle of a
transaction. Any commands that were on the response list when this would
happen would never be completed and the process would then be stuck in
an uninterruptible sleep. This change also prevents the driver from
sleeping in timer context, which would result in a kernel panic.

This change at least lets an error message propogate back to the user.

DAHDI-880

Signed-off-by: Shaun Ruffell <sruffell at digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10082

Conflicts:

	drivers/dahdi/wctc4xxp/base.c

Modified:
    linux/branches/2.4/drivers/dahdi/wctc4xxp/base.c

Modified: linux/branches/2.4/drivers/dahdi/wctc4xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/branches/2.4/drivers/dahdi/wctc4xxp/base.c?view=diff&rev=10084&r1=10083&r2=10084
==============================================================================
--- linux/branches/2.4/drivers/dahdi/wctc4xxp/base.c (original)
+++ linux/branches/2.4/drivers/dahdi/wctc4xxp/base.c Wed Jul 27 11:27:47 2011
@@ -1614,6 +1614,20 @@
 wctc4xxp_transmit_cmd(struct wcdte *wc, struct tcb *cmd)
 {
 	int res;
+
+	/* If we're shutdown all commands will timeout. Just complete the
+	 * command here with the timeout flag */
+	if (unlikely(test_bit(DTE_SHUTDOWN, &wc->flags))) {
+		if (cmd->flags & DO_NOT_AUTO_FREE) {
+			cmd->flags |= DTE_CMD_TIMEOUT;
+			list_del_init(&cmd->node);
+			complete(&cmd->complete);
+		} else {
+			list_del(&cmd->node);
+			free_cmd(cmd);
+		}
+		return;
+	}
 
 	if (cmd->data_len < MIN_PACKET_LEN) {
 		memset((u8 *)(cmd->data) + cmd->data_len, 0,
@@ -2741,11 +2755,10 @@
 }
 
 static void
-wctc4xxp_stop_dma(struct wcdte *wc)
+_wctc4xxp_stop_dma(struct wcdte *wc)
 {
 	/* Disable interrupts and reset */
 	unsigned int reg;
-	unsigned long newjiffies;
 	/* Disable interrupts */
 	wctc4xxp_setintmask(wc, 0x00000000);
 	wctc4xxp_setctl(wc, 0x0084, 0x00000000);
@@ -2754,14 +2767,20 @@
 	reg = wctc4xxp_getctl(wc, 0x0000);
 	reg |= 0x00000001;
 	wctc4xxp_setctl(wc, 0x0000, reg);
-
+}
+
+static void
+wctc4xxp_stop_dma(struct wcdte *wc)
+{
+	unsigned long newjiffies;
+
+	_wctc4xxp_stop_dma(wc);
 	newjiffies = jiffies + HZ; /* One second timeout */
 	/* We'll wait here for the part to come out of reset */
 	while (((wctc4xxp_getctl(wc, 0x0000)) & 0x00000001) &&
 		(newjiffies > jiffies))
 			msleep(1);
 }
-
 
 #define MDIO_SHIFT_CLK		0x10000
 #define MDIO_DATA_WRITE1 	0x20000
@@ -3307,13 +3326,19 @@
 		if (time_after(jiffies, cmd->timeout)) {
 			if (++cmd->retries > MAX_RETRIES) {
 				if (!(cmd->flags & TX_COMPLETE)) {
+
+					cmd->flags |= DTE_CMD_TIMEOUT;
+					list_del_init(&cmd->node);
+					complete(&cmd->complete);
+
 					set_bit(DTE_SHUTDOWN, &wc->flags);
 					spin_unlock(&wc->cmd_list_lock);
-					wctc4xxp_stop_dma(wc);
+					_wctc4xxp_stop_dma(wc);
 					DTE_PRINTK(ERR,
 					  "Board malfunctioning.  " \
 					  "Halting operation.\n");
-					return;
+					reschedule_timer = 0;
+					break;
 				}
 				/* ERROR:  We've retried the command and
 				 * haven't received the ACK or the response.




More information about the dahdi-commits mailing list