[svn-commits] sruffell: branch linux/sruffell/dahdi-linux-cmdqueue r6031 - in /linux/team/s...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Feb 23 09:25:25 CST 2009


Author: sruffell
Date: Mon Feb 23 09:25:24 2009
New Revision: 6031

URL: http://svn.digium.com/svn-view/dahdi?view=rev&rev=6031
Log:
Saving some work in progress.

The command queue for reading from the registers on the framer is stored in a
linked_list instead of an array.  Allows for the locks to protect this structure
to be held for shorter periods of time and reduces the need to cycle through all
the elements in the array to decide if there is a command in the queue to
process.

Modified:
    linux/team/sruffell/dahdi-linux-cmdqueue/   (props changed)
    linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/base.c
    linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/wcte12xp.h

Propchange: linux/team/sruffell/dahdi-linux-cmdqueue/
------------------------------------------------------------------------------
    automerge = yes

Propchange: linux/team/sruffell/dahdi-linux-cmdqueue/
------------------------------------------------------------------------------
    svnmerge-integrated = /linux/trunk:1-6029

Modified: linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/base.c
URL: http://svn.digium.com/svn-view/dahdi/linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/base.c?view=diff&rev=6031&r1=6030&r2=6031
==============================================================================
--- linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/base.c (original)
+++ linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/base.c Mon Feb 23 09:25:24 2009
@@ -35,6 +35,8 @@
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
 #include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
 
 #include <dahdi/kernel.h>
 
@@ -47,6 +49,8 @@
 #include "vpmadt032.h"
 #include "GpakApi.h"
 #endif
+
+#define HERE() do { if (1) /* printk_ratelimit()) */ printk(KERN_INFO "HERE: %s:%d\n", __FILE__, __LINE__); } while(0)
 
 struct pci_driver te12xp_driver;
 
@@ -120,21 +124,61 @@
 	return(0);
 }
 
