[svn-commits] sruffell: linux/trunk r4589 - in /linux/trunk: drivers/dahdi/ include/dahdi/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jul 9 16:27:08 CDT 2008


Author: sruffell
Date: Wed Jul  9 16:27:07 2008
New Revision: 4589

URL: http://svn.digium.com/view/dahdi?view=rev&rev=4589
Log:
Saving off some work in progress on half-full buffering.  Still needs a method
for dumping half the buffer on tx overrun from the user side.

Also, the behavior of half-full on the rx side has not been checked.

Modified:
    linux/trunk/drivers/dahdi/dahdi-base.c
    linux/trunk/include/dahdi/kernel.h

Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svn.digium.com/view/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=4589&r1=4588&r2=4589
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Wed Jul  9 16:27:07 2008
@@ -850,15 +850,17 @@
 	ss->outreadbuf = -1;
 	ss->outwritebuf = -1;
 	ss->numbufs = numbufs;
-	if (ss->txbufpolicy == DAHDI_POLICY_WHEN_FULL)
+	if (DAHDI_POLICY_IMMEDIATE != ss->txbufpolicy) {
 		ss->txdisable = 1;
-	else
+	} else {
 		ss->txdisable = 0;
-
-	if (ss->rxbufpolicy == DAHDI_POLICY_WHEN_FULL)
+	}
+
+	if (DAHDI_POLICY_IMMEDIATE != ss->rxbufpolicy) {
 		ss->rxdisable = 1;
-	else
+	} else {
 		ss->rxdisable = 0;
+	}
 
 	spin_unlock_irqrestore(&ss->lock, flags);
 	if (oldbuf)
@@ -1448,8 +1450,8 @@
 		module_printk(KERN_NOTICE, "%s is not a net device!\n", ms->name);
 		return -EINVAL;
 	}
-	ms->txbufpolicy = DAHDI_POLICY_IMMEDIATE;
-	ms->rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
+	ms->txbufpolicy = DAHDI_POLICY_DEFAULT;
+	ms->rxbufpolicy = DAHDI_POLICY_DEFAULT;
 
 	res = dahdi_reallocbufs(ms, DAHDI_DEFAULT_MTU_MRU, DAHDI_DEFAULT_NUM_BUFS);
 	if (res) 
@@ -1894,8 +1896,9 @@
 	if (chan->outreadbuf == chan->inreadbuf) {
 		/* Out of stuff */
 		chan->outreadbuf = -1;
-		if (chan->rxbufpolicy == DAHDI_POLICY_WHEN_FULL)
+		if (DAHDI_POLICY_IMMEDIATE != chan->rxbufpolicy) {
 			chan->rxdisable = 1;
+		}
 	}
 	if (chan->inreadbuf < 0) {
 		/* Notify interrupt handler that we have some space now */
@@ -1904,6 +1907,35 @@
 	spin_unlock_irqrestore(&chan->lock, flags);
 	
 	return amnt;
+}
+
+static int __attribute__((const)) buffers_half_full(int hp, int tp, int length)
+{
+	if (hp < 0) {
+		/* We're full... */
+		return 1;
+	}
+	if (tp < 0) {
+		/* We're empty ... */
+		return 0;
+	}
+	if (hp > tp) {
+		return ((hp - tp) > length / 2) ? 1 : 0;
+	} else {
+		return (((length - tp) + hp) > length/2 ) ? 1 : 0;
+	}
+}
+
+static int tx_buffers_half_full(struct dahdi_chan *chan)
+{
+	return buffers_half_full(chan->inwritebuf, chan->outwritebuf, 
+	                         chan->numbufs);
+}
+
+static int rx_buffers_half_full(struct dahdi_chan *chan)
+{
+	return buffers_half_full(chan->inreadbuf, chan->outreadbuf, 
+	                         chan->numbufs);
 }
 
 static ssize_t dahdi_chan_write(struct file *file, const char *usrbuf, size_t count, int unit)
@@ -1934,7 +1966,14 @@
 		spin_unlock_irqrestore(&chan->lock, flags);
 		if (res >= 0) 
 			break;
-		if (file->f_flags & O_NONBLOCK)
+
+		if (DAHDI_POLICY_HALF_FULL == chan->txbufpolicy) {
+			if (chan->flags & DAHDI_FLAG_AUDIO) {
+				/* dahdi_flush_half_tx_buffers(chan); */
+				;
+			}
+		}
+		if (file->f_flags & O_NONBLOCK) 
 			return -EAGAIN;
 		/* Wait for something to be available */
 		rv = schluffen(&chan->writebufq);
