[svn-commits] sruffell: branch linux/sruffell/dahdi-transcoder r4609 - in /linux/team/sruff...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Jul 17 16:11:01 CDT 2008


Author: sruffell
Date: Thu Jul 17 16:11:01 2008
New Revision: 4609

URL: http://svn.digium.com/view/dahdi?view=rev&rev=4609
Log:
Saving more work in progress.  The big changes here are a) more DAHDI
compatibility work and b) responses from the transcoder are matched up with
commands as opposed to using variables in the wcdte structure shared between
the bottom and top halves.


Removed:
    linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/codec_test.c
Modified:
    linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi-base.c
    linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi_transcode.c
    linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/base.c
    linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wcdte_net.c
    linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wctc4xxp.h

Modified: linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi-base.c
URL: http://svn.digium.com/view/dahdi/linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi-base.c?view=diff&rev=4609&r1=4608&r2=4609
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi-base.c (original)
+++ linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi-base.c Thu Jul 17 16:11:01 2008
@@ -2512,30 +2512,29 @@
 static int dahdi_open(struct inode *inode, struct file *file)
 {
 	int unit = UNIT(file);
-	int ret = -ENXIO;
 	struct dahdi_chan *chan;
 	/* Minor 0: Special "control" descriptor */
 	if (!unit) 
 		return dahdi_ctl_open(inode, file);
 	if (unit == 250) {
-		if (!dahdi_transcode_fops)
-			request_module("dahdi_transcode");
+		if (!dahdi_transcode_fops) {
+			if (request_module("dahdi_transcode")) {
+				return -ENXIO;
+			}
+		}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+		__MOD_INC_USE_COUNT (dahdi_transcode_fops->owner);
+#else
+		if (!try_module_get(dahdi_transcode_fops->owner)) {
+			return -ENXIO;
+		}
+#endif
 		if (dahdi_transcode_fops && dahdi_transcode_fops->open) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-			if (dahdi_transcode_fops->owner) {
-				__MOD_INC_USE_COUNT (dahdi_transcode_fops->owner);
-#else
-			if (try_module_get(dahdi_transcode_fops->owner)) {
-#endif
-				ret = dahdi_transcode_fops->open(inode, file);
-				if (ret)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-					__MOD_DEC_USE_COUNT (dahdi_transcode_fops->owner);
-#else
-					module_put(dahdi_transcode_fops->owner);
-#endif
-			}
-			return ret;
+			return dahdi_transcode_fops->open(inode, file);
+		} else {
+			/* dahdi_transcode module should have exported a
+			 * file_operations table. */
+			 WARN_ON(1);
 		}
 		return -ENXIO;
 	}
@@ -3057,14 +3056,11 @@
 		return dahdi_timer_release(inode, file);
 	}
 	if (unit == 250) {
-		res = dahdi_transcode_fops->release(inode, file);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-		if (dahdi_transcode_fops->owner)
-			__MOD_DEC_USE_COUNT (dahdi_transcode_fops->owner);
-#else
-		module_put(dahdi_transcode_fops->owner);
-#endif
-		return res;
+		/* We should not be here because the dahdi_transcode.ko module
+		 * should have updated the file_operations for this file
+		 * handle when the file was opened. */
+		WARN_ON(1);
+		return -EFAULT;
 	}
 	if (unit == 254) {
 		chan = file->private_data;
@@ -5137,8 +5133,12 @@
 	if (!unit)
 		return dahdi_ctl_ioctl(inode, file, cmd, data);
 
-	if (unit == 250)
-		return dahdi_transcode_fops->ioctl(inode, file, cmd, data);
+	if (unit == 250) {
+		/* dahdi_transcode should have updated the file_operations on
+		 * this file object on open, so we shouldn't be here. */
+		WARN_ON(1);
+		return -EFAULT;
+	}
 
 	if (unit == 253) {
 		timer = file->private_data;

Modified: linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi_transcode.c
URL: http://svn.digium.com/view/dahdi/linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi_transcode.c?view=diff&rev=4609&r1=4608&r2=4609
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi_transcode.c (original)
+++ linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi_transcode.c Thu Jul 17 16:11:01 2008
@@ -49,6 +49,8 @@
 #include <linux/moduleparam.h>
 #endif
 
+#define HERE() printk(KERN_DEBUG "HERE: %s:%d\n", __FILE__, __LINE__)
+
 static int debug;
 LIST_HEAD(trans);
 static spinlock_t translock = SPIN_LOCK_UNLOCKED;
@@ -157,7 +159,7 @@
 	original_fops = file->f_op;
 	file->f_op = dahdi_transcode_fops;
 	file->private_data = NULL;
-	/* Under normal operation, this releases the reference on the zaptel
+	/* Under normal operation, this releases the reference on the DAHDI
 	 * module that was created when the file was opened. dahdi_open is
 	 * responsible for taking a reference out on this module before
 	 * calling this function. */
@@ -365,7 +367,7 @@
 	case DAHDI_TRANSCODE_OP:
 		/* This is a deprecated call from the previous transcoder
 		 * interface, which was all routed through the dahdi_ioctl in
-		 * zaptel-base.c, and this ioctl request was used to indicate
+		 * dahdi-base.c, and this ioctl request was used to indicate
 		 * that the call should be forwarded to this function. Now
 		 * when the file is opened, the f_ops pointer is updated to
 		 * point directly to this function, and we don't need a

Modified: linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/base.c
URL: http://svn.digium.com/view/dahdi/linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/base.c?view=diff&rev=4609&r1=4608&r2=4609
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/base.c (original)
+++ linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/base.c Thu Jul 17 16:11:01 2008
@@ -69,16 +69,16 @@
 #endif
 
 
-#define G729_LENGTH 20
-#define G723_LENGTH 30
-
-#define G729_SAMPLES 160	/* G.729 */
-#define G723_SAMPLES 240 	/* G.723.1 */
-
-#define G729_BYTES    20	/* G.729 */
-#define G723_6K_BYTES 24 	/* G.723.1 at 6.3kb/s */
-#define G723_5K_BYTES 20	/* G.723.1 at 5.3kb/s */
-#define G723_SID_BYTES 4	/* G.723.1 SID frame */
+#define G729_LENGTH	20
+#define G723_LENGTH	30
+
+#define G729_SAMPLES	160	/* G.729 */
+#define G723_SAMPLES	240 	/* G.723.1 */
+
+#define G729_BYTES	20	/* G.729 */
+#define G723_6K_BYTES	24 	/* G.723.1 at 6.3kb/s */
+#define G723_5K_BYTES	20	/* G.723.1 at 5.3kb/s */
+#define G723_SID_BYTES	4	/* G.723.1 SID frame */
 
 #define MDIO_SHIFT_CLK		0x10000
 #define MDIO_DATA_WRITE1 	0x20000
@@ -86,10 +86,10 @@
 #define MDIO_ENB_IN		0x40000
 #define MDIO_DATA_READ		0x80000
 
-#define RCV_CSMENCAPS     1
-#define RCV_RTP           2
-#define RCV_CSMENCAPS_ACK 3
-#define RCV_OTHER         99
+#define RCV_CSMENCAPS		1
+#define RCV_RTP			2
+#define RCV_CSMENCAPS_ACK	3
+#define RCV_OTHER		99
 
 
 int debug;
@@ -97,7 +97,6 @@
 static int debug_des_cnt; /* Set the number of times descriptor packets are displayed before the output is disabled */
 static char *mode;
 static int debug_packets;
-
 
 /*! In-memory structure shared by the host and the adapter. */
 struct dte_descriptor {
@@ -213,9 +212,9 @@
 	unsigned int len;
 
 	WARN_ON(!c);
-	len = (c->cmdlen < MIN_PACKET_LEN) ? MIN_PACKET_LEN : c->cmdlen;
-	if (c->cmdlen > 1518) {
-		printk(KERN_ERR "Invalid frame size: %d.\n", c->cmdlen);
+	len = (c->data_len < MIN_PACKET_LEN) ? MIN_PACKET_LEN : c->data_len;
+	if (c->data_len > 1518) {
+		printk(KERN_ERR "Invalid frame size: %d.\n", c->data_len);
 		return -EBUSY;
 	}
 
@@ -261,7 +260,7 @@
 		d->buffer1 = 0;
 		--dr->count;
 		WARN_ON(!c);
-		c->cmdlen = (d->des0 >> 16) & BUFFER1_SIZE_MASK;
+		c->data_len = (d->des0 >> 16) & BUFFER1_SIZE_MASK;
 	} else {
 		c = NULL;
 	}
@@ -368,18 +367,18 @@
 {
 	int res;
 
-	if (cmd->cmdlen < MIN_PACKET_LEN) {
-		HERE();
-		memset((u8*)(cmd->data) + cmd->cmdlen, 0, MIN_PACKET_LEN-cmd->cmdlen);
-		cmd->cmdlen = MIN_PACKET_LEN;
-	} else if (cmd->cmdlen > cmd->data_len) {
-		DTE_PRINTK(WARNING, "Packet of size %d passed to dte_transmit_cmd.\n", cmd->cmdlen);
-		cmd->cmdlen = cmd->data_len;
+	if (cmd->data_len < MIN_PACKET_LEN) {
+		memset((u8*)(cmd->data) + cmd->data_len, 0, MIN_PACKET_LEN-cmd->data_len);
+		cmd->data_len = MIN_PACKET_LEN;
+	} else if (cmd->data_len > cmd->data_len) {
+		DTE_PRINTK(WARNING, "Packet of size %d passed to dte_transmit_cmd.\n", cmd->data_len);
+		cmd->data_len = cmd->data_len;
 	}
 	if (!(cmd->flags & DO_NOT_CAPTURE)) {
 		wcdte_net_capture_cmd(wc, cmd);
 	}
-
+	WARN_ON(cmd->response);
+	cmd->timeout = jiffies + HZ;
 	if ((res=dte_submit(wc->txd, cmd))) {
 		if (-EBUSY == res) {
 			dte_add_to_command_list(wc, cmd);
@@ -394,13 +393,13 @@
 
 static int dte_transmit_cmd_and_wait(struct wcdte *wc, struct dte_cmd *cmd)
 {
+	cmd->flags |= DO_NOT_AUTO_FREE;
 	dte_transmit_cmd(wc, cmd);
 	wait_for_completion(&cmd->complete);
 	if (cmd->flags & DTE_CMD_TIMEOUT) {
-		/* Something is wrong with the hardware if these commands have
-		 * timedout. */
+		DTE_DEBUG(DTE_DEBUG_GENERAL, "Timeout waiting for command.\n");
 		return -EIO;
-	}
+	} 
 	return 0;
 }
 
@@ -429,12 +428,14 @@
 static int wcdte_destroy_channel_pair(struct wcdte *wc, struct channel_pvt *cpvt);
 static int __wcdte_setup_channels(struct wcdte *wc);
 
-static int __dahdi_send_cmd(struct wcdte *wc, struct dte_cmd *cmd)
+static int __dte_send_cmd(struct wcdte *wc, struct dte_cmd *cmd)
 {
 	int ret = 0;
-	cmd->flags |= (WAIT_FOR_ACK | DO_NOT_AUTO_FREE);
 	dte_transmit_cmd(wc, cmd);
 	wait_for_completion(&cmd->complete);
+	if (cmd->flags & DTE_CMD_TIMEOUT) {
+		ret = -EIO;
+	}
 	free_cmd(cmd);
 	return ret;
 }
@@ -658,20 +659,22 @@
 
 	BUG_ON(!compl_dtc);
 
-	/* If the channel complement (other half of the encoder/decoder pair) is being used... */
+	if (!dahdi_tc_is_built(compl_dtc)) {
+		DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, 
+			"Releasing a channel that was never built.\n");
+		res = 0;
+		goto error_exit;
+	}
+
+	/* If the channel complement (other half of the encoder/decoder pair) is
+	 * being used... */
 	if (dahdi_tc_is_busy(compl_dtc)) {
-		up(&wc->chansem);
-		LEAVING();
-		return -EBUSY;
+		res = -EBUSY;
+		goto error_exit;
 	}
 
 	if ((res = wcdte_destroy_channel_pair(wc, cpvt))) {
-		/* There was a problem destroying the channels.*/
-		/* \todo log a message */
-		up(&wc->chansem);
-		HERE();
-		LEAVING();
-		return res;
+		goto error_exit;
 	}
 
 	DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, "Releasing channel: %p\n", dtc);
@@ -690,6 +693,7 @@
 
 	cpvt->dte_seqno_rcv = 0;
 
+error_exit:
 	up(&wc->chansem);
 	LEAVING();
 	return res;
@@ -891,12 +895,12 @@
 	hdr = cmd->data;
 	BUG_ON(sizeof(*hdr) > cmd->data_len);
 	setup_common_header(wc, hdr);
-	hdr->op_code = cpu_to_be16(0x0100);
+	hdr->op_code = cpu_to_be16(0x0001);
 	hdr->seq_num = seqno;
 	hdr->control = 0xe0;
 	hdr->channel = channel;
 
-	cmd->cmdlen = sizeof(*hdr);
+	cmd->data_len = sizeof(*hdr);
 	dte_transmit_cmd(wc, cmd);
 }
 
@@ -913,8 +917,7 @@
 	spin_lock_bh(&wc->cmd_list_lock);
 	list_for_each_entry_safe(pos, temp, &wc->waiting_for_response_list, node) {
 		listhdr = pos->data;
-		if ((listhdr->seq_num == rxhdr->seq_num) && 
-		    (listhdr->function == rxhdr->function)) {
+		if (listhdr->function == rxhdr->function) {
 			list_del_init(&pos->node);
 			pos->flags &= ~(__WAIT_FOR_RESPONSE);
 			WARN_ON(pos->response);
@@ -962,6 +965,8 @@
 				}
 			}
 			break;
+		} else {
+			;
 		}
 	}
 	spin_unlock_bh(&wc->cmd_list_lock);
@@ -1094,7 +1099,7 @@
 		if(!(newcmd = __alloc_cmd(ALLOC_FLAGS, 0))) {
 			DTE_PRINTK(ERR, "Out of memory in %s.\n", __FUNCTION__);
 		} else {
-			newcmd->cmdlen = SFRAME_SIZE;
+			newcmd->data_len = SFRAME_SIZE;
 			dte_submit(wc->rxd, newcmd);
 		}
 		wcdte_receiveprep(wc, cmd);
@@ -1110,10 +1115,12 @@
 			spin_lock_bh(&wc->cmd_list_lock);
 			list_add_tail(&cmd->node, &wc->waiting_for_ack_list);
 			spin_unlock_bh(&wc->cmd_list_lock);
+			mod_timer(&wc->watchdog, jiffies + HZ);
 	        } else if (__WAIT_FOR_RESPONSE & cmd->flags) {
 			spin_lock_bh(&wc->cmd_list_lock);
 			list_add_tail(&cmd->node, &wc->waiting_for_response_list);
 			spin_unlock_bh(&wc->cmd_list_lock);
+			mod_timer(&wc->watchdog, jiffies + HZ);
 		} else if (DO_NOT_AUTO_FREE & cmd->flags) {
 			complete(&cmd->complete);
 		} else {
@@ -1296,7 +1303,7 @@
 			WARN();
 			return;
 		}
-		cmd->cmdlen = SFRAME_SIZE;
+		cmd->data_len = SFRAME_SIZE;
 		if ((res=dte_submit(wc->rxd, cmd))) {
 			/* When we're starting the DMA, we should always be
 			 * able to fill the ring....so something is wrong
@@ -1458,7 +1465,7 @@
 		length = (firmware->data[byteloc] << 8) | firmware->data[byteloc+1];
 		byteloc += 2;
 		cmd->flags |= (WAIT_FOR_ACK | DO_NOT_AUTO_FREE);
-		cmd->cmdlen = length;
+		cmd->data_len = length;
 		BUG_ON(length > cmd->data_len);
 		memcpy(cmd->data, &firmware->data[byteloc], length);
 		byteloc += length;
@@ -1548,6 +1555,7 @@
 	unsigned int timeslot;   
 	unsigned int part2_id;
 	struct dte_cmd *cmd;
+	const struct csm_encaps_hdr *hdr;
 
 	ENTERING();
 	
@@ -1565,37 +1573,51 @@
 	}
 
 	length = (DTE_FORMAT_G729A == complicated) ? G729_LENGTH : 
-		(DTE_FORMAT_G723_1 == complicated) ? G723_LENGTH : 0;
+	         (DTE_FORMAT_G723_1 == complicated) ? G723_LENGTH : 0;
 
 	if (!(cmd = dte_create_channel_cmd(wc, timeslot))) {
 		return -ENOMEM;
 	}
-
-	dte_transmit_cmd(wc, cmd);
-	wait_for_completion(&cmd->complete);
-
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_QUERY_CHANNEL(wc->seq_num++, timeslot)))) {
-		return res;
-	}
-#if 0
-	chan1 = wc->last_rparm1;
-#endif
+	if ((res=dte_transmit_cmd_and_wait(wc, cmd))) {
+		HERE();
+		free_cmd(cmd);
+		return res;
+	}
+	free_cmd(cmd);
+
+	cmd = dte_create_cmd(wc, CMD_MSG_QUERY_CHANNEL(wc->seq_num++, timeslot));
+	cmd->flags |= WAIT_FOR_RESPONSE;
+	if ((res=dte_transmit_cmd_and_wait(wc,cmd))) {
+		free_cmd(cmd);
+		HERE();
+		return res;
+	}
+	WARN_ON(!cmd->response);
+	hdr = (const struct csm_encaps_hdr*)cmd->response->data;
+	chan1 = le16_to_cpu(hdr->params[0]);;
+	free_cmd(cmd);
 
 	if (!(cmd = dte_create_channel_cmd(wc, part2_id))) {
+		HERE();
 		return -ENOMEM;
 	}
-	if ((res = __dahdi_send_cmd(wc, cmd))) {
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_QUERY_CHANNEL(wc->seq_num++, part2_id)))) {
-		return res;
-	}
-#if 0
-	chan2 = wc->last_rparm1;
-#endif
+	if ((res = __dte_send_cmd(wc, cmd))) {
+		HERE();
+		return res;
+	}
+	cmd = dte_create_cmd(wc, CMD_MSG_QUERY_CHANNEL(wc->seq_num++, part2_id));
+	cmd->flags |= WAIT_FOR_RESPONSE;
+	if ((res=dte_transmit_cmd_and_wait(wc,cmd))) {
+		HERE();
+		return res;
+	}
+	WARN_ON(!cmd->response);
+	hdr = (const struct csm_encaps_hdr*)cmd->response->data;
+	chan2 = le16_to_cpu(hdr->params[0]);;
+	free_cmd(cmd);
 
 	DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, 
-	  "DTE is using the following channels chan1: %d chan2: %d\n", chan1, chan2);
+	   "DTE is using the following channels chan1: %d chan2: %d\n", chan1, chan2);
 
 	BUG_ON(timeslot/2 >= wc->numchannels);
 	BUG_ON(part2_id/2 >= wc->numchannels);
@@ -1607,63 +1629,75 @@
 	BUG_ON(!cpvt2);
 
 	/* Configure complex channel */
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(cpvt1->cmd_seqno++, chan1, part2_id, timeslot)))) {
-		LEAVING();
-		return res;
-	}
-
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(cpvt1->cmd_seqno++, chan1, length, 0)))) {
-		LEAVING();
+	if ((res=dte_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(cpvt1->cmd_seqno++, chan1, part2_id, timeslot)))) {
+		LEAVING();
+		HERE();
+		return res;
+	}
+
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(cpvt1->cmd_seqno++, chan1, length, 0)))) {
+		LEAVING();
+		HERE();
 		return res;
 	}
 
 	/* Configure simple channel */
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(cpvt2->cmd_seqno++, chan2, timeslot, part2_id)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(cpvt2->cmd_seqno++, chan2, length, 0)))) {
+	if ((res=dte_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(cpvt2->cmd_seqno++, chan2, timeslot, part2_id)))) {
+		LEAVING();
+		HERE();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(cpvt2->cmd_seqno++, chan2, length, 0)))) {
 		LEAVING();
 		return res;
 	}
 
 #ifdef QUIET_DSP
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_TONECTL(cpvt1->cmd_seqno++, chan1)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_DTMFOPT(cpvt1->cmd_seqno++, chan1)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_TONECTL(cpvt2->cmd_seqno++, chan2)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_DTMFOPT(cpvt2->cmd_seqno++, chan2)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(cpvt1->cmd_seqno++, chan1)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(cpvt2->cmd_seqno++, chan2)))) {
-		LEAVING();
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_TONECTL(cpvt1->cmd_seqno++, chan1)))) {
+		LEAVING();
+		HERE();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_DTMFOPT(cpvt1->cmd_seqno++, chan1)))) {
+		LEAVING();
+		HERE();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_TONECTL(cpvt2->cmd_seqno++, chan2)))) {
+		LEAVING();
+		HERE();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_DTMFOPT(cpvt2->cmd_seqno++, chan2)))) {
+		LEAVING();
+		HERE();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(cpvt1->cmd_seqno++, chan1)))) {
+		LEAVING();
+		HERE();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(cpvt2->cmd_seqno++, chan2)))) {
+		LEAVING();
+		HERE();
 		return res;
 	}
 #endif
 
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 1, chan1, chan2, complicated, simple)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_VOPENA(cpvt1->cmd_seqno++, chan1, complicated)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_VOPENA(cpvt2->cmd_seqno++, chan2, simple)))) {
-		LEAVING();
+	if ((res=dte_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 1, chan1, chan2, complicated, simple)))) {
+		LEAVING();
+		HERE();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_VOPENA(cpvt1->cmd_seqno++, chan1, complicated)))) {
+		LEAVING();
+		HERE();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_VOPENA(cpvt2->cmd_seqno++, chan2, simple)))) {
+		LEAVING();
+		HERE();
 		return res;
 	}
 
