[svn-commits] sruffell: branch linux/sruffell/dahdi-linux-wctc4xxp r8526 - /linux/team/sruf...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Apr 14 13:24:53 CDT 2010


Author: sruffell
Date: Wed Apr 14 13:24:51 2010
New Revision: 8526

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8526
Log:
wctc4xxp: Do not ACK response packets without a corresponding request.

Closes a small window of opportunity where system conditions prevent
the driver from servicing it's receive ring within the timeout period of
a request, and then in the middle of retrying the request (after the request
was already removed from the "waiting_for_response" list) the driver process
the response, it's possible for the driver to ACK the response without ever
pairing it up with the original request. The result being that the DTE will
then ignore our attempts to retry the original request. DAHDI-430.

Modified:
    linux/team/sruffell/dahdi-linux-wctc4xxp/drivers/dahdi/wctc4xxp/base.c

Modified: linux/team/sruffell/dahdi-linux-wctc4xxp/drivers/dahdi/wctc4xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/dahdi-linux-wctc4xxp/drivers/dahdi/wctc4xxp/base.c?view=diff&rev=8526&r1=8525&r2=8526
==============================================================================
--- linux/team/sruffell/dahdi-linux-wctc4xxp/drivers/dahdi/wctc4xxp/base.c (original)
+++ linux/team/sruffell/dahdi-linux-wctc4xxp/drivers/dahdi/wctc4xxp/base.c Wed Apr 14 13:24:51 2010
@@ -1,5 +1,4 @@
-/*
- * Wildcard TC400B Driver
+/* Wildcard TC400B Driver
  *
  * Copyright (C) 2006-2010, Digium, Inc.
  *
@@ -38,6 +37,8 @@
 #include <linux/udp.h>
 #include <linux/etherdevice.h>
 #include <linux/timer.h>
+
+#include <stdbool.h>
 
 #include "dahdi/kernel.h"
 
@@ -2216,19 +2217,18 @@
 	wctc4xxp_transmit_cmd(wc, cmd);
 }
 
-static void
-do_rx_response_packet(struct wcdte *wc, struct tcb *cmd)
+static bool do_rx_response_packet(struct wcdte *wc, struct tcb *cmd)
 {
 	const struct csm_encaps_hdr *listhdr, *rxhdr;
 	struct tcb *pos, *temp;
 	unsigned long flags;
-	u32 handled = 0;
+	bool handled = false;
 	rxhdr = cmd->data;
-	if (0xffff == rxhdr->channel) {
+	if (SUPERVISOR_CHANNEL == rxhdr->channel) {
 		/* We received a duplicate response. */
 		if (rxhdr->seq_num == wc->last_rx_seq_num) {
 			free_cmd(cmd);
-			return;
+			return false;
 		}
 		wc->last_rx_seq_num = rxhdr->seq_num;
 	}
@@ -2249,7 +2249,7 @@
 			if (pos->flags & TX_COMPLETE)
 				complete(&pos->complete);
 			spin_unlock(&pos->lock);
-			handled = 1;
+			handled = true;
 
 			break;
 		}
@@ -2261,7 +2261,10 @@
 			"Freeing unhandled response ch:(%04x)\n",
 			be16_to_cpu(rxhdr->channel));
 		free_cmd(cmd);
-	}
+		return false;
+	}
+
+	return true;
 }
 
 static void
@@ -2355,12 +2358,19 @@
 	const struct csm_encaps_hdr *hdr = cmd->data;
 
 	if (!(hdr->control & MESSAGE_PACKET)) {
-		if (!(hdr->control & SUPPRESS_ACK))
-			wctc4xxp_send_ack(wc, hdr->seq_num, hdr->channel);
-
 		if (is_response(hdr)) {
-			do_rx_response_packet(wc, cmd);
+			u8 seq_num = hdr->seq_num;
+			__be16 channel = hdr->channel;
+			int suppress_ack = ((hdr->control & SUPPRESS_ACK) == SUPPRESS_ACK);
+
+			if (do_rx_response_packet(wc, cmd)) {
+				if (!suppress_ack)
+					wctc4xxp_send_ack(wc, seq_num, channel);
+			}
 		} else if (0xc1 == hdr->type) {
+			if (!(hdr->control & SUPPRESS_ACK))
+				wctc4xxp_send_ack(wc, hdr->seq_num, hdr->channel);
+
 			if (0x75 == hdr->class) {
 				DTE_PRINTK(WARNING,
 				   "Received alert (0x%04x) from dsp\n",
@@ -2368,6 +2378,8 @@
 			}
 			free_cmd(cmd);
 		} else if (0xd4 == hdr->type) {
+			if (!(hdr->control & SUPPRESS_ACK))
+					wctc4xxp_send_ack(wc, hdr->seq_num, hdr->channel);
 			if (hdr->params[0] != le16_to_cpu(0xffff)) {
 				DTE_PRINTK(WARNING,
 				   "DTE Failed self test (%04x).\n",
@@ -2383,10 +2395,14 @@
 			}
 			free_cmd(cmd);
 		} else if (MONITOR_LIVE_INDICATION_TYPE == hdr->type) {
+			if (!(hdr->control & SUPPRESS_ACK))
+					wctc4xxp_send_ack(wc, hdr->seq_num, hdr->channel);
 			DTE_PRINTK(WARNING, "Received diagnostic message:\n");
 			print_command(wc, cmd);
 			free_cmd(cmd);
 		} else {
+			if (!(hdr->control & SUPPRESS_ACK))
+				wctc4xxp_send_ack(wc, hdr->seq_num, hdr->channel);
 			DTE_PRINTK(WARNING,
 			  "Unknown command type received. %02x\n", hdr->type);
 			free_cmd(cmd);




More information about the svn-commits mailing list