@@ -2002,6 +2041,14 @@
 			chan->inwritebuf = -1;
 			/* Make sure the transmitter is transmitting in case of POLICY_WHEN_FULL */
 			chan->txdisable = 0;
+		} else if (chan->txdisable) {
+			/* We might need to enable the transmitter again if the
+			 * policy is set to half full. */
+			if (DAHDI_POLICY_HALF_FULL == chan->txbufpolicy) {
+				if (tx_buffers_half_full(chan)) {
+					chan->txdisable = 0;
+				}
+			}
 		}
 		if (chan->outwritebuf < 0) {
 			/* Okay, the interrupt handler has been waiting for us.  Give them a buffer */
@@ -2242,8 +2289,8 @@
 
 	spin_lock_irqsave(&chan->lock, flags);
 
-	chan->rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
-	chan->txbufpolicy = DAHDI_POLICY_IMMEDIATE;
+	chan->rxbufpolicy = DAHDI_POLICY_DEFAULT;
+	chan->txbufpolicy = DAHDI_POLICY_DEFAULT;
 
 	ec_state = chan->ec_state;
 	chan->ec_state = NULL;
@@ -4101,6 +4148,29 @@
 	return rv;
 }
 
+static void dahdi_flush_tx_buffers(struct dahdi_chan *chan)
+{
+	int j;
+	/* initialize write buffers and pointers */
+	chan->outwritebuf = -1;
+	chan->inwritebuf = 0;
+	for (j=0;j<chan->numbufs;j++) {
+		/* Do we need this? */
+		chan->writen[j] = 0;
+		chan->writeidx[j] = 0;
+	}
+	wake_up_interruptible(&chan->writebufq); /* wake_up_interruptible waiting on write */
+	wake_up_interruptible(&chan->sel);  /* wake_up_interruptible waiting on select */
+	   /* if IO MUX wait on write empty, well, this
+		certainly *did* empty the write */
+	if (chan->iomask & DAHDI_IOMUX_WRITEEMPTY)
+		wake_up_interruptible(&chan->eventbufq); /* wake_up_interruptible waiting on IOMUX */
+
+	if (DAHDI_POLICY_IMMEDIATE != chan->txbufpolicy) {
+		chan->txdisable = 1;
+	}
+}
+
 static int dahdi_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
 {
 	struct dahdi_chan *chan = chans[unit];
@@ -4145,8 +4215,11 @@
 			return -EINVAL;
 		if (stack.bi.bufsize * stack.bi.numbufs > DAHDI_MAX_BUF_SPACE)
 			return -EINVAL;
-		chan->rxbufpolicy = stack.bi.rxbufpolicy & 0x1;
-		chan->txbufpolicy = stack.bi.txbufpolicy & 0x1;
+		/* TODO: Change mask to inline function to validate the policy. */
+		chan->rxbufpolicy = stack.bi.rxbufpolicy & 0x3;
+		chan->txbufpolicy = stack.bi.txbufpolicy & 0x3;
+		/* !!!SRR!!! */
+		printk(KERN_DEBUG "txpolicy: %d rxpolicy: %d\n", chan->txbufpolicy, chan->rxbufpolicy);
 		if ((rv = dahdi_reallocbufs(chan,  stack.bi.bufsize, stack.bi.numbufs)))
 			return (rv);
 		break;
@@ -4179,24 +4252,14 @@
 			}
 			wake_up_interruptible(&chan->readbufq);  /* wake_up_interruptible waiting on read */
 			wake_up_interruptible(&chan->sel); /* wake_up_interruptible waiting on select */
+
+			if (DAHDI_POLICY_IMMEDIATE != chan->rxbufpolicy) {
+				chan->txdisable = 1;
+			}
 		   }
