[svn-commits] sruffell: linux/trunk r5413 - /linux/trunk/drivers/dahdi/wctc4xxp/base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Dec 1 09:59:14 CST 2008


Author: sruffell
Date: Mon Dec  1 09:59:14 2008
New Revision: 5413

URL: http://svn.digium.com/view/dahdi?view=rev&rev=5413
Log:
Service the transmit descriptor ring before the receive descriptor ring so
that commands that are still sitting on the transmit descriptor ring are not
completed twice.

Modified:
    linux/trunk/drivers/dahdi/wctc4xxp/base.c

Modified: linux/trunk/drivers/dahdi/wctc4xxp/base.c
URL: http://svn.digium.com/view/dahdi/linux/trunk/drivers/dahdi/wctc4xxp/base.c?view=diff&rev=5413&r1=5412&r2=5413
==============================================================================
--- linux/trunk/drivers/dahdi/wctc4xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wctc4xxp/base.c Mon Dec  1 09:59:14 2008
@@ -1818,8 +1818,9 @@
 		    (listhdr->channel == rxhdr->channel)) {
 			list_del_init(&pos->node);
 			pos->flags &= ~(__WAIT_FOR_RESPONSE);
+			pos->response = cmd;
 			WARN_ON(pos->response);
-			pos->response = cmd;
+			WARN_ON(!(pos->flags & TX_COMPLETE));
 			complete(&pos->complete);
 			break;
 		}
@@ -1844,6 +1845,7 @@
 			wc->seq_num = (rxhdr->seq_num + 1) & 0xff;
 			WARN_ON(!(pos->flags & DO_NOT_AUTO_FREE));
 			list_del_init(&pos->node);
+			WARN_ON(!(pos->flags & TX_COMPLETE));
 			complete(&pos->complete);
 		} else if ((listhdr->seq_num == rxhdr->seq_num) && 
 			   (listhdr->channel == rxhdr->channel)) {
@@ -1853,6 +1855,7 @@
 				list_del_init(&pos->node);
 
 				if (pos->flags & DO_NOT_AUTO_FREE) {
+					WARN_ON(!(pos->flags & TX_COMPLETE));
 					complete(&pos->complete);
 				} else {
 					free_cmd(pos);
@@ -1975,14 +1978,44 @@
 	}
 }
 
-static inline void service_dte(struct wcdte *wc) 
+static inline void service_tx_ring(struct wcdte *wc)
 {
 	struct tcb *cmd;
-
-	/* 
-	 * Process the received packets
-	 */
-	while((cmd = wctc4xxp_retrieve(wc->rxd))) {
+	while ((cmd = wctc4xxp_retrieve(wc->txd))) {
+		if (!(cmd->flags & (__WAIT_FOR_ACK | __WAIT_FOR_RESPONSE))) {
+			/* If we're not waiting for an ACK or Response from
+			 * the DTE, this message should not be sitting on any
+			 * lists. */
+			WARN_ON(!list_empty(&cmd->node));
+			if (DO_NOT_AUTO_FREE & cmd->flags) {
+				WARN_ON(!(pos->flags & TX_COMPLETE));
+				complete(&cmd->complete);
+			} else {
+				free_cmd(cmd);
+			}
+		}
+		/* We've freed up a spot in the hardware ring buffer.  If
+		 * another packet is queued up, let's submit it to the
+		 * hardware. */
+		spin_lock_bh(&wc->cmd_list_lock);
+		if (!list_empty(&wc->cmd_list)) {
+			cmd = list_entry(wc->cmd_list.next, struct tcb, node);
+			list_del_init(&cmd->node);
+		} else {
+			cmd = NULL;
+		}
+		spin_unlock_bh(&wc->cmd_list_lock);
+
+		if (cmd) {
+			wctc4xxp_transmit_cmd(wc, cmd);
+		}
+	}
+}
+
+static inline void service_rx_ring(struct wcdte *wc)
+{
+	struct tcb *cmd;
+	while ((cmd = wctc4xxp_retrieve(wc->rxd))) {
 		struct tcb *newcmd;
 
 		wctc4xxp_net_capture_cmd(wc, cmd);
@@ -2007,38 +2040,12 @@
 		wctc4xxp_receiveprep(wc, cmd);
 	}
 	wctc4xxp_receive_demand_poll(wc);
-	
-	/* 
-	 * Process the transmit packets
-	 */
-	while((cmd = wctc4xxp_retrieve(wc->txd))) {
-		if (!(cmd->flags & (__WAIT_FOR_ACK | __WAIT_FOR_RESPONSE))) {
-			/* If we're not waiting for an ACK or Response from
-			 * the DTE, this message should not be sitting on any
-			 * lists. */
-			WARN_ON(!list_empty(&cmd->node));
-			if (DO_NOT_AUTO_FREE & cmd->flags) {
-				complete(&cmd->complete);
-			} else {
-				free_cmd(cmd);
-			}
-		}
-		/* We've freed up a spot in the hardware ring buffer.  If
-		 * another packet is queued up, let's submit it to the
-		 * hardware. */
-		spin_lock_bh(&wc->cmd_list_lock);
-		if (!list_empty(&wc->cmd_list)) {
-			cmd = list_entry(wc->cmd_list.next, struct tcb, node);
-			list_del_init(&cmd->node);
-		} else {
-			cmd = NULL;
-		}
-		spin_unlock_bh(&wc->cmd_list_lock);
-
-		if (cmd) {
-			wctc4xxp_transmit_cmd(wc, cmd);
-		}
-	}
+}
+
+static inline void service_dte(struct wcdte *wc) 
+{
+	service_tx_ring(wc);
+	service_rx_ring(wc);	
 }
 
 
@@ -2832,6 +2839,9 @@
 	LIST_HEAD(cmds_to_retry);
 	const int MAX_RETRIES = 5;
 
+	/* Check for any commands that have completed transmitted. */
+	service_tx_ring(wc);
+
 	spin_lock(&wc->cmd_list_lock);
 	/* Go through the list of messages that are waiting for responses from
 	 * the DTE, and complete or retry any that have timed out. */
@@ -2850,7 +2860,6 @@
 				 * received the ACK or the response. */
 				cmd->flags |= DTE_CMD_TIMEOUT;
 				list_del_init(&cmd->node);
-				complete(&cmd->complete);
 			} else if (cmd->flags & TX_COMPLETE) {
 				/* Move this to the local list because we're
 				 * going to resend it once we free the locks */




More information about the svn-commits mailing list