@@ -1714,27 +1748,27 @@
 	cpvt2 = dtc2->pvt;
 
 	/* Turn off both channels */
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(cpvt1->cmd_seqno++, chan1)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(cpvt2->cmd_seqno++, chan2)))) {
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(cpvt1->cmd_seqno++, chan1)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(cpvt2->cmd_seqno++, chan2)))) {
 		LEAVING();
 		return res;
 	}
 	
 	/* Disconnect the channels */
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 0, chan1, chan2, 0, 0)))) {
+	if ((res=dte_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 0, chan1, chan2, 0, 0)))) {
 		LEAVING();
 		return res;
 	}
 
 	/* Remove the channels */
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan1)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan2)))) {
+	if ((res=dte_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan1)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan2)))) {
 		LEAVING();
 		return res;
 	}
@@ -1753,91 +1787,84 @@
 		return -ENOMEM;
 	}
 
-	HERE();
 	__dte_create_set_arm_clk_cmd(wc, cmd);
 	if ((res = dte_transmit_cmd_and_wait(wc, cmd))) {
-		HERE();
-		return res;
-	}
-	HERE();
-
-#if 0
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SET_ARM_CLK(wc->seq_num++)))) {
+		return res;
+	}
+	free_cmd(cmd);
+
+	cmd = dte_create_cmd(wc, CMD_MSG_SET_SPU_CLK(wc->seq_num++));
+	if ((res = dte_transmit_cmd_and_wait(wc, cmd))) {
+		return res;
+	}
+	free_cmd(cmd);
+
+#ifdef USE_TDM_CONFIG
+	if ((res=dte_send_cmd(wc, CMD_MSG_TDM_SELECT_BUS_MODE(wc->seq_num++)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_TDM_ENABLE_BUS(wc->seq_num++)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x03, 0x20, 0x00)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x04, 0x80, 0x04)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x05, 0x20, 0x08)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x06, 0x80, 0x0C)))) {
 		LEAVING();
 		return res;
 	}
 #endif
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SET_SPU_CLK(wc->seq_num++)))) {
+
+	if ((res=dte_send_cmd(wc, CMD_MSG_SET_ETH_HEADER(wc->seq_num++)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_IP_SERVICE_CONFIG(wc->seq_num++)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_ARP_SERVICE_CONFIG(wc->seq_num++)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_ICMP_SERVICE_CONFIG(wc->seq_num++)))) {
 		LEAVING();
 		return res;
 	}
 
 #ifdef USE_TDM_CONFIG
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_TDM_SELECT_BUS_MODE(wc->seq_num++)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_TDM_ENABLE_BUS(wc->seq_num++)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x03, 0x20, 0x00)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x04, 0x80, 0x04)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x05, 0x20, 0x08)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x06, 0x80, 0x0C)))) {
+	if ((res=dte_send_cmd(wc, CMD_MSG_DEVICE_SET_COUNTRY_CODE(wc->seq_num++)))) {
 		LEAVING();
 		return res;
 	}
 #endif
 
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SET_ETH_HEADER(wc->seq_num++)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_IP_SERVICE_CONFIG(wc->seq_num++)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_ARP_SERVICE_CONFIG(wc->seq_num++)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_ICMP_SERVICE_CONFIG(wc->seq_num++)))) {
+	if ((res=dte_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x02)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_IP_OPTIONS(wc->seq_num++)))) {
+		LEAVING();
+		return res;
+	}
+	if ((res=dte_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x04)))) {
 		LEAVING();
 		return res;
 	}
 
 #ifdef USE_TDM_CONFIG
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_DEVICE_SET_COUNTRY_CODE(wc->seq_num++)))) {
-		LEAVING();
-		return res;
-	}
-#endif
-
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x02)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_IP_OPTIONS(wc->seq_num++)))) {
-		LEAVING();
-		return res;
-	}
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x04)))) {
-		LEAVING();
-		return res;
-	}
-
-#ifdef USE_TDM_CONFIG
-	if ((res=dahdi_send_cmd(wc, CMD_MSG_TDM_OPT(wc->seq_num++)))) {
+	if ((res=dte_send_cmd(wc, CMD_MSG_TDM_OPT(wc->seq_num++)))) {
 		LEAVING();
 		return res;
 	}
@@ -2029,10 +2056,42 @@
 static void wctc4xxp_watchdog(unsigned long data)
 {
 	struct wcdte *wc = (struct wcdte *)data;
-
- 	HERE();	
-	wc->watchdog.expires = jiffies + HZ;
-	add_timer(&wc->watchdog);
+	struct dte_cmd *cmd, *temp;
+	int cmds_on_lists = 0;
+
+	spin_lock(&wc->cmd_list_lock);
+
+	/* Go through the list of messages that are waiting for an ack.. */
+	list_for_each_entry_safe(cmd, temp, &wc->waiting_for_ack_list, node) {
+		++cmds_on_lists;
+		if (time_after(jiffies, cmd->timeout)) {
+			cmd->flags |= DTE_CMD_TIMEOUT;
+			list_del_init(&cmd->node);
+			complete(&cmd->complete);
+			--cmds_on_lists;
+		}
+	}
+
+	/* Go through the list of messages that are waiting for responses from
+	 * the DTE, and complete or retry any that have timed out. */
+	list_for_each_entry_safe(cmd, temp, &wc->waiting_for_response_list, node) {
+		++cmds_on_lists;
+		WARN_ON(!(cmd->flags & (__WAIT_FOR_RESPONSE | DO_NOT_AUTO_FREE)));
+		if (time_after(jiffies, cmd->timeout)) {
+			cmd->flags |= DTE_CMD_TIMEOUT;
+			list_del_init(&cmd->node);
+			complete(&cmd->complete);
+			--cmds_on_lists;
+		} 
+	}
+	spin_unlock(&wc->cmd_list_lock);
+
+	/* Only schedule this watchdog to run if the driver is not in the
+	 * process of being unloaded, and there are items on the list that we
+	 * would like to check in the future. */
+	if (cmds_on_lists && !test_bit(DTE_SHUTDOWN, &wc->flags)) {
+		mod_timer(&wc->watchdog, jiffies + HZ);
+	}
 }
 
 static int __devinit 
@@ -2306,6 +2365,12 @@
 		return;
 	}
 