-		if (i & DAHDI_FLUSH_WRITE) /* if for write (output) */
-		   {
-			  /* initialize write buffers and pointers */
-			chan->outwritebuf = -1;
-			chan->inwritebuf = 0;
-			for (j=0;j<chan->numbufs;j++) {
-				/* Do we need this? */
-				chan->writen[j] = 0;
-				chan->writeidx[j] = 0;
-			}
-			wake_up_interruptible(&chan->writebufq); /* wake_up_interruptible waiting on write */
-			wake_up_interruptible(&chan->sel);  /* wake_up_interruptible waiting on select */
-			   /* if IO MUX wait on write empty, well, this
-				certainly *did* empty the write */
-			if (chan->iomask & DAHDI_IOMUX_WRITEEMPTY)
-				wake_up_interruptible(&chan->eventbufq); /* wake_up_interruptible waiting on IOMUX */
-		   }
+		if (i & DAHDI_FLUSH_WRITE) { /* if for write (output) */
+			dahdi_flush_tx_buffers(chan);
+		}
 		if (i & DAHDI_FLUSH_EVENT) /* if for events */
 		   {
 			   /* initialize the event pointers */
@@ -5753,18 +5816,20 @@
 						ms->outwritebuf = -1;
 						if (ms->iomask & (DAHDI_IOMUX_WRITE | DAHDI_IOMUX_WRITEEMPTY))
 							wake_up_interruptible(&ms->eventbufq);
-						/* If we're only supposed to start when full, disable the transmitter */
-						if (ms->txbufpolicy == DAHDI_POLICY_WHEN_FULL)
+						/* If we're only supposed to start when not empty, disable the transmitter */
+						if (DAHDI_POLICY_IMMEDIATE != ms->txbufpolicy) {
 							ms->txdisable = 1;
+						}
 					}
 				} else {
 					if (ms->outwritebuf == ms->inwritebuf) {
 						ms->outwritebuf = oldbuf;
 						if (ms->iomask & (DAHDI_IOMUX_WRITE | DAHDI_IOMUX_WRITEEMPTY))
 							wake_up_interruptible(&ms->eventbufq);
-						/* If we're only supposed to start when full, disable the transmitter */
-						if (ms->txbufpolicy == DAHDI_POLICY_WHEN_FULL)
+						/* If we're only supposed to start when not empty, disable the transmitter */
+						if (DAHDI_POLICY_IMMEDIATE != ms->txbufpolicy) {
 							ms->txdisable = 1;
+						}
 					}
 				}
 				if (ms->inwritebuf < 0) {
@@ -6827,7 +6892,14 @@
 							ms->inreadbuf = -1;
 							/* Enable the receiver in case they've got POLICY_WHEN_FULL */
 							ms->rxdisable = 0;
+						} else if (ms->rxdisable) {
+							if (DAHDI_POLICY_HALF_FULL == ms->rxbufpolicy) {
+								if (rx_buffers_half_full(ms)) {
+									ms->rxdisable = 0;
+								}
+							}
 						}
+
 						if (ms->outreadbuf < 0) { /* start out buffer if not already */
 							ms->outreadbuf = oldbuf;
 						}
@@ -7066,8 +7138,9 @@
 				if (ss->iomask & (DAHDI_IOMUX_WRITE | DAHDI_IOMUX_WRITEEMPTY))
 					wake_up_interruptible(&ss->eventbufq);
 				/* If we're only supposed to start when full, disable the transmitter */
-				if (ss->txbufpolicy == DAHDI_POLICY_WHEN_FULL)
+				if (DAHDI_POLICY_IMMEDIATE != ss->txbufpolicy) {
 					ss->txdisable = 1;
+				}
 				res = -1;
 			}
 

Modified: linux/trunk/include/dahdi/kernel.h
URL: http://svn.digium.com/view/dahdi/linux/trunk/include/dahdi/kernel.h?view=diff&rev=4589&r1=4588&r2=4589
==============================================================================
--- linux/trunk/include/dahdi/kernel.h (original)
+++ linux/trunk/include/dahdi/kernel.h Wed Jul  9 16:27:07 2008
@@ -157,8 +157,11 @@
 #define DAHDI_DEFAULT_BLOCKSIZE 1024
 #define DAHDI_DEFAULT_MTR_MRU	 2048
 
-#define DAHDI_POLICY_IMMEDIATE	 0		/* Start play/record immediately */
-#define DAHDI_POLICY_WHEN_FULL  1		/* Start play/record when buffer is full */
+#define DAHDI_POLICY_IMMEDIATE	0	/* Start play/record immediately */
+#define DAHDI_POLICY_WHEN_FULL	1	/* Start play/record when buffer is full */
+#define DAHDI_POLICY_HALF_FULL	2	/* ...and when buffer is half full. */
+
+#define DAHDI_POLICY_DEFAULT	DAHDI_POLICY_HALF_FULL
 
 #define	RING_DEBOUNCE_TIME	2000	/* 2000 ms ring debounce time */
 




More information about the svn-commits mailing list