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

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jul 21 09:56:36 CDT 2008


Author: sruffell
Date: Mon Jul 21 09:56:36 2008
New Revision: 4617

URL: http://svn.digium.com/view/dahdi?view=rev&rev=4617
Log:
Saving off more work in progress. 

- Fixed a memory leak with the response packets.
- Implemented retries on commands.


Modified:
    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_commands.h
    linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wctc4xxp.h
    linux/team/sruffell/dahdi-transcoder/include/dahdi/kernel.h

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=4617&r1=4616&r2=4617
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi_transcode.c (original)
+++ linux/team/sruffell/dahdi-transcoder/drivers/dahdi/dahdi_transcode.c Mon Jul 21 09:56:36 2008
@@ -63,33 +63,33 @@
 
 struct dahdi_transcoder *dahdi_transcoder_alloc(int numchans)
 {
-	struct dahdi_transcoder *ztc;
+	struct dahdi_transcoder *tc;
 	unsigned int x;
-	size_t size = sizeof(*ztc) + (sizeof(ztc->channels[0]) * numchans);
-
-	if (!(ztc = kmalloc(size, GFP_KERNEL)))
+	size_t size = sizeof(*tc) + (sizeof(tc->channels[0]) * numchans);
+
+	if (!(tc = kmalloc(size, GFP_KERNEL)))
 		return NULL;
 
-	memset(ztc, 0, size);
-	strcpy(ztc->name, "<unspecified>");
-	ztc->numchannels = numchans;
-	for (x=0;x<ztc->numchannels;x++) {
-		init_waitqueue_head(&ztc->channels[x].ready);
-		INIT_LIST_HEAD(&ztc->node);
-		ztc->channels[x].parent = ztc;
+	memset(tc, 0, size);
+	strcpy(tc->name, "<unspecified>");
+	tc->numchannels = numchans;
+	for (x=0;x<tc->numchannels;x++) {
+		init_waitqueue_head(&tc->channels[x].ready);
+		INIT_LIST_HEAD(&tc->node);
+		tc->channels[x].parent = tc;
 	}
 
 	WARN_ON(!dahdi_transcode_fops);
 	/* Individual transcoders should supply their own file_operations for
 	 * write and read.  But they will by default use the file_operations
 	 * provided by the dahdi_transcode layer.  */
-	memcpy(&ztc->fops, dahdi_transcode_fops, sizeof(*dahdi_transcode_fops));
-	return ztc;
-}
-
-void dahdi_transcoder_free(struct dahdi_transcoder *ztc)
-{
-	kfree(ztc);
+	memcpy(&tc->fops, dahdi_transcode_fops, sizeof(*dahdi_transcode_fops));
+	return tc;
+}
+
+void dahdi_transcoder_free(struct dahdi_transcoder *tc)
+{
+	kfree(tc);
 }
 
 /* Returns 1 if the item is on the list pointed to by head, otherwise, returns
@@ -146,9 +146,9 @@
 }
 
 /* Alert a transcoder */
-int dahdi_transcoder_alert(struct dahdi_transcoder_channel *ztc)
-{
-	wake_up_interruptible(&ztc->ready);
+int dahdi_transcoder_alert(struct dahdi_transcoder_channel *chan)
+{
+	wake_up_interruptible(&chan->ready);
 	return 0;
 }
 
@@ -167,23 +167,23 @@
 	return 0;
 }
 
-static void ztc_release(struct dahdi_transcoder_channel *ztc)
-{
-	BUG_ON(!ztc);
-	if (ztc->parent && ztc->parent->operation) {
-		ztc->parent->operation(ztc, DAHDI_TCOP_RELEASE);
-	}
-	dahdi_tc_clear_busy(ztc);
+static void dtc_release(struct dahdi_transcoder_channel *chan)
+{
+	BUG_ON(!chan);
+	if (chan->parent && chan->parent->release) {
+		chan->parent->release(chan);
+	}
+	dahdi_tc_clear_busy(chan);
 }
 
 static int dahdi_tc_release(struct inode *inode, struct file *file)
 {
-	struct dahdi_transcoder_channel *ztc = file->private_data;
+	struct dahdi_transcoder_channel *chan = file->private_data;
 	/* There will not be a transcoder channel associated with this file if
 	 * the ALLOCATE ioctl never succeeded. 
 	 */
-	if (ztc) {
-		ztc_release(ztc);
+	if (chan) {
+		dtc_release(chan);
 	}
 
 	return 0;
@@ -194,16 +194,16 @@
 get_free_channel(struct dahdi_transcoder *tc)
 
 {
-	struct dahdi_transcoder_channel *ztc;
+	struct dahdi_transcoder_channel *chan;
 	int i;
 	/* Should be called with the translock held. */
 	WARN_ON(!spin_is_locked(&translock));
 
 	for (i = 0; i < tc->numchannels; i++) {
-		ztc = &tc->channels[i];
-		if (!dahdi_tc_is_busy(ztc)) {
-			dahdi_tc_set_busy(ztc);
-			return ztc;
+		chan = &tc->channels[i];
+		if (!dahdi_tc_is_busy(chan)) {
+			dahdi_tc_set_busy(chan);
+			return chan;
 		}
 	}
 	return NULL;
@@ -220,7 +220,7 @@
 __find_free_channel(struct list_head *list, const struct dahdi_transcoder_formats *fmts)
 {
 	struct dahdi_transcoder *tc;
-	struct dahdi_transcoder_channel *ztc = NULL;
+	struct dahdi_transcoder_channel *chan = NULL;
 	unsigned int match = 0;
 
 	list_for_each_entry(tc, list, node) {
@@ -228,14 +228,14 @@
 			/* We found a transcoder that can handle our formats.
 			 * Now look for an available channel. */
 			match = 1; 
-			if ((ztc = get_free_channel(tc))) {
+			if ((chan = get_free_channel(tc))) {
 				/* transcoder tc has a free channel.  In order
 				 * to spread the load among available
 				 * transcoders (when there are more than one
 				 * transcoder in the system) we'll move tc 
 				 * to the end of the list. */
 				list_move_tail(&tc->node, list);
-				return ztc;
+				return chan;
 			}
 		}
 	}
@@ -244,7 +244,7 @@
 
 static long dahdi_tc_allocate(struct file *file, unsigned long data)
 {
-	struct dahdi_transcoder_channel *ztc = NULL;
+	struct dahdi_transcoder_channel *chan = NULL;
 	struct dahdi_transcoder_formats fmts;
 	
 	if (copy_from_user(&fmts, 
@@ -253,43 +253,47 @@
 	}
 
 	spin_lock(&translock);
-	ztc = __find_free_channel(&trans, &fmts);
+	chan = __find_free_channel(&trans, &fmts);
 	spin_unlock(&translock);
 
-	if (IS_ERR(ztc)) {
-		return PTR_ERR(ztc);
+	if (IS_ERR(chan)) {
+		return PTR_ERR(chan);
 	}
 
 	/* Every transcoder channel must be associated with a parent
 	 * transcoder. */
-	BUG_ON(!ztc->parent);
-
-	ztc->srcfmt = fmts.srcfmt;
-	ztc->dstfmt = fmts.dstfmt;
+	BUG_ON(!chan->parent);
+
+	chan->srcfmt = fmts.srcfmt;
+	chan->dstfmt = fmts.dstfmt;
 
 	if (file->private_data) {
 		/* This open file is moving to a new channel. Cleanup and
 		 * close the old channel here.  */
-		ztc_release(file->private_data);
-	}
-
-	file->private_data = ztc;
-	if (ztc->parent->fops.owner != file->f_op->owner) {
-		if (!try_module_get(ztc->parent->fops.owner)) {
+		dtc_release(file->private_data);
+	}
+
+	file->private_data = chan;
+	if (chan->parent->fops.owner != file->f_op->owner) {
+		if (!try_module_get(chan->parent->fops.owner)) {
 			/* Failed to get a reference on the driver for the
 			 * actual transcoding hardware.  */
 			return -EINVAL;
 		}
 		/* Release the reference on the existing driver. */
 		module_put(file->f_op->owner);
-		file->f_op = &ztc->parent->fops;
-	}
-
-	(file->f_flags & O_NONBLOCK) ? dahdi_tc_set_nonblock(ztc) : dahdi_tc_clear_nonblock(ztc);
+		file->f_op = &chan->parent->fops;
+	}
+
+	if (file->f_flags & O_NONBLOCK) {
+		dahdi_tc_set_nonblock(chan);
+	} else {
+		dahdi_tc_clear_nonblock(chan); 
+	}
 
 	/* Actually reset the transcoder channel */
-	if (ztc->parent->operation)
-		return ztc->parent->operation(ztc, DAHDI_TCOP_ALLOCATE);
+	if (chan->parent->allocate)
+		return chan->parent->allocate(chan);
 
 	return -EINVAL;
 }
@@ -372,8 +376,7 @@
 		 * when the file is opened, the f_ops pointer is updated to
 		 * point directly to this function, and we don't need a
 		 * general indication that the ioctl is destined for the
-		 * transcoder.
-		 */
+		 * transcoder.  */
 		printk(KERN_WARNING "%s: DAHDI_TRANSCODE_OP is no longer " \
 		   "supported. Please call DAHDI_TC ioctls directly.\n",
 		   THIS_MODULE->name);
@@ -397,19 +400,19 @@
 static unsigned int dahdi_tc_poll(struct file *file, struct poll_table_struct *wait_table)
 {
 	int ret;
-	struct dahdi_transcoder_channel *ztc = file->private_data;
-
-	if (!ztc) {
+	struct dahdi_transcoder_channel *chan = file->private_data;
+
+	if (!chan) {
 		/* This is because the DAHDI_TC_ALLOCATE ioctl was not called
 		 * before calling poll, which is invalid. */
 		return -EINVAL;
 	}
 
-	poll_wait(file, &ztc->ready, wait_table);
-
-	ret =  dahdi_tc_is_busy(ztc)         ? 0       : POLLPRI;
-	ret |= dahdi_tc_is_built(ztc)        ? POLLOUT : 0;
-	ret |= dahdi_tc_is_data_waiting(ztc) ? POLLIN  : 0;
+	poll_wait(file, &chan->ready, wait_table);
+
+	ret =  dahdi_tc_is_busy(chan)         ? 0       : POLLPRI;
+	ret |= dahdi_tc_is_built(chan)        ? POLLOUT : 0;
+	ret |= dahdi_tc_is_data_waiting(chan) ? POLLIN  : 0;
 	return ret;
 }
 

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=4617&r1=4616&r2=4617
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/base.c (original)
+++ linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/base.c Mon Jul 21 09:56:36 2008
@@ -253,7 +253,7 @@
 	d = dte_descriptor(dr, head);
 	if (d->buffer1 && !OWNED(d)) {
 		pci_unmap_single(dr->pdev, d->buffer1, 
-			SFRAME_SIZE, dr->direction);
+		                 SFRAME_SIZE, dr->direction);
 		c = dr->pending[head];
 		WARN_ON(!c);
 		dr->head = (++head) & DRING_MASK; 
@@ -268,6 +268,15 @@
 	return c;
 }
 
+static inline int dte_getcount(struct dte_descriptor_ring *dr) 
+{
+	int count;
+	spin_lock_bh(&dr->lock);
+	count = dr->count;
+	spin_unlock_bh(&dr->lock);
+	return count;
+}
+
 static inline void __wcdte_setctl(struct wcdte *wc, unsigned int addr, unsigned int val)
 {
 	outl(val, wc->iobase + addr);
@@ -288,14 +297,15 @@
 /* Instruct the DTE to read in the next rx descriptor */
 static inline void dte_receive_demand_poll(struct wcdte *wc) 
 {
-	wcdte_setctl(wc, 0x0010, 0x00000000);
+	__wcdte_setctl(wc, 0x0010, 0x00000000);
 }
 
 /* Instruct the DTE to read in the next tx descriptor */
 static inline void dte_transmit_demand_poll(struct wcdte *wc)
 {
-	spin_lock_bh(&wc->reglock);
+	// spin_lock_bh(&wc->reglock);
 	__wcdte_setctl(wc, 0x0008, 0x00000000);
+
 	/* \todo Investigate why this register needs to be written twice in
 	 * order to get it to poll reliably.  So far, most of the problems
 	 * I've seen with timeouts had more to do with an untransmitted
@@ -303,7 +313,7 @@
 	 * problem with the dte firmware.
 	 */
 	__wcdte_setctl(wc, 0x0008, 0x00000000);
-	spin_unlock_bh(&wc->reglock);
+	// spin_unlock_bh(&wc->reglock);
 }
 
 static void
@@ -319,7 +329,7 @@
 		d = dte_descriptor(dr, i);
 		if (d->buffer1) {
 			dma_unmap_single(&dr->pdev->dev, d->buffer1, 
-				SFRAME_SIZE, dr->direction);
+			                 SFRAME_SIZE, dr->direction);
 			d->buffer1 = 0;
 			free_cmd(dr->pending[i]);
 			dr->pending[i] = NULL;
@@ -368,17 +378,20 @@
 	int res;
 
 	if (cmd->data_len < MIN_PACKET_LEN) {
-		memset((u8*)(cmd->data) + cmd->data_len, 0, MIN_PACKET_LEN-cmd->data_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);
+		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;
+	cmd->timeout = jiffies + HZ/4;
 	if ((res=dte_submit(wc->txd, cmd))) {
 		if (-EBUSY == res) {
 			dte_add_to_command_list(wc, cmd);
@@ -533,15 +546,11 @@
 	} else {
 		down(&wc->chansem);
 	}
-
 	DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, 
 	          "Entering %s for channel %p.\n", __FUNCTION__, dtc);
-
 	/* Anything on the rx queue now is old news... */
 	wcdte_cleanup_channel_private(wc, cpvt);
-
 	DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, "Allocating a new channel: %p.\n", dtc);
-
 	dte_srcfmt = wcdte_dahdifmt_to_dtefmt(dtc->srcfmt);
 	dte_dstfmt = wcdte_dahdifmt_to_dtefmt(dtc->dstfmt);
 	if ((res = wcdte_create_channel_pair(wc, cpvt, dte_srcfmt, dte_dstfmt))) {
@@ -550,16 +559,12 @@
 		LEAVING();
 		return res;
 	}
-
 	/* Mark this channel as built */
 	dahdi_tc_set_built(dtc);
 	dtc->built_fmts = dtc->dstfmt | dtc->srcfmt;
-
 	/* Mark the channel complement (other half of encoder/decoder pair) as built */
 	res = wcdte_mark_channel_complement_built(wc, dtc);
-
 	up(&wc->chansem);
-	
 	dahdi_transcoder_alert(dtc);
 	LEAVING();
 	return res;
@@ -583,9 +588,16 @@
 
 	WARN_ON(!dahdi_tc_is_nonblock(channel_work->dtc));
 
+retry:
 	/* \todo Make sure this is safe from races... */
 	if (-EAGAIN == do_channel_allocate(channel_work->dtc)) {
 		struct wcdte *wc = ((struct channel_pvt*)(channel_work->dtc->pvt))->wc;
+		HERE();
+
+		/* !!!SRR!!! */
+		msleep(10);
+		goto retry;
+
 		spin_lock(&wc->supervisor_list_lock);
 		list_add_tail(&channel_work->work.entry, &wc->supervisor_list);
 		spin_unlock(&wc->supervisor_list_lock);
@@ -599,21 +611,17 @@
 dte_operation_allocate(struct dahdi_transcoder_channel *dtc)
 {
 	struct wcdte *wc = ((struct channel_pvt*)(dtc->pvt))->wc;
-	ENTERING();
-
 	if (dahdi_tc_is_built(dtc)) {
 		DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, 
 		          "Allocating channel %p which is already built.\n", dtc);
 		LEAVING();
 		return 0;
 	}
-
 	if (dahdi_tc_is_nonblock(dtc)) {
 		struct channel_allocate_work *channel_work;
 		if (!(channel_work = kmalloc(sizeof(*channel_work), GFP_KERNEL))) {
 			return -ENOMEM;
 		}
-
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
 		INIT_WORK(&channel_work->work, allocate_channel_work_func, channel_work);
 #else
@@ -643,56 +651,49 @@
 	BUG_ON(!cpvt);
 	BUG_ON(!wc);
 
-	down(&wc->chansem);
-
+	/* !!!SRR!!! change this back to down after troubleshooting */
+	if (down_interruptible(&wc->chansem)) {
+		HERE();
+		return -EINTR;
+	}
 	/* Remove any packets that are waiting on the outbound queue. */
 	wcdte_cleanup_channel_private(wc, cpvt);
-	
 	index = cpvt->timeslot_in_num/2;
 	BUG_ON(index >= wc->numchannels);
-
 	if (ENCODER == cpvt->encoder) {
 		compl_dtc = &(wc->udecode->channels[index]);
 	} else {
 		compl_dtc = &(wc->uencode->channels[index]);
 	}
-
 	BUG_ON(!compl_dtc);
-
 	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)) {
 		res = -EBUSY;
 		goto error_exit;
 	}
-
 	if ((res = wcdte_destroy_channel_pair(wc, cpvt))) {
 		goto error_exit;
 	}
-
 	DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, "Releasing channel: %p\n", dtc);
 	/* Mark this channel as not built */
 	dahdi_tc_clear_built(dtc);
 	dtc->built_fmts = 0;
 	cpvt->chan_in_num = INVALID;
 	cpvt->chan_out_num = INVALID;
-	
 	/* Mark the channel complement as not built */
 	dahdi_tc_clear_built(compl_dtc);
 	compl_dtc->built_fmts = 0;
 	compl_cpvt = compl_dtc->pvt;
 	compl_cpvt->chan_in_num = INVALID;
 	compl_cpvt->chan_out_num = INVALID;
-
 	cpvt->dte_seqno_rcv = 0;
-
 error_exit:
 	up(&wc->chansem);
 	LEAVING();
@@ -857,23 +858,6 @@
 
 	LEAVING();
 	return count;
-}
-
-static int dte_operation(struct dahdi_transcoder_channel *dtc, int op)
-{
-	int res = 0;
-	switch(op) {
-	case DAHDI_TCOP_ALLOCATE:
-		res = dte_operation_allocate(dtc);
-		break;
-	case DAHDI_TCOP_RELEASE:
-		res = dte_operation_release(dtc);
-		break;
-	default:
-		WARN();
-		break;
-	}
-	return res;
 }
 
 static void 
@@ -1002,7 +986,7 @@
 			}
 			free_cmd(cmd);
 		} else if (0xd4 == hdr->type) {
-			if (hdr->params[0] != 0xffff) {
+			if (hdr->params[0] != le16_to_cpu(0xffff)) {
 				DTE_PRINTK(WARNING, 
 				   "DTE Failed self test (%04x).\n", 
 				   le16_to_cpu(hdr->params[0]));
@@ -1064,7 +1048,7 @@
 
 static inline void wcdte_receiveprep(struct wcdte *wc, struct dte_cmd *cmd)
 {
-	const struct ethhdr *ethhdr = (const struct ethhdr*)(cmd->cmd);
+	const struct ethhdr *ethhdr = (const struct ethhdr*)(cmd->data);
 
 	if (cpu_to_be16(ETH_P_IP) == ethhdr->h_proto) {
 		queue_rtp_packet(wc, cmd);
@@ -1099,8 +1083,19 @@
 		if(!(newcmd = __alloc_cmd(ALLOC_FLAGS, 0))) {
 			DTE_PRINTK(ERR, "Out of memory in %s.\n", __FUNCTION__);
 		} else {
-			newcmd->data_len = SFRAME_SIZE;
-			dte_submit(wc->rxd, newcmd);
+			/* 
+			newcmd->data = kmalloc(1518, ALLOC_FLAGS);
+			if (!newcmd->data) {
+				DTE_PRINTK(ERR, "out of memory in %s " \
+				    "again.\n", __FUNCTION__);
+			}
+			newcmd->data_len = 1518;
+			*/
+			if (dte_submit(wc->rxd, newcmd)) {
+				DTE_PRINTK(ERR, "Failed submit in %s\n", __FUNCTION__);
+				free_cmd(newcmd);
+			}
+			dte_receive_demand_poll(wc);
 		}
 		wcdte_receiveprep(wc, cmd);
 	}
@@ -1202,7 +1197,8 @@
 			DTE_PRINTK(INFO, "Receive Stopped INT\n");
 
 		if ((ints & 0x00000080) && debug) {
-			DTE_PRINTK(INFO, "Receive Desciptor Unavailable INT\n");
+			DTE_PRINTK(INFO, "Receive Desciptor Unavailable INT " \
+			    "(%d)\n", dte_getcount(wc->rxd));
 		}
 
 		if ((ints & 0x00000020) && debug)
@@ -1586,7 +1582,6 @@
 	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();
@@ -2008,7 +2003,8 @@
 	}
 	(*zt)->srcfmts = srcfmts;
 	(*zt)->dstfmts = dstfmts;
-	(*zt)->operation = dte_operation;
+	(*zt)->allocate = dte_operation_allocate;
+	(*zt)->release = dte_operation_release;
 	dte_setup_file_operations(&((*zt)->fops));
 	for (chan = 0; chan < wc->numchannels; ++chan) {
 		(*zt)->channels[chan].pvt = &pvts[chan];
@@ -2058,6 +2054,8 @@
 	struct wcdte *wc = (struct wcdte *)data;
 	struct dte_cmd *cmd, *temp;
 	int cmds_on_lists = 0;
+	LIST_HEAD(cmds_to_retry);
+	const int MAX_RETRIES = 5;
 
 	spin_lock(&wc->cmd_list_lock);
 
@@ -2065,10 +2063,17 @@
 	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;
+			if (++cmd->retries > MAX_RETRIES) {
+				cmd->flags |= DTE_CMD_TIMEOUT;
+				list_del_init(&cmd->node);
+				complete(&cmd->complete);
+				--cmds_on_lists;
+			} else {
+				/* Just move this to the local list because
+				 * we're going to resend it once we free the
+				 * locks */
+				list_move_tail(&cmd->node, &cmds_to_retry);
+			}
 		}
 	}
 
@@ -2078,18 +2083,31 @@
 		++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;
+			if (++cmd->retries > MAX_RETRIES) {
+				cmd->flags |= DTE_CMD_TIMEOUT;
+				list_del_init(&cmd->node);
+				complete(&cmd->complete);
+				--cmds_on_lists;
+			} else {
+				/* Just move this to the local list because
+				 * we're going to resend it once we free the
+				 * locks */
+				list_move_tail(&cmd->node, &cmds_to_retry);
+			}
 		} 
 	}
 	spin_unlock(&wc->cmd_list_lock);
+
+	list_for_each_entry_safe(cmd, temp, &cmds_to_retry, node) {
+		HERE();
+		cmd->flags |= __WAIT_FOR_ACK;
+		dte_transmit_cmd(wc, cmd);
+	}
 
 	/* 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)) {
+	if (debug || (cmds_on_lists && !test_bit(DTE_SHUTDOWN, &wc->flags))) {
 		mod_timer(&wc->watchdog, jiffies + HZ);
 	}
 }
@@ -2245,8 +2263,7 @@
 	}
 
 	setup_timer(&wc->watchdog, wctc4xxp_watchdog, (unsigned long)wc); 
-	wc->watchdog.expires = jiffies + HZ;
-	add_timer(&wc->watchdog);
+	mod_timer(&wc->watchdog, jiffies + HZ);
 
 	/* ------------------------------------------------------------------
 	 * Load the firmware and start the DTE.

Modified: linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wcdte_commands.h
URL: http://svn.digium.com/view/dahdi/linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wcdte_commands.h?view=diff&rev=4617&r1=4616&r2=4617
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wcdte_commands.h (original)
+++ linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wcdte_commands.h Mon Jul 21 09:56:36 2008
@@ -1,3 +1,5 @@
+#ifndef __WCDTE_COMMANDS__
+#define __WCDTE_COMMANDS__
 
 /* \todo It might be clearer if these commands were mapped to packed stuctures
  * instead of used as byte arrays. */
@@ -237,8 +239,11 @@
 	0x24,0x00, 0x00,0x00 }
 
 struct dahdi_transcoder_channel;
+struct wcdte;
 
 void setup_common_header(struct wcdte *wc, struct csm_encaps_hdr *hdr);
 struct dte_cmd * dte_create_channel_cmd(struct wcdte *wc, u16 timeslot);
 struct dte_cmd * dte_create_rtp_cmd(struct wcdte *wc, struct dahdi_transcoder_channel *dtc, unsigned int inbytes);
 void __dte_create_set_arm_clk_cmd(struct wcdte *wc, struct dte_cmd *cmd);
+
+#endif

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=4617&r1=4616&r2=4617
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wctc4xxp.h (original)
+++ linux/team/sruffell/dahdi-transcoder/drivers/dahdi/wctc4xxp/wctc4xxp.h Mon Jul 21 09:56:36 2008
@@ -35,6 +35,7 @@
 #include <linux/completion.h>
 
 #include "dahdi/kernel.h"
+#include "wcdte_commands.h"
 
 /* COMPILE TIME OPTIONS =================================================== */
 
@@ -109,7 +110,7 @@
 	void *data;
 	/* The number of bytes available in data. */
 	int data_len; 
-#define SFRAME_SIZE 260 
+#define SFRAME_SIZE (240+sizeof(struct rtp_packet)) 
 	/* cmd must be the last field. */
 	u8 cmd[SFRAME_SIZE];
 };
@@ -155,17 +156,22 @@
 	return __alloc_cmd(GFP_KERNEL, 0);
 }
 
-static inline void 
-free_cmd(struct dte_cmd *cmd)
-{
-	if (cmd->response) {
-		kmem_cache_free(cmd_cache, cmd->response);
-	}
+static inline void __free_cmd(struct dte_cmd *cmd)
+{
 	if (cmd->data != &cmd->cmd[0]) {
 		kfree(cmd->data);
 	}
 	kmem_cache_free(cmd_cache, cmd);
 	return;
+}
+
+static inline void 
+free_cmd(struct dte_cmd *cmd)
+{
+	if (cmd->response) {
+		__free_cmd(cmd->response);
+	}
+	__free_cmd(cmd);
 }
 
 struct dte_descriptor_ring;

Modified: linux/team/sruffell/dahdi-transcoder/include/dahdi/kernel.h
URL: http://svn.digium.com/view/dahdi/linux/team/sruffell/dahdi-transcoder/include/dahdi/kernel.h?view=diff&rev=4617&r1=4616&r2=4617
==============================================================================
--- linux/team/sruffell/dahdi-transcoder/include/dahdi/kernel.h (original)
+++ linux/team/sruffell/dahdi-transcoder/include/dahdi/kernel.h Mon Jul 21 09:56:36 2008
@@ -813,25 +813,6 @@
 #define DAHDI_TONEDETECT_ON	(1 << 0)		/* Detect tones */
 #define DAHDI_TONEDETECT_MUTE	(1 << 1)		/* Mute audio in received channel */
 
-#define DAHDI_TRANSCODE_MAGIC 0x74a9c0de
-
-/* Operations */
-#define DAHDI_TCOP_ALLOCATE	1	/* Allocate/reset DTE channel */
-#define DAHDI_TCOP_TRANSCODE	2	/* Begin transcoding a block */
-#define DAHDI_TCOP_GETINFO	3	/* Get information (use dahdi_transcode_info) */
-#define DAHDI_TCOP_RELEASE	4	/* Release DTE channel */
-#define DAHDI_TCOP_TEST		5	/* test DTE device */
-#if 0 /* !!!SRR!!! Remove these */
-typedef struct dahdi_transcode_info {
-	unsigned int op;
-	unsigned int tcnum;
-	char name[80];
-	int numchannels;
-	unsigned int srcfmts;
-	unsigned int dstfmts;
-} DAHDI_TRANSCODE_INFO;
-#endif 
-
 #define DAHDI_TC_CODE	'T'
 
 struct dahdi_transcoder_formats {
@@ -849,42 +830,6 @@
 };
 #define DAHDI_TC_GETINFO	_IOWR(DAHDI_TC_CODE, 2, \
 				      struct dahdi_transcoder_info)
-
-#define DAHDI_TCCONF_USETS		(1 << 0)		/* Use/update timestamp field */
-#define DAHDI_TCCONF_USESEQ	(1 << 1)		/* Use/update seqno field */
-
-#define DAHDI_TCSTAT_DSTRDY	(1 << 0)		/* Destination data is ready */
-#define DAHDI_TCSTAT_DSTBUSY	(1 << 1)		/* Destination data is outstanding */
-
-#if 0 /* !!!SRR!!! */
-#define __DAHDI_TRANSCODE_BUFSIZ	16384
-#define DAHDI_TRANSCODE_HDRLEN	256
-#define DAHDI_TRANSCODE_BUFSIZ	((__DAHDI_TRANSCODE_BUFSIZ) - (DAHDI_TRANSCODE_HDRLEN))
-#define DAHDI_TRANSCODE_DSTOFFSET	(((DAHDI_TRANSCODE_BUFSIZ) / 2) + DAHDI_TRANSCODE_HDRLEN)
-#define DAHDI_TRANSCODE_SRCOFFSET	(((DAHDI_TRANSCODE_BUFSIZ) / 2) + DAHDI_TRANSCODE_HDRLEN)
-
-typedef struct dahdi_transcode_header {
-	unsigned int srcfmt;		/* See formats.h -- use TCOP_RESET when you change */
-	unsigned int srcoffset; 	/* In bytes -- written by user */
-	unsigned int srclen;		/* In bytes -- written by user */
-	unsigned int srctimestamp;	/* In samples -- written by user (only used if DAHDI_TCCONF_USETS is set) */
-	unsigned int srcseqno;		/* In units -- written by user (only used if DAHDI_TCCONF_USESEQ is set) */
-
-	unsigned int dstfmt;		/* See formats.h -- use TCOP_RESET when you change */
-	unsigned int dstoffset;  	/* In bytes -- written by user */
-	unsigned int dsttimestamp;	/* In samples -- read by user */
-	unsigned int dstseqno;		/* In units -- read by user (only used if DAHDI_TCCONF_USESEQ is set) */
-	unsigned int dstlen;  		/* In bytes -- read by user */
-	unsigned int dstsamples;	/* In timestamp units -- read by user */
-
-	unsigned int magic;		/* Magic value -- DAHDI_TRANSCODE_MAGIC, read by user */
-	unsigned int config;		/* Read/write by user */
-	unsigned int status;		/* Read/write by user */
-	unsigned char userhdr[DAHDI_TRANSCODE_HDRLEN - (sizeof(unsigned int) * 14)];	/* Storage for user parameters */
-	unsigned char srcdata[DAHDI_TRANSCODE_BUFSIZ / 2];	/* Storage of source data */
-	unsigned char dstdata[DAHDI_TRANSCODE_BUFSIZ / 2];	/* Storage of destination data */
-} DAHDI_TRANSCODE_HEADER;
-#endif 
 
 struct dahdi_ring_cadence {
 	int ringcadence[DAHDI_MAX_CADENCE];
@@ -1648,40 +1593,52 @@
 	u32 srcfmt;
 };
 
-static inline int dahdi_tc_is_built(struct dahdi_transcoder_channel *dtc) {
+static inline int 
+dahdi_tc_is_built(struct dahdi_transcoder_channel *dtc) {
 	return test_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags);
 }
-static inline void dahdi_tc_set_built(struct dahdi_transcoder_channel *dtc) {
+static inline void
+dahdi_tc_set_built(struct dahdi_transcoder_channel *dtc) {
 	set_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags);
 }
-static inline void dahdi_tc_clear_built(struct dahdi_transcoder_channel *dtc) {
+static inline void 
+dahdi_tc_clear_built(struct dahdi_transcoder_channel *dtc) {
 	clear_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags);
 }
-static inline int dahdi_tc_is_nonblock(struct dahdi_transcoder_channel *dtc) {
+static inline int 
+dahdi_tc_is_nonblock(struct dahdi_transcoder_channel *dtc) {
 	return test_bit(DAHDI_TC_FLAG_NONBLOCK, &dtc->flags);
 }
-static inline void dahdi_tc_set_nonblock(struct dahdi_transcoder_channel *dtc) {
+static inline void 
+dahdi_tc_set_nonblock(struct dahdi_transcoder_channel *dtc) {
 	set_bit(DAHDI_TC_FLAG_NONBLOCK, &dtc->flags);
 }
-static inline void dahdi_tc_clear_nonblock(struct dahdi_transcoder_channel *dtc) {
+static inline void 
+dahdi_tc_clear_nonblock(struct dahdi_transcoder_channel *dtc) {
 	clear_bit(DAHDI_TC_FLAG_NONBLOCK, &dtc->flags);
 }
-static inline int dahdi_tc_is_data_waiting(struct dahdi_transcoder_channel *dtc) {
+static inline int 
+dahdi_tc_is_data_waiting(struct dahdi_transcoder_channel *dtc) {
 	return test_bit(DAHDI_TC_FLAG_DATA_WAITING, &dtc->flags);
 }
-static inline int dahdi_tc_is_busy(struct dahdi_transcoder_channel *dtc) {
+static inline int 
+dahdi_tc_is_busy(struct dahdi_transcoder_channel *dtc) {
 	return test_bit(DAHDI_TC_FLAG_BUSY, &dtc->flags);
 }
-static inline void dahdi_tc_set_busy(struct dahdi_transcoder_channel *dtc) {
+static inline void 
+dahdi_tc_set_busy(struct dahdi_transcoder_channel *dtc) {
 	set_bit(DAHDI_TC_FLAG_BUSY, &dtc->flags);
 }
-static inline void dahdi_tc_clear_busy(struct dahdi_transcoder_channel *dtc) {
+static inline void 
+dahdi_tc_clear_busy(struct dahdi_transcoder_channel *dtc) {
 	clear_bit(DAHDI_TC_FLAG_BUSY, &dtc->flags);
 }
-static inline void dahdi_tc_set_data_waiting(struct dahdi_transcoder_channel *dtc) {
+static inline void 
+dahdi_tc_set_data_waiting(struct dahdi_transcoder_channel *dtc) {
 	set_bit(DAHDI_TC_FLAG_DATA_WAITING, &dtc->flags);
 }
-static inline void dahdi_tc_clear_data_waiting(struct dahdi_transcoder_channel *dtc) {
+static inline void 
+dahdi_tc_clear_data_waiting(struct dahdi_transcoder_channel *dtc) {
 	clear_bit(DAHDI_TC_FLAG_DATA_WAITING, &dtc->flags);
 }
 
@@ -1691,9 +1648,9 @@
 	int numchannels;
 	unsigned int srcfmts;
 	unsigned int dstfmts;
-	/* !!!SRR!!! Review to see if this operation pointer can be dropped */
-	int (*operation)(struct dahdi_transcoder_channel *channel, int op);
 	struct file_operations fops;
+	int (*allocate)(struct dahdi_transcoder_channel *channel);
+	int (*release)(struct dahdi_transcoder_channel *channel);
 	/* Transcoder channels */
 	struct dahdi_transcoder_channel channels[0];
 };




More information about the svn-commits mailing list