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

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


Author: sruffell
Date: Wed Apr 14 13:00:04 2010
New Revision: 8525

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8525
Log:
wctc4xxp: Allow read to return more than one packet of data.

As of this writing codec_dahdi (Asterisk module) will not call 'read' on a
transcoder channel more often than it calls 'write'.  When a translation
path is setup that will transcode from g723 to g729, write is called every
30ms and each 'read' returns only 20ms of data.  The end result is audio
that slowly becomes increasing delayed.

Since codec_dahdi calls the system read function with a buffer large enough
to hold more than one packet this can prevents packets from backing up
on the channel. DAHDI-582

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=8525&r1=8524&r2=8525
==============================================================================
--- 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:00:04 2010
@@ -1,7 +1,7 @@
 /*
  * Wildcard TC400B Driver
  *
- * Copyright (C) 2006-2009, Digium, Inc.
+ * Copyright (C) 2006-2010, Digium, Inc.
  *
  * All rights reserved.
  *
@@ -2038,6 +2038,8 @@
 	struct tcb *cmd;
 	struct rtp_packet *packet;
 	ssize_t payload_bytes;
+	ssize_t returned_bytes = 0;
+	unsigned long flags;
 
 	BUG_ON(!dtc);
 	BUG_ON(!cpvt);
@@ -2050,48 +2052,63 @@
 
 	cmd = get_ready_cmd(dtc);
 	if (!cmd) {
-		if (file->f_flags & O_NONBLOCK) {
+		if (file->f_flags & O_NONBLOCK)
 			return -EAGAIN;
-		} else {
-			ret = wait_event_interruptible(dtc->ready,
+		ret = wait_event_interruptible(dtc->ready,
 				dahdi_tc_is_data_waiting(dtc));
-			if (-ERESTARTSYS == ret) {
-				/* Signal interrupted the wait */
-				return -EINTR;
-			} else {
-				/* List went not empty. */
-				cmd = get_ready_cmd(dtc);
+		if (-ERESTARTSYS == ret)
+			return -EINTR;
+		/* List went not empty. */
+		cmd = get_ready_cmd(dtc);
+	}
+
+	do {
+		BUG_ON(!cmd);
+		packet = cmd->data;
+
+		payload_bytes = be16_to_cpu(packet->udphdr.len) -
+					sizeof(struct rtphdr) -
+					sizeof(struct udphdr);
+
+		if ((count + returned_bytes) < payload_bytes) {
+			if (returned_bytes) {
+				/* If we have already returned at least one
+				 * packets worth of data, we'll add this next
+				 * packet to the head of the receive queue so
+				 * it will be picked up next time. */
+				spin_lock_irqsave(&cpvt->lock, flags);
+				list_add(&cmd->node, &cpvt->rx_queue);
+				dahdi_tc_set_data_waiting(dtc);
+				spin_unlock_irqrestore(&cpvt->lock, flags);
+				return returned_bytes;
 			}
+
+			if (printk_ratelimit()) {
+				DTE_PRINTK(ERR,
+				  "Cannot copy %zd bytes into %zd byte user " \
+				  "buffer.\n", payload_bytes, count);
+			}
+			free_cmd(cmd);
+			return -EFBIG;
 		}
-	}
-
-	BUG_ON(!cmd);
-	packet = cmd->data;
-
-	payload_bytes = be16_to_cpu(packet->udphdr.len) -
-		sizeof(struct rtphdr) - sizeof(struct udphdr);
-
-	if (count < payload_bytes) {
-		if (printk_ratelimit()) {
-			DTE_PRINTK(ERR,
-			  "Cannot copy %zd bytes into %zd byte user " \
-			  "buffer.\n", payload_bytes, count);
+
+		atomic_inc(&cpvt->stats.packets_received);
+
+		ret = copy_to_user(&frame[returned_bytes],
+				   &packet->payload[0], payload_bytes);
+		if (unlikely(ret)) {
+			DTE_PRINTK(ERR, "Failed to copy data in %s\n", __func__);
+			free_cmd(cmd);
+			return -EFAULT;
 		}
+
+		returned_bytes += payload_bytes;
+
 		free_cmd(cmd);
-		return -EFBIG;
-	}
-
-	atomic_inc(&cpvt->stats.packets_received);
-
-	if (unlikely(copy_to_user(frame, &packet->payload[0], payload_bytes))) {
-		DTE_PRINTK(ERR, "Failed to copy data in %s\n", __func__);
-		free_cmd(cmd);
-		return -EFAULT;
-	}
-
-	free_cmd(cmd);
-
-	return payload_bytes;
+
+	} while ((cmd = get_ready_cmd(dtc)));
+
+	return returned_bytes;
 }
 
 /* Called with a frame in the srcfmt to be transcoded into the dstfmt. */




More information about the svn-commits mailing list