[svn-commits] sruffell: branch 1.4 r4582 - /branches/1.4/kernel/wctc4xxp/base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Nov 17 13:43:24 CST 2008


Author: sruffell
Date: Mon Nov 17 13:43:23 2008
New Revision: 4582

URL: http://svn.digium.com/view/zaptel?view=rev&rev=4582
Log:
- Fix for race condition of encoder and decoder are allocated at the same time
  in the driver.  This would result in -EBUSY returns from the
  DAHDI_TC_ALLOCATE ioctl.
- Increase the length of the receive descriptor ring from 8 to 32 to reduce
  the probability of running out of receive descriptors.


Modified:
    branches/1.4/kernel/wctc4xxp/base.c

Modified: branches/1.4/kernel/wctc4xxp/base.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/kernel/wctc4xxp/base.c?view=diff&rev=4582&r1=4581&r2=4582
==============================================================================
--- branches/1.4/kernel/wctc4xxp/base.c (original)
+++ branches/1.4/kernel/wctc4xxp/base.c Mon Nov 17 13:43:23 2008
@@ -432,8 +432,6 @@
 	struct channel_stats stats;
 
 	u16 last_dte_seqno;
-	unsigned int wctc4xxp_seqno_rcv;
-
 	unsigned char ssrc;
 	struct list_head rx_queue;	/* Transcoded packets for this channel. */
 };
@@ -898,7 +896,7 @@
 	__le32 container; /* Unused */
 } __attribute__((packed));
 
-#define DRING_SIZE (1 << 3) /* Must be a power of two */
+#define DRING_SIZE (1 << 5) /* Must be a power of two */
 #define DRING_MASK (DRING_SIZE-1)
 #define MIN_PACKET_LEN  64
 
@@ -1444,6 +1442,7 @@
 	spin_lock_bh(&cpvt->lock);
 	list_splice_init(&cpvt->rx_queue, &local_list);
 	zt_tc_clear_data_waiting(dtc);
+	cpvt->last_dte_seqno = 0;
 	spin_unlock_bh(&cpvt->lock);
 
 	list_for_each_entry_safe(cmd, temp, &local_list, node) {
@@ -1492,7 +1491,19 @@
 	u8 wctc4xxp_dstfmt; /* Digium Transcoder Engine Dest Format */
 	int res;
 
-	down(&wc->chansem);
+	if (down_interruptible(&wc->chansem)) {
+		return -EINTR;
+	}
+	/* Check again to see if the channel was built after grabbing the
+	 * channel semaphore, in case the previous holder of the semaphore
+	 * built this channel as a complement to itself. */
+	if (dahdi_tc_is_built(dtc)) {
+		up(&wc->chansem);
+		DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, 
+		          "Allocating channel %p which is already built.\n", dtc);
+		return 0;
+	}
+	
 	DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, 
 	          "Entering %s for channel %p.\n", __FUNCTION__, dtc);
 	/* Anything on the rx queue now is old news... */
@@ -1557,10 +1568,10 @@
 		return -EIO;
 	}
 
-	/* !!!SRR!!! change this back to down after troubleshooting */
 	if (down_interruptible(&wc->chansem)) {
 		return -EINTR;
 	}
+
 	/* Remove any packets that are waiting on the outbound queue. */
 	wctc4xxp_cleanup_channel_private(wc, dtc);
 	index = cpvt->timeslot_in_num/2;
@@ -1578,9 +1589,9 @@
 		goto error_exit;
 	}
 	/* If the channel complement (other half of the encoder/decoder pair) is
-	 * being used... */
+	 * being used.*/
 	if (zt_tc_is_busy(compl_dtc)) {
-		res = -EBUSY;
+		res = 0;
 		goto error_exit;
 	}
 	if ((res = wctc4xxp_destroy_channel_pair(wc, cpvt))) {
@@ -1598,7 +1609,6 @@
 	compl_cpvt = compl_dtc->pvt;
 	compl_cpvt->chan_in_num = INVALID;
 	compl_cpvt->chan_out_num = INVALID;
-	cpvt->wctc4xxp_seqno_rcv = 0;
 error_exit:
 	up(&wc->chansem);
 	return res;
@@ -1676,20 +1686,18 @@
 
 	atomic_inc(&cpvt->stats.packets_received);
 
-	if (0 == cpvt->wctc4xxp_seqno_rcv) {
-		cpvt->wctc4xxp_seqno_rcv = 1;
+	if (!(cpvt->last_dte_seqno)) {
 		cpvt->last_dte_seqno = be16_to_cpu(packet->rtphdr.seqno);
 	} else {
 		rtp_eseq = ++cpvt->last_dte_seqno;
-		if ( be16_to_cpu(packet->rtphdr.seqno) != rtp_eseq )
+		cpvt->last_dte_seqno = be16_to_cpu(packet->rtphdr.seqno);
+		if (rtp_eseq != cpvt->last_dte_seqno)
 			DTE_DEBUG(DTE_DEBUG_GENERAL,
 			 "Bad seqno from DTE! [%04X][%d][%d][%d]\n", 
 			 be16_to_cpu(packet->rtphdr.seqno), 
 			 (be16_to_cpu(packet->udphdr.dest) - 0x5000),
 			 be16_to_cpu(packet->rtphdr.seqno), 
 			 rtp_eseq);
-
-		cpvt->last_dte_seqno = be16_to_cpu(packet->rtphdr.seqno);
 	}
 
 	if (unlikely(copy_to_user(frame, &packet->payload[0], payload_bytes))) {




More information about the svn-commits mailing list