-static inline int empty_slot(struct t1 *wc)
-{
-	unsigned int x;
-
-	for (x = 0; x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
-		if (!wc->cmdq.cmds[x].flags && !wc->cmdq.cmds[x].address)
-			return x;
-	}
-	return -1;
-}
-
+static inline struct command * get_free_cmd(struct t1 *wc)
+{
+	struct command *cmd = NULL;
+	unsigned long flags;
+	spin_lock_irqsave(&wc->cmd_list_lock, flags);
+	if (!list_empty(&wc->free_cmds)) {
+		cmd = list_entry(wc->free_cmds.next, struct command, node);
+		list_del_init(&cmd->node);
+		memset(cmd, 0, sizeof(*cmd));
+	}
+	spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
+	return cmd;
+}
+
+static inline void free_cmd(struct t1 *wc, struct command *cmd)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&wc->cmd_list_lock, flags);
+	list_move(&cmd->node, &wc->free_cmds);
+	spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
+}
+
+static inline struct command * get_pending_cmd(struct t1 *wc)
+{
+	struct command *cmd = NULL;
+	unsigned long flags;
+	spin_lock_irqsave(&wc->cmd_list_lock, flags);
+	if (!list_empty(&wc->pending_cmds)) {
+		cmd = list_entry(wc->pending_cmds.next, struct command, node);
+		list_move_tail(&cmd->node, &wc->active_cmds);
+	}
+	spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
+	return cmd;
+}
+
+static inline void submit_cmd(struct t1 *wc, struct command *cmd)
+{
+	unsigned long flags;
+	if (cmd->flags & (__CMD_RD | __CMD_PINS)) 
+		init_completion(&cmd->complete);
+	spin_lock_irqsave(&wc->cmd_list_lock, flags);
+	list_add_tail(&cmd->node, &wc->pending_cmds);
+	spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
+}
+
+static inline void resend_cmds(struct t1 *wc)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&wc->cmd_list_lock, flags);
+	list_splice_init(&wc->active_cmds, &wc->pending_cmds);
+	spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
+}
 static inline void cmd_dequeue(struct t1 *wc, volatile unsigned char *writechunk, int eframe, int slot)
 {
 	struct command *curcmd=NULL;
-	unsigned int x;
 
 	/* Skip audio */
 	writechunk += 66;
@@ -143,15 +187,7 @@
 		/* only 6 useable cs slots per */
 
 		/* framer */
-		for (x = 0; x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
-			if ((wc->cmdq.cmds[x].flags & (__CMD_RD | __CMD_WR | __CMD_LEDS | __CMD_PINS)) && 
-			    !(wc->cmdq.cmds[x].flags & (__CMD_TX | __CMD_FIN))) {
-			   	curcmd = &wc->cmdq.cmds[x];
-				wc->cmdq.cmds[x].flags |= __CMD_TX;
-				wc->cmdq.cmds[x].ident = wc->txident;
-				break;
-			}
-		}
+		curcmd = get_pending_cmd(wc);
 		if (!curcmd) {
 			curcmd = &wc->dummy;
 			/* If nothing else, use filler */
@@ -160,6 +196,7 @@
 			curcmd->flags = __CMD_RD;
 		}
 		curcmd->cs_slot = slot; 
+		curcmd->ident = wc->txident;
 		if (curcmd->flags & __CMD_WR)
 			writechunk[CMD_BYTE(slot,0,0)] = 0x0c; /* 0c write command */
 		else if (curcmd->flags & __CMD_LEDS)
@@ -176,69 +213,64 @@
 
 static inline void cmd_decipher(struct t1 *wc, volatile unsigned char *readchunk)
 {
-	unsigned char ident, cs_slot;
-	unsigned int x;
-	unsigned int is_vpm = 0;
+	struct command *cmd = NULL;
+	unsigned long flags;
+	const int IS_VPM = 0;
 
 	/* Skip audio */
 	readchunk += 66;
-	/* Search for any pending results */
-	for (x = 0; x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
-		if ((wc->cmdq.cmds[x].flags & (__CMD_RD | __CMD_WR | __CMD_LEDS | __CMD_PINS)) && 
-		    (wc->cmdq.cmds[x].flags & (__CMD_TX)) && 
-		    !(wc->cmdq.cmds[x].flags & (__CMD_FIN))) {
-		   	ident = wc->cmdq.cmds[x].ident;
-		   	cs_slot = wc->cmdq.cmds[x].cs_slot;
-
-		   	if (ident == wc->rxident) {
-				/* Store result */
-				wc->cmdq.cmds[x].data |= readchunk[CMD_BYTE(cs_slot,2,is_vpm)];
-				/*printk(KERN_INFO "answer in rxident=%d cs_slot=%d is %d CMD_BYTE=%d jiffies=%d\n", ident, cs_slot, last_read_command, CMD_BYTE(cs_slot, 2), jiffies); */
-				wc->cmdq.cmds[x].flags |= __CMD_FIN;
-				if (wc->cmdq.cmds[x].flags & (__CMD_WR | __CMD_LEDS))
-					/* clear out writes (and leds) since they need no ack */
-					memset(&wc->cmdq.cmds[x], 0, sizeof(wc->cmdq.cmds[x]));
+	spin_lock_irqsave(&wc->cmd_list_lock, flags);
+	while (!list_empty(&wc->active_cmds)) {
+		cmd = list_entry(wc->active_cmds.next, struct command, node);
+		if (cmd->ident != wc->rxident)
+			break;
+
+		if (cmd->flags & (__CMD_WR | __CMD_LEDS)) {
+			/* Nobody is waiting on writes...so let's just
+			 * free them here. */
+			list_move(&cmd->node, &wc->free_cmds);
+		} else if (cmd->flags & __CMD_ISR) {
+			/* If it was an isr read, someone will still want to get
+			 * the result. */
+			list_move(&cmd->node, &wc->complete_isr_read_cmds);
+		} else {
+			cmd->data |= readchunk[CMD_BYTE(cmd->cs_slot, 2, IS_VPM)];
+			list_del_init(&cmd->node);
+			complete(&cmd->complete);
+		}
+	}
+	spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
+}
+
+static inline int t1_setreg_full(struct t1 *wc, int addr, int val, int vpm_num)
+{
+	const int inatomic = in_atomic() ? 1 : 0;
+	struct command *cmd;
+	do {
+		cmd = get_free_cmd(wc);
+		if (cmd) {
+			cmd->address = addr;
+			cmd->data = val;
+			cmd->flags |= __CMD_WR;
+			if (vpm_num >= 0) {
+				cmd->flags |= __CMD_VPM;
+				cmd->vpm_num = vpm_num;
 			}
-		}
-	}
-}
-
-static inline int t1_setreg_full(struct t1 *wc, int addr, int val, const int inisr, int vpm_num)
-{
-	unsigned long flags = 0;
-	int hit;
-	int ret;
-
-
-	do {
-		if (!inisr)
-			spin_lock_irqsave(&wc->reglock, flags);
-		hit = empty_slot(wc);
-		if (hit > -1) {
-			wc->cmdq.cmds[hit].address = addr;
-			wc->cmdq.cmds[hit].data = val;
-			wc->cmdq.cmds[hit].flags |= __CMD_WR;
-			if(vpm_num >= 0) {
-				wc->cmdq.cmds[hit].flags |= __CMD_VPM;
-				wc->cmdq.cmds[hit].vpm_num = vpm_num;
-			}
-		}
-		if (inisr)
-			break;
+			submit_cmd(wc, cmd);
+			return 0;
+		}
+		if (!inatomic) 
+			msleep(1);
 		else
-			spin_unlock_irqrestore(&wc->reglock, flags);
-		if (hit < 0) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit < 0);
-
-	return (hit > -1) ? 0 : -1;
+			return -1;
+	} while (1);
+	/* should never get here. */
+	return -1;
 }
 
 static inline int t1_setreg(struct t1 *wc, int addr, int val)
 {
-	return t1_setreg_full(wc, addr, val, 0, NOT_VPM);
+	return t1_setreg_full(wc, addr, val, NOT_VPM);
 }
 
 /***************************************************************************
@@ -248,18 +280,13 @@
  **************************************************************************/
 static inline void clean_leftovers(struct t1 *wc)
 {
-	unsigned int x;
-	int count = 0;
-	
-	/* find our requested command */
-	for (x = 0; x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
-		if ((wc->cmdq.cmds[x].flags & __CMD_RD) &&
-		    (wc->cmdq.cmds[x].flags & __CMD_ISR) &&
-		    !(wc->cmdq.cmds[x].flags & __CMD_FIN)) {
-			debug_printk(1,"leftover isr read! %d", count);
-			memset(&wc->cmdq.cmds[x], 0, sizeof(wc->cmdq.cmds[x]));
-		}
-	}
+	unsigned long flags;
+	spin_lock_irqsave(&wc->cmd_list_lock, flags);
+	if (!list_empty(&wc->complete_isr_read_cmds)) {
+		debug_printk(1,"leftover isr reads!");
+		list_splice_init(&wc->complete_isr_read_cmds, &wc->free_cmds);
+	}
+	spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
 }
 
 /********************************************************************
@@ -268,162 +295,101 @@
  * Called in interrupt context to retrieve a value already requested
  * by the normal t1_getreg().
  *******************************************************************/
-static inline int t1_getreg_isr(struct t1 *wc, int addr)
-{
-	int hit=-1;
-	int ret;
-	unsigned int x;
-	
-	/* find our requested command */
-	for (x = 0;x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
-		if ((wc->cmdq.cmds[x].flags & __CMD_RD) &&
-		    (wc->cmdq.cmds[x].address==addr)) 
-		{
-			if (wc->cmdq.cmds[x].flags & __CMD_FIN) {
-				hit = x;
-				break;
-			}
-			else {
-				/* still in progress. */
-				return -1;
-			}
-		}
-	}
-
-	if (hit < 0) {
-		debug_printk(2, "t1_getreg_isr() no addr=%02x\n", addr);
-		return -1; /* oops, couldn't find it */
-	}
-
-	ret = wc->cmdq.cmds[hit].data;
-	memset(&wc->cmdq.cmds[hit], 0, sizeof(struct command));
-
+static inline int t1_getreg_isr(struct t1 *wc, const int addr)
+{
+	unsigned long flags;
+	int ret = -1;
+	struct command *cur, *temp;
+	spin_lock_irqsave(&wc->cmd_list_lock, flags);
+	list_for_each_entry_safe(cur, temp, &wc->complete_isr_read_cmds, node) {
+		if (addr == cur->address) {
+			ret = cur->data;
+			list_move(&cur->node, &wc->free_cmds);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
 	return ret;
 }
 
-static inline int t1_getreg_full(struct t1 *wc, int addr, const int inisr, int vpm_num)
-{
-	unsigned long flags = 0;
-	int hit;
+static inline int t1_getreg_full(struct t1 *wc, int addr, int vpm_num)
+{
+	struct command *cmd =  NULL;
 	int ret = 0;
-
-	do {
-		if (!inisr) {
-			spin_lock_irqsave(&wc->reglock, flags);
-		}
-		hit = empty_slot(wc);
-		if (hit > -1) {
-			wc->cmdq.cmds[hit].address = addr;
-			wc->cmdq.cmds[hit].data = 0x00;
-			wc->cmdq.cmds[hit].flags |= __CMD_RD;
-			if(vpm_num >= 0) {
-				wc->cmdq.cmds[hit].flags |= __CMD_VPM;
-				wc->cmdq.cmds[hit].vpm_num = vpm_num;
-			}
-			if (inisr)
-				wc->cmdq.cmds[hit].flags |= __CMD_ISR;
-		}
-		if (inisr) /* must be requested in t1_getreg_isr() */
-			return (hit > -1) ? 0 : -1;
-		else {
-			spin_unlock_irqrestore(&wc->reglock, flags);
-		}
-		if (hit < 0) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit < 0);
-
-	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		if (wc->cmdq.cmds[hit].flags & __CMD_FIN) {
-			ret = wc->cmdq.cmds[hit].data;
-			memset(&wc->cmdq.cmds[hit], 0, sizeof(wc->cmdq.cmds[hit]));
-			hit = -1;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
-		if (hit > -1) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit > -1);
-
+	int inisr = in_atomic() ? 1 : 0;
+retry:
+	cmd = get_free_cmd(wc);
+	if (cmd) {
+		cmd->address = addr;
+		cmd->data = 0x00;
+		cmd->flags = __CMD_RD;
+		if (inisr) {
+			cmd->flags |= __CMD_ISR;
+		}
+		if (vpm_num > -1) {
+			cmd->flags |= __CMD_VPM;
+			cmd->vpm_num = vpm_num;
+		}
+		submit_cmd(wc, cmd);
+	} else if (!inisr) {
+		msleep(500);
+		goto retry;
+	} else {
+		/* We're in atomic context...we need to just exit. */
+		return -1;
+	}
+
+	if (inisr)
+		return 0;
+
+	wait_for_completion(&cmd->complete);
+	ret = cmd->data;
+	free_cmd(wc, cmd);
 	return ret;
 }
 
 static inline int t1_getreg(struct t1 *wc, int addr, int inisr)
 {
-	return t1_getreg_full(wc, addr, inisr, NOT_VPM);
+	inisr = 0; /* TODO: Remove this */
+	return t1_getreg_full(wc, addr, NOT_VPM);
 }
 
 static inline int t1_setleds(struct t1 *wc, int leds, const int inisr)
 {
-	unsigned long flags = 0;
-	int hit;
+	struct command *cmd;
+
+	leds = ~leds & 0x0E; /* invert the LED bits (3 downto 1)*/
+retry:
+	cmd = get_free_cmd(wc);
+	if (cmd) {
+		cmd->flags |= __CMD_LEDS;
+		cmd->address = leds;
+		submit_cmd(wc, cmd);
+		return 0;
+	} else if (inisr) {
+		return -1;
+	} else {
+		msleep(1);
+		goto retry;
+	}
+	/* should not get here. */
+}
+
+static inline int t1_getpins(struct t1 *wc, int inisr)
+{
 	int ret = 0;
-
-	leds = ~leds & 0x0E; /* invert the LED bits (3 downto 1)*/
-
-	do {
-		if (!inisr) {
-			spin_lock_irqsave(&wc->reglock, flags);
-		}
-		hit = empty_slot(wc);
-		if (hit > -1) {
-			wc->cmdq.cmds[hit].flags |= __CMD_LEDS;
-			wc->cmdq.cmds[hit].address = leds;
-		}
-		if (inisr) {
-			break;
-		} else {
-			spin_unlock_irqrestore(&wc->reglock, flags);
-		}
-		if (hit < 0) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit < 0);
-
-	return (hit > -1) ? 0 : -1;
-}
-
-static inline int t1_getpins(struct t1 *wc, int inisr)
-{
-	unsigned long flags;
-	int hit;
-	int ret = 0;
-
-	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		hit = empty_slot(wc);
-		if (hit > -1) {
-			wc->cmdq.cmds[hit].address = 0x00;
-			wc->cmdq.cmds[hit].data = 0x00;
-			wc->cmdq.cmds[hit].flags |= __CMD_PINS;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
-		if (inisr)
-			return (hit > -1) ? 0 : -1;
-		if (hit < 0) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit < 0);
-
-	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		if (wc->cmdq.cmds[hit].flags & __CMD_FIN) {
-			ret = wc->cmdq.cmds[hit].data;
-			memset(&wc->cmdq.cmds[hit], 0, sizeof(wc->cmdq.cmds[hit]));
-			hit = -1;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
-		if (hit > -1) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit > -1);
-
+	struct command *cmd; 
+
+	cmd = get_free_cmd(wc);
+	BUG_ON(!cmd);
+
+	cmd->address = 0x00;
+	cmd->data = 0x00;
+	cmd->flags = __CMD_PINS;
+	submit_cmd(wc, cmd);
+	wait_for_completion(&cmd->complete);
+	ret = cmd->data;
+	free_cmd(wc, cmd);
 	return ret;
 }
 
@@ -440,7 +406,7 @@
 		if (((i % 8)==7) &&  /* write byte every 8 channels */
 		    ((channo < 0) ||    /* channo=-1 means all channels */ 
 		     (j == (channo-1)/8) )) { /* only the register for this channo */    
-			ret = t1_setreg_full(wc, 0x2f + j, val, 1, NOT_VPM);
+			ret = t1_setreg_full(wc, 0x2f + j, val, NOT_VPM);
 			if (ret < 0)
 				module_printk("set_clear failed for chan %d!\n",i); 
 			val = 0;
@@ -766,7 +732,7 @@
 		wc->txsigs[b] = c;
 		spin_unlock_irqrestore(&wc->reglock, flags);
 		  /* output them to the chip */
-		t1_setreg_full(wc,0x71 + b,c,1,NOT_VPM); 
+		t1_setreg_full(wc,0x71 + b,c,NOT_VPM); 
 	} else if (wc->span.lineconfig & DAHDI_CONFIG_D4) {
 		n = chan->chanpos - 1;
 		b = (n / 4);
@@ -778,8 +744,8 @@
 		wc->txsigs[b] = c;
 		spin_unlock_irqrestore(&wc->reglock, flags);
 		/* output them to the chip */
-		t1_setreg_full(wc,0x70 + b,c,1,NOT_VPM); 
-		t1_setreg_full(wc,0x70 + b + 6,c,1,NOT_VPM); 
+		t1_setreg_full(wc,0x70 + b,c,NOT_VPM); 
+		t1_setreg_full(wc,0x70 + b + 6,c,NOT_VPM); 
 	} else if (wc->span.lineconfig & DAHDI_CONFIG_ESF) {
 		n = chan->chanpos - 1;
 		b = (n / 2);
@@ -791,7 +757,7 @@
 		wc->txsigs[b] = c;
 		spin_unlock_irqrestore(&wc->reglock, flags);
 		  /* output them to the chip */
-		t1_setreg_full(wc,0x70 + b,c,1,NOT_VPM); 
+		t1_setreg_full(wc,0x70 + b,c,NOT_VPM); 
 	} 
 	debug_printk(2,"Finished setting RBS bits\n");
 
@@ -1175,12 +1141,12 @@
 #ifdef VPM_SUPPORT
 static inline unsigned char t1_vpm_in(struct t1 *wc, int unit, const unsigned int addr) 
 {
-		return t1_getreg_full(wc, addr, 0, unit);
+		return t1_getreg_full(wc, addr, unit);
 }
 
 static inline unsigned char t1_vpm_out(struct t1 *wc, int unit, const unsigned int addr, const unsigned char val) 
 {
-		return t1_setreg_full(wc, addr, val, 0, unit);
+		return t1_setreg_full(wc, addr, val, unit);
 }
 
 #endif
@@ -1282,16 +1248,16 @@
 			   we haven't found a multiframe since last loss
 			   of frame */
 			if (!wc->flags.nmf) {
-				t1_setreg_full(wc, 0x20, 0x9f | 0x20, 1, NOT_VPM);	/* LIM0: Force RAI High */
+				t1_setreg_full(wc, 0x20, 0x9f | 0x20, NOT_VPM);	/* LIM0: Force RAI High */
 				wc->flags.nmf = 1;
 				module_printk("NMF workaround on!\n");
 			}
-			t1_setreg_full(wc, 0x1e, 0xc3, 1, NOT_VPM);	/* Reset to CRC4 mode */
-			t1_setreg_full(wc, 0x1c, 0xf2, 1, NOT_VPM);	/* Force Resync */
-			t1_setreg_full(wc, 0x1c, 0xf0, 1, NOT_VPM);	/* Force Resync */
+			t1_setreg_full(wc, 0x1e, 0xc3, NOT_VPM);	/* Reset to CRC4 mode */
+			t1_setreg_full(wc, 0x1c, 0xf2, NOT_VPM);	/* Force Resync */
+			t1_setreg_full(wc, 0x1c, 0xf0, NOT_VPM);	/* Force Resync */
 		} else if (!(c & 0x02)) {
 			if (wc->flags.nmf) {
-				t1_setreg_full(wc, 0x20, 0x9f, 1, NOT_VPM);	/* LIM0: Clear forced RAI */
+				t1_setreg_full(wc, 0x20, 0x9f, NOT_VPM);	/* LIM0: Clear forced RAI */
 				wc->flags.nmf = 0;
 				module_printk("NMF workaround off!\n");
 			}
@@ -1301,8 +1267,8 @@
 		if ((!wc->span.mainttimer) && (d & 0x08)) {
 			/* Loop-up code detected */
 			if ((wc->loopupcnt++ > 80)  && (wc->span.maintstat != DAHDI_MAINT_REMOTELOOP)) {
-				t1_setreg_full(wc, 0x36, 0x08, 1, NOT_VPM);	/* LIM0: Disable any local loop */
-				t1_setreg_full(wc, 0x37, 0xf6, 1, NOT_VPM);	/* LIM1: Enable remote loop */
+				t1_setreg_full(wc, 0x36, 0x08, NOT_VPM);	/* LIM0: Disable any local loop */
+				t1_setreg_full(wc, 0x37, 0xf6, NOT_VPM);	/* LIM1: Enable remote loop */
 				wc->span.maintstat = DAHDI_MAINT_REMOTELOOP;
 			}
 		} else
@@ -1311,8 +1277,8 @@
 		if ((!wc->span.mainttimer) && (d & 0x10)) {
 			/* Loop-down code detected */
 			if ((wc->loopdowncnt++ > 80)  && (wc->span.maintstat == DAHDI_MAINT_REMOTELOOP)) {
-				t1_setreg_full(wc, 0x36, 0x08, 1, NOT_VPM);	/* LIM0: Disable any local loop */
-				t1_setreg_full(wc, 0x37, 0xf0, 1, NOT_VPM);	/* LIM1: Disable remote loop */
+				t1_setreg_full(wc, 0x36, 0x08, NOT_VPM);	/* LIM0: Disable any local loop */
+				t1_setreg_full(wc, 0x37, 0xf0, NOT_VPM);	/* LIM1: Disable remote loop */
 				wc->span.maintstat = DAHDI_MAINT_NONE;
 			}
 		} else
@@ -1350,12 +1316,12 @@
 		module_printk("Setting yellow alarm\n");
 
 		/* We manually do yellow alarm to handle RECOVER and NOTOPEN, otherwise it's auto anyway */
-		t1_setreg_full(wc, 0x20, fmr4 | 0x20, 1, NOT_VPM);
+		t1_setreg_full(wc, 0x20, fmr4 | 0x20, NOT_VPM);
 		wc->flags.sendingyellow = 1;
 	} else if (!alarms && wc->flags.sendingyellow) {
 		module_printk("Clearing yellow alarm\n");
 		/* We manually do yellow alarm to handle RECOVER  */
-		t1_setreg_full(wc, 0x20, fmr4 & ~0x20, 1, NOT_VPM);
+		t1_setreg_full(wc, 0x20, fmr4 & ~0x20, NOT_VPM);
 		wc->flags.sendingyellow = 0;
 	}
 	
@@ -1484,18 +1450,6 @@
 	}
 }
 
-static inline void cmd_retransmit(struct t1 *wc)
-{
-	unsigned int x;
-
-	for (x = 0; x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
-		if (!(wc->cmdq.cmds[x].flags &  __CMD_FIN)) {
-			wc->cmdq.cmds[x].flags &= ~(__CMD_TX) ; /* clear __CMD_TX */
-			wc->cmdq.cmds[x].ident = 0;
-		}
-	}
-}
-
 static inline void t1_receiveprep(struct t1 *wc, unsigned char* readchunk)
 {
 	int x,chan;
@@ -1513,7 +1467,7 @@
 			wc->statreg = readchunk[EFRAME_SIZE + 2];
 			if (wc->rxident != expected) {
 				wc->span.irqmisses++;
-				cmd_retransmit(wc);
+				resend_cmds(wc);
 				if (unlikely(debug && wc->initialized))
 					module_printk("oops: rxident=%d expected=%d x=%d\n", wc->rxident, expected, x);
 			}
@@ -1603,6 +1557,15 @@
 	ifaces[index] = wc;
 	memset(wc, 0, sizeof(*wc));
 	spin_lock_init(&wc->reglock);
+	spin_lock_init(&wc->cmd_list_lock);
+	INIT_LIST_HEAD(&wc->active_cmds);
+	INIT_LIST_HEAD(&wc->pending_cmds);
+	INIT_LIST_HEAD(&wc->free_cmds);
+	INIT_LIST_HEAD(&wc->complete_isr_read_cmds);
+	for (x = 0; x < MAX_COMMANDS; ++x) {
+		INIT_LIST_HEAD(&wc->cmds[x].node);
+		free_cmd(wc, &wc->cmds[x]);
+	}
 	wc->variety = d->name;
 	wc->txident = 1;
 

Modified: linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/wcte12xp.h
URL: http://svn.digium.com/svn-view/dahdi/linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/wcte12xp.h?view=diff&rev=6031&r1=6030&r2=6031
==============================================================================
--- linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/wcte12xp.h (original)
+++ linux/team/sruffell/dahdi-linux-cmdqueue/drivers/dahdi/wcte12xp/wcte12xp.h Mon Feb 23 09:25:24 2009
@@ -61,8 +61,10 @@
 #define __CMD_LEDS (1 << 19)		/* LED Operation */
 #define __CMD_RD   (1 << 20)		/* Read Operation */
 #define __CMD_WR   (1 << 21)		/* Write Operation */
+#if 0
 #define __CMD_FIN  (1 << 22)		/* Has finished receive */
 #define __CMD_TX   (1 << 23)		/* Has been transmitted */
+#endif
 
 #define __LED_ORANGE	(1<<3)
 #define __LED_GREEN	(1<<2)
@@ -98,11 +100,15 @@
 	unsigned int flags;
 	unsigned char cs_slot;
 	unsigned char vpm_num; /* ignored for all but vpm commmands */
+	struct list_head node;
+	struct completion complete;
 };
 
+/* TODO
 struct cmdq {
 	struct command cmds[MAX_COMMANDS];
 };
+*/
 
 struct vpm150m;
 
@@ -141,7 +147,7 @@
 	struct dahdi_span span;						/* Span */
 	struct dahdi_chan *chans[32];					/* Channels */
 	wait_queue_head_t regq;
-	struct cmdq	cmdq;
+	/* struct cmdq	cmdq; */
 	struct command dummy;	/* preallocate for dummy noop command */
 	unsigned char ctlreg;
 	unsigned int rxints;
@@ -156,7 +162,17 @@
 	unsigned long dtmfmask;
 	unsigned long dtmfmutemask;
 #endif
+	/* Preallocted memory for the commands. */
+	struct command cmds[MAX_COMMANDS];
+	
+	/* The lists we're interested in. */
+	spinlock_t cmd_list_lock;
+	struct list_head pending_cmds;
+	struct list_head active_cmds;
+	struct list_head free_cmds;
+	struct list_head complete_isr_read_cmds;
 };
+
 
 int schluffen(wait_queue_head_t *q);
 




More information about the svn-commits mailing list