+	set_bit(DTE_SHUTDOWN, &wc->flags);
+	del_timer_sync(&wc->watchdog);
+	/* Need to call this twice in case the timer was running when the
+	 * DTE_SHUTDOWN flag was set the first time. */
+	del_timer_sync(&wc->watchdog);
+
 	wcdte_net_unregister(wc);
 
 	wcdte_debugfs_remove_board_entry(wc);

Modified: linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wcdte_net.c
URL: http://svn.digium.com/view/dahdi/linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wcdte_net.c?view=diff&rev=4609&r1=4608&r2=4609
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wcdte_net.c (original)
+++ linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wcdte_net.c Thu Jul 17 16:11:01 2008
@@ -45,11 +45,11 @@
 wcdte_cmd_to_skb(struct net_device *netdev, const struct dte_cmd *cmd)
 {
 	struct sk_buff *skb;
-	skb = alloc_skb(cmd->cmdlen, in_atomic() ? GFP_ATOMIC : GFP_KERNEL);
+	skb = alloc_skb(cmd->data_len, in_atomic() ? GFP_ATOMIC : GFP_KERNEL);
 	if (skb) {
 		skb->dev = netdev;
-		skb_put(skb, cmd->cmdlen);
-		memcpy(skb->data, cmd->data, cmd->cmdlen);
+		skb_put(skb, cmd->data_len);
+		memcpy(skb->data, cmd->data, cmd->data_len);
 		skb->protocol = eth_type_trans(skb,netdev);
 	}
 	return skb;
@@ -63,8 +63,8 @@
 	/* const static char dev_mac[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; */
 	if ((cmd = __alloc_cmd(alloc_flags, 0))) {
 		int res;
-		cmd->cmdlen = skb->len;
-		if ((res = skb_copy_bits(skb, 0, cmd->data, cmd->cmdlen))) {
+		cmd->data_len = skb->len;
+		if ((res = skb_copy_bits(skb, 0, cmd->data, cmd->data_len))) {
 			DTE_PRINTK(WARNING, 
 			   "Failed call to skb_copy_bits.\n");
 			free_cmd(cmd);

Modified: linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wctc4xxp.h
URL: http://svn.digium.com/view/dahdi/linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wctc4xxp.h?view=diff&rev=4609&r1=4608&r2=4609
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wctc4xxp.h (original)
+++ linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wctc4xxp.h Thu Jul 17 16:11:01 2008
@@ -88,9 +88,13 @@
 
 struct wcdte;
 struct dte_cmd {
-	/*! number of bytes in cmd */
-	unsigned int cmdlen;
 	struct list_head node;
+	/* The jiffies when this command is to expire. */
+	unsigned long timeout;
+	/* The number of times to retry this command. */
+	unsigned long retries;
+	/* NOTE:  these flags aren't bit fields because some of the flags are
+	 * combinations of the other ones. */
 #define DO_NOT_AUTO_FREE        (1 << 0)
 #define TX_COMPLETE             (1 << 1)
 #define DO_NOT_CAPTURE          (1 << 2)
@@ -102,7 +106,6 @@
 	unsigned long flags;
 	struct dte_cmd *response;
 	struct completion complete;
-	unsigned long timeout;
 	void *data;
 	/* The number of bytes available in data. */
 	int data_len; 
@@ -155,6 +158,9 @@
 static inline void 
 free_cmd(struct dte_cmd *cmd)
 {
+	if (cmd->response) {
+		kmem_cache_free(cmd_cache, cmd->response);
+	}
 	if (cmd->data != &cmd->cmd[0]) {
 		kfree(cmd->data);
 	}
@@ -209,7 +215,8 @@
 	wait_queue_head_t waitq;
 	struct semaphore chansem;
 	atomic_t open_channel_count;
-#define DTE_READY (1 << 0)
+#define DTE_READY	1
+#define DTE_SHUTDOWN	2 
 	unsigned long flags;
 
 	spinlock_t cmd_list_lock;
@@ -287,17 +294,27 @@
 #if 1
  /* \todo This macro is a candidate for removal.  It's still here because of
  * how the commands are passed to this dahdi_send_cmd */
-#define dahdi_send_cmd(wc, command) ({                                          \
+#define dte_send_cmd(wc, command) ({                                         \
 	int __res;                                                           \
 	u8 _cmd[] = command;                                                 \
 	struct dte_cmd *cmd;                                                 \
-	if (!(cmd=__alloc_cmd(GFP_KERNEL, 0)))                               \
-	    return -ENOMEM;                                                  \
+	if (!(cmd=__alloc_cmd(GFP_KERNEL, WAIT_FOR_RESPONSE)))               \
+		return -ENOMEM;                                              \
 	BUG_ON(sizeof(_cmd) > SFRAME_SIZE);                                  \
-	memcpy(cmd->cmd, _cmd, sizeof(_cmd));                                \
-	cmd->cmdlen = sizeof(_cmd);                                          \
-	__res = __dahdi_send_cmd(wc, cmd);                                   \
+	memcpy(cmd->data, _cmd, sizeof(_cmd));                               \
+	cmd->data_len = sizeof(_cmd);                                        \
+	__res = __dte_send_cmd(wc, cmd);                                     \
 	__res;                                                               \
+})
+#define dte_create_cmd(wc, command) ({                                       \
+	u8 _command[] = command;                                             \
+	struct dte_cmd *_cmd;                                                \
+	if (!(_cmd=__alloc_cmd(GFP_KERNEL, WAIT_FOR_RESPONSE)))              \
+		return -ENOMEM;                                              \
+	BUG_ON(sizeof(_command) > SFRAME_SIZE);                              \
+	memcpy(_cmd->data, _command, sizeof(_command));                      \
+	_cmd->data_len = sizeof(_command);                                   \
+	_cmd;                                                                \
 })
 #endif
 




More information about the svn-commits mailing list