[zaptel-commits] sruffell: branch 1.4 r3592 - in /branches: 1.2/wctdm24xxp/ 1.2/wcte12xp/ 1.4/...

SVN commits to the Zaptel project zaptel-commits at lists.digium.com
Wed Jan 2 14:30:58 CST 2008


Author: sruffell
Date: Wed Jan  2 14:30:58 2008
New Revision: 3592

URL: http://svn.digium.com/view/zaptel?view=rev&rev=3592
Log:
VPMADT032 stability changes for wctdm24xxp and wcte12xp:
- Remove double reads.
- Wait for writes to complete before starting reads.
- Optimize reads of multi-word register.

Modified:
    branches/1.2/wctdm24xxp/GpakCust.c
    branches/1.2/wctdm24xxp/base.c
    branches/1.2/wctdm24xxp/wctdm24xxp.h
    branches/1.2/wcte12xp/vpmadt032.c
    branches/1.4/wctdm24xxp/GpakCust.c
    branches/1.4/wctdm24xxp/base.c
    branches/1.4/wctdm24xxp/wctdm24xxp.h
    branches/1.4/wcte12xp/vpmadt032.c

Modified: branches/1.2/wctdm24xxp/GpakCust.c
URL: http://svn.digium.com/view/zaptel/branches/1.2/wctdm24xxp/GpakCust.c?view=diff&rev=3592&r1=3591&r2=3592
==============================================================================
--- branches/1.2/wctdm24xxp/GpakCust.c (original)
+++ branches/1.2/wctdm24xxp/GpakCust.c Wed Jan  2 14:30:58 2008
@@ -105,51 +105,97 @@
 	int x;
 
 	for (x = 0; x < VPM150M_MAX_COMMANDS; x++)
-		if (!wc->vpm150m->cmdq[x].desc)
+		if (!wc->vpm150m->cmdq[x].desc) {
 			return &wc->vpm150m->cmdq[x];
+		}
 	return NULL;
 }
 
-
-unsigned short wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
-{
+/* Wait for any outstanding commands to be completed. */
+static inline int vpm150m_io_wait(struct wctdm *wc)
+{
+	int x;
+	int ret=0;
+	for (x=0; x < VPM150M_MAX_COMMANDS;) {
+		if (wc->vpm150m->cmdq[x].desc) {
+			if ((ret=schluffen(&wc->regq))) {
+				return ret;
+			}
+			x=0;
+		}
+		else {
+			++x;
+		}
+	}
+	return ret;
+}
+
+int wctdm_vpm150m_getreg_full_async(struct wctdm *wc, int pagechange, unsigned int len, 
+	unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
+{
+	int ret=0;
 	unsigned long flags;
-	volatile struct vpm150m_cmd *hit;
-	unsigned short ret = 0;
-	int i;
+	BUG_ON(!hit_p);
+	spin_lock_irqsave(&wc->reglock, flags);
+	(*hit_p) = vpm150m_empty_slot(wc);
+	if (*hit_p) {
+		(*hit_p)->desc = __VPM150M_RD;
+		if (pagechange) {
+			(*hit_p)->desc |= __VPM150M_RWPAGE;
+		}
+		(*hit_p)->datalen = len;
+		(*hit_p)->addr = addr;
+		memset((*hit_p)->data, 0, len*sizeof(outbuf[0]));
+	}
+	else {
+		ret = -EBUSY;
+	}
+	spin_unlock_irqrestore(&wc->reglock, flags);
+	return ret;
+}
+
+int wctdm_vpm150m_getreg_full_return(struct wctdm *wc, int pagechange, unsigned int len,
+	unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
+{
+	int ret = 0;
+	unsigned long flags;
+	BUG_ON(!hit_p);
+	spin_lock_irqsave(&wc->reglock, flags);
 	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		hit = vpm150m_empty_slot(wc);
-		if (hit) {
-			hit->desc = __VPM150M_RD;
-			if (pagechange) {
-				hit->desc |= __VPM150M_RWPAGE;
-			}
-			hit->datalen = len;
-			hit->addr = addr;
-			for (i = 0; i < hit->datalen; i++)
-				hit->data[i] = 0x0000;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
+		if ((*hit_p)->desc & __VPM150M_FIN) {
+			memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0])));
+			(*hit_p)->desc = 0;
+			(*hit_p) = NULL;
+			ret = 0;
+		}
+		else {
+			spin_unlock_irqrestore(&wc->reglock, flags);
+			if ((ret=schluffen(&wc->regq))) {
+				return ret;
+			}
+			spin_lock_irqsave(&wc->reglock, flags);
+			ret = -EBUSY;
+		}
+	} while (-EBUSY == ret);
+	spin_unlock_irqrestore(&wc->reglock, flags);
+	return ret;
+}
+
+int wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
+{
+	struct vpm150m_cmd *hit = 0;
+	int ret = 0;
+	do {
+		ret = wctdm_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit);
 		if (!hit) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
+			if ( -EBUSY == ret ) {
+				if ((ret = schluffen(&wc->regq))) 
+					return ret;
+			}
+			BUG_ON(0 != ret);
 		}
 	} while (!hit);
-	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		if (hit->desc & __VPM150M_FIN) {
-			for (i = 0; i < hit->datalen; i++)
-				outbuf[i] = hit->data[i];
-			hit->desc = 0;
-			hit = NULL;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
-		if (hit) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit);
+	ret = wctdm_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit);
 	return ret;
 }
 
@@ -202,17 +248,10 @@
 unsigned short wctdm_vpm150m_getreg(struct wctdm *wc, unsigned int len, unsigned int addr, unsigned short *data)
 {
 	unsigned short res;
-	unsigned short count=0;
-	unsigned short first_data=0;
-	do {
-		wctdm_vpm150m_setpage(wc, addr >> 16);
-		if ((addr >> 16) != ((addr + len) >> 16))
-			printk("getreg: You found it!\n");
-		if (count > 0) {
-			first_data = *data;
-		}
-		res = wctdm_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
-	} while(((0==count++) || (first_data != *data)) && (count < 100));
+	wctdm_vpm150m_setpage(wc, addr >> 16);
+	if ((addr >> 16) != ((addr + len) >> 16))
+		printk("getreg: You found it!\n");
+	res = wctdm_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
  	return res;
 }
 
@@ -247,9 +286,29 @@
 	struct wctdm *wc = wc_find_iface(DspId);
 	int i;
 	int transcount;
-
-	//printk("Reading %d words from memory\n");
-	if (wc && wc->vpm150m) {
+	int ret;
+
+	vpm150m_io_wait(wc);
+	if ( NumWords < VPM150M_MAX_COMMANDS ) {
+		struct vpm150m_cmd* cmds[VPM150M_MAX_COMMANDS] = {0};
+		wctdm_vpm150m_setpage(wc, DspAddress >> 16);
+		DspAddress &= 0xffff;
+		for (i=0; i < NumWords; ++i) {
+			ret = wctdm_vpm150m_getreg_full_async(wc,0,1,DspAddress+i,&pWordValues[i],
+				&cmds[i]);
+			if (0 != ret) {
+				return ret;
+			}
+		}
+		for (i=NumWords-1; i >=0; --i) {
+			ret = wctdm_vpm150m_getreg_full_return(wc,0,1,DspAddress+i,&pWordValues[i],
+				&cmds[i]);
+			if (0 != ret) {
+				return ret;
+			}
+		}
+	}
+	else {
 		for (i = 0; i < NumWords;) {
 			if ((NumWords - i) > VPM150M_MAX_DATA)
 				transcount = VPM150M_MAX_DATA;
@@ -262,7 +321,6 @@
 	return;
 }
 
-
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  * gpakWriteDspMemory - Write DSP memory.
  *

Modified: branches/1.2/wctdm24xxp/base.c
URL: http://svn.digium.com/view/zaptel/branches/1.2/wctdm24xxp/base.c?view=diff&rev=3592&r1=3591&r2=3592
==============================================================================
--- branches/1.2/wctdm24xxp/base.c (original)
+++ branches/1.2/wctdm24xxp/base.c Wed Jan  2 14:30:58 2008
@@ -3087,8 +3087,6 @@
 		while (test_bit(VPM150M_HPIRESET, &vpm150m->control))
 			schluffen(&wc->regq);
 
-		msleep(1000);
-
 		printk("VPMADT032 Loading firwmare... ");
 		downloadstatus = gpakDownloadDsp(vpm150m->dspid, &fw);
 
@@ -3107,7 +3105,6 @@
 		while (test_bit(VPM150M_SWRESET, &vpm150m->control))
 			schluffen(&wc->regq);
 
-		msleep(1000);
 #if 0
 	}
 #endif

Modified: branches/1.2/wctdm24xxp/wctdm24xxp.h
URL: http://svn.digium.com/view/zaptel/branches/1.2/wctdm24xxp/wctdm24xxp.h?view=diff&rev=3592&r1=3591&r2=3592
==============================================================================
--- branches/1.2/wctdm24xxp/wctdm24xxp.h (original)
+++ branches/1.2/wctdm24xxp/wctdm24xxp.h Wed Jan  2 14:30:58 2008
@@ -147,7 +147,7 @@
 	unsigned long desiredecstate;
 	unsigned long curdtmfmutestate;
 	unsigned long desireddtmfmutestate;
-	struct vpm150m_cmd cmdq[MAX_COMMANDS];
+	struct vpm150m_cmd cmdq[VPM150M_MAX_COMMANDS];
 	unsigned char curtone[24];
 };
 

Modified: branches/1.2/wcte12xp/vpmadt032.c
URL: http://svn.digium.com/view/zaptel/branches/1.2/wcte12xp/vpmadt032.c?view=diff&rev=3592&r1=3591&r2=3592
==============================================================================
--- branches/1.2/wcte12xp/vpmadt032.c (original)
+++ branches/1.2/wcte12xp/vpmadt032.c Wed Jan  2 14:30:58 2008
@@ -289,7 +289,7 @@
 {
 	unsigned int x;
 
-	for (x = 0; x < sizeof(wc->vpm150m->cmdq) / sizeof(wc->vpm150m->cmdq[0]); x++) {
+	for (x = 0; x < VPM150M_MAX_COMMANDS; x++) {
 		if (!wc->vpm150m->cmdq[x].flags) {
 			return &wc->vpm150m->cmdq[x];
 		}
@@ -297,50 +297,92 @@
 	return NULL;
 }
 
-unsigned short t1_vpm150m_getreg_full(struct t1 *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
-{
+/* Wait for any outstanding commands to be completed. */
+static inline int vpm150m_io_wait(struct t1 *wc)
+{
+	int x;
+	int ret=0;
+	for (x=0; x < VPM150M_MAX_COMMANDS;) {
+		if (wc->vpm150m->cmdq[x].flags) {
+			if ((ret=schluffen(&wc->regq))) {
+				return ret;
+			}
+			x=0;
+		}
+		else {
+			++x;
+		}
+	}
+	return ret;
+}
+
+int t1_vpm150m_getreg_full_async(struct t1 *wc, int pagechange, unsigned int len, 
+	unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
+{
+	int ret=0;
 	unsigned long flags;
-	volatile struct vpm150m_cmd *hit;
-	unsigned short ret = 0;
-	int i;
-
+	BUG_ON(!hit_p);
+	spin_lock_irqsave(&wc->reglock, flags);
+	(*hit_p) = vpm150m_empty_slot(wc);
+	if (*hit_p) {
+		(*hit_p)->flags = __VPM150M_RD;
+		if (pagechange) {
+			(*hit_p)->flags |= __VPM150M_RWPAGE;
+		}
+		(*hit_p)->datalen = len;
+		(*hit_p)->address = addr;
+		memset((*hit_p)->data, 0, len*sizeof(outbuf[0]));
+	}
+	else {
+		ret = -EBUSY;
+	}
+	spin_unlock_irqrestore(&wc->reglock, flags);
+	return ret;
+}
+
+int t1_vpm150m_getreg_full_return(struct t1 *wc, int pagechange, unsigned int len,
+	unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
+{
+	int ret = 0;
+	unsigned long flags;
+	BUG_ON(!hit_p);
+	spin_lock_irqsave(&wc->reglock, flags);
 	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		hit = vpm150m_empty_slot(wc);
-		if (hit) {
-			hit->flags = __VPM150M_RD;
-			if(pagechange)
-				hit->flags |= __VPM150M_RWPAGE;
-			hit->datalen = len;
-			hit->address = addr;
-			for (i=0; i < hit->datalen; i++)
-				hit->data[i] = 0x0000;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
+		if ((*hit_p)->flags & __VPM150M_FIN) {
+			memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0])));
+			(*hit_p)->flags = 0;
+			(*hit_p) = NULL;
+			ret = 0;
+		}
+		else {
+			spin_unlock_irqrestore(&wc->reglock, flags);
+			if ((ret=schluffen(&wc->regq))) {
+				return ret;
+			}
+			spin_lock_irqsave(&wc->reglock, flags);
+			ret = -EBUSY;
+		}
+	} while (-EBUSY == ret);
+	spin_unlock_irqrestore(&wc->reglock, flags);
+	return ret;
+}
+
+int t1_vpm150m_getreg_full(struct t1 *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
+{
+	struct vpm150m_cmd *hit = 0;
+	int ret = 0;
+	do {
+		ret = t1_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit);
 		if (!hit) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
+			if ( -EBUSY == ret ) {
+				if ((ret = schluffen(&wc->regq))) 
+					return ret;
+			}
+			BUG_ON( 0 != ret);
 		}
 	} while (!hit);
 
-#if 1
-	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		if (hit->flags & __VPM150M_FIN) {
-			for (i = 0; i < hit->datalen; i++)
-				outbuf[i] = hit->data[i];
-			hit->flags = 0;
-			hit=NULL;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
-		if (hit) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit);
-
-#endif
-
+	ret = t1_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit);
 	return ret;
 }
 
@@ -403,20 +445,10 @@
 unsigned short t1_vpm150m_getreg(struct t1 *wc, unsigned int len, unsigned int addr, unsigned short *data)
 {
 	unsigned short res;
-	unsigned short count=0;
-	unsigned short first_data=0;
-	do {
-		t1_vpm150m_setpage(wc, addr >> 16);
-		if ((addr >> 16) != ((addr + len) >> 16))
-			module_printk("getreg: You found it!\n");
-		if (count > 0) {
-			first_data = *data;
-		}
-		res = t1_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
-	} while (((0==count++) || (first_data != *data)) && (count < 100));
-	if (count >= 100) {
-		module_printk(" %s:%d\n", __FILE__, __LINE__);
-	}
+	t1_vpm150m_setpage(wc, addr >> 16);
+	if ((addr >> 16) != ((addr + len) >> 16))
+		module_printk("getreg: You found it!\n");
+	res = t1_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
 	return res;
 }
 
@@ -985,8 +1017,31 @@
 	struct t1 *wc = wc_find_iface(DspId);
 	int i;
 	int transcount;
-
-	if (wc && wc->vpm150m) {
+	int ret;
+
+	vpm150m_io_wait(wc);
+	if ( NumWords < VPM150M_MAX_COMMANDS ) {
+		struct vpm150m_cmd* cmds[VPM150M_MAX_COMMANDS] = {0};
+		t1_vpm150m_setpage(wc, DspAddress >> 16);
+		DspAddress &= 0xffff;
+		for (i=0; i < NumWords; ++i) {
+			ret = t1_vpm150m_getreg_full_async(wc,0,1,DspAddress+i,&pWordValues[i],
+				&cmds[i]);
+			if (0 != ret) {
+				dump_stack();
+				return;
+			}
+		}
+		for (i=NumWords-1; i >=0; --i) {
+			ret = t1_vpm150m_getreg_full_return(wc,0,1,DspAddress+i,&pWordValues[i],
+				&cmds[i]);
+			if (0 != ret) {
+				dump_stack();
+				return;
+			}
+		}
+	}
+	else {
 		for (i = 0; i < NumWords;) {
 			if ((NumWords - i) > VPM150M_MAX_DATA)
 				transcount = VPM150M_MAX_DATA;

Modified: branches/1.4/wctdm24xxp/GpakCust.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/wctdm24xxp/GpakCust.c?view=diff&rev=3592&r1=3591&r2=3592
==============================================================================
--- branches/1.4/wctdm24xxp/GpakCust.c (original)
+++ branches/1.4/wctdm24xxp/GpakCust.c Wed Jan  2 14:30:58 2008
@@ -105,51 +105,97 @@
 	int x;
 
 	for (x = 0; x < VPM150M_MAX_COMMANDS; x++)
-		if (!wc->vpm150m->cmdq[x].desc)
+		if (!wc->vpm150m->cmdq[x].desc) {
 			return &wc->vpm150m->cmdq[x];
+		}
 	return NULL;
 }
 
-
-unsigned short wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
-{
+/* Wait for any outstanding commands to be completed. */
+static inline int vpm150m_io_wait(struct wctdm *wc)
+{
+	int x;
+	int ret=0;
+	for (x=0; x < VPM150M_MAX_COMMANDS;) {
+		if (wc->vpm150m->cmdq[x].desc) {
+			if ((ret=schluffen(&wc->regq))) {
+				return ret;
+			}
+			x=0;
+		}
+		else {
+			++x;
+		}
+	}
+	return ret;
+}
+
+int wctdm_vpm150m_getreg_full_async(struct wctdm *wc, int pagechange, unsigned int len, 
+	unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
+{
+	int ret=0;
 	unsigned long flags;
-	volatile struct vpm150m_cmd *hit;
-	unsigned short ret = 0;
-	int i;
+	BUG_ON(!hit_p);
+	spin_lock_irqsave(&wc->reglock, flags);
+	(*hit_p) = vpm150m_empty_slot(wc);
+	if (*hit_p) {
+		(*hit_p)->desc = __VPM150M_RD;
+		if (pagechange) {
+			(*hit_p)->desc |= __VPM150M_RWPAGE;
+		}
+		(*hit_p)->datalen = len;
+		(*hit_p)->addr = addr;
+		memset((*hit_p)->data, 0, len*sizeof(outbuf[0]));
+	}
+	else {
+		ret = -EBUSY;
+	}
+	spin_unlock_irqrestore(&wc->reglock, flags);
+	return ret;
+}
+
+int wctdm_vpm150m_getreg_full_return(struct wctdm *wc, int pagechange, unsigned int len,
+	unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
+{
+	int ret = 0;
+	unsigned long flags;
+	BUG_ON(!hit_p);
+	spin_lock_irqsave(&wc->reglock, flags);
 	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		hit = vpm150m_empty_slot(wc);
-		if (hit) {
-			hit->desc = __VPM150M_RD;
-			if (pagechange) {
-				hit->desc |= __VPM150M_RWPAGE;
-			}
-			hit->datalen = len;
-			hit->addr = addr;
-			for (i = 0; i < hit->datalen; i++)
-				hit->data[i] = 0x0000;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
+		if ((*hit_p)->desc & __VPM150M_FIN) {
+			memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0])));
+			(*hit_p)->desc = 0;
+			(*hit_p) = NULL;
+			ret = 0;
+		}
+		else {
+			spin_unlock_irqrestore(&wc->reglock, flags);
+			if ((ret=schluffen(&wc->regq))) {
+				return ret;
+			}
+			spin_lock_irqsave(&wc->reglock, flags);
+			ret = -EBUSY;
+		}
+	} while (-EBUSY == ret);
+	spin_unlock_irqrestore(&wc->reglock, flags);
+	return ret;
+}
+
+int wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
+{
+	struct vpm150m_cmd *hit = 0;
+	int ret = 0;
+	do {
+		ret = wctdm_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit);
 		if (!hit) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
+			if ( -EBUSY == ret ) {
+				if ((ret = schluffen(&wc->regq))) 
+					return ret;
+			}
+			BUG_ON(0 != ret);
 		}
 	} while (!hit);
-	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		if (hit->desc & __VPM150M_FIN) {
-			for (i = 0; i < hit->datalen; i++)
-				outbuf[i] = hit->data[i];
-			hit->desc = 0;
-			hit = NULL;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
-		if (hit) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit);
+	ret = wctdm_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit);
 	return ret;
 }
 
@@ -202,17 +248,10 @@
 unsigned short wctdm_vpm150m_getreg(struct wctdm *wc, unsigned int len, unsigned int addr, unsigned short *data)
 {
 	unsigned short res;
-	unsigned short count=0;
-	unsigned short first_data=0;
-	do {
-		wctdm_vpm150m_setpage(wc, addr >> 16);
-		if ((addr >> 16) != ((addr + len) >> 16))
-			printk("getreg: You found it!\n");
-		if (count > 0) {
-			first_data = *data;
-		}
-		res = wctdm_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
-	} while(((0==count++) || (first_data != *data)) && (count < 100));
+	wctdm_vpm150m_setpage(wc, addr >> 16);
+	if ((addr >> 16) != ((addr + len) >> 16))
+		printk("getreg: You found it!\n");
+	res = wctdm_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
  	return res;
 }
 
@@ -247,9 +286,29 @@
 	struct wctdm *wc = wc_find_iface(DspId);
 	int i;
 	int transcount;
-
-	//printk("Reading %d words from memory\n");
-	if (wc && wc->vpm150m) {
+	int ret;
+
+	vpm150m_io_wait(wc);
+	if ( NumWords < VPM150M_MAX_COMMANDS ) {
+		struct vpm150m_cmd* cmds[VPM150M_MAX_COMMANDS] = {0};
+		wctdm_vpm150m_setpage(wc, DspAddress >> 16);
+		DspAddress &= 0xffff;
+		for (i=0; i < NumWords; ++i) {
+			ret = wctdm_vpm150m_getreg_full_async(wc,0,1,DspAddress+i,&pWordValues[i],
+				&cmds[i]);
+			if (0 != ret) {
+				return ret;
+			}
+		}
+		for (i=NumWords-1; i >=0; --i) {
+			ret = wctdm_vpm150m_getreg_full_return(wc,0,1,DspAddress+i,&pWordValues[i],
+				&cmds[i]);
+			if (0 != ret) {
+				return ret;
+			}
+		}
+	}
+	else {
 		for (i = 0; i < NumWords;) {
 			if ((NumWords - i) > VPM150M_MAX_DATA)
 				transcount = VPM150M_MAX_DATA;
@@ -262,7 +321,6 @@
 	return;
 }
 
-
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  * gpakWriteDspMemory - Write DSP memory.
  *

Modified: branches/1.4/wctdm24xxp/base.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/wctdm24xxp/base.c?view=diff&rev=3592&r1=3591&r2=3592
==============================================================================
--- branches/1.4/wctdm24xxp/base.c (original)
+++ branches/1.4/wctdm24xxp/base.c Wed Jan  2 14:30:58 2008
@@ -3730,8 +3730,6 @@
 		while (test_bit(VPM150M_HPIRESET, &vpm150m->control))
 			schluffen(&wc->regq);
 
-		msleep(1000);
-
 		printk("VPMADT032 Loading firwmare... ");
 		downloadstatus = gpakDownloadDsp(vpm150m->dspid, &fw);
 
@@ -3750,7 +3748,6 @@
 		while (test_bit(VPM150M_SWRESET, &vpm150m->control))
 			schluffen(&wc->regq);
 
-		msleep(1000);
 #if 0
 	}
 #endif

Modified: branches/1.4/wctdm24xxp/wctdm24xxp.h
URL: http://svn.digium.com/view/zaptel/branches/1.4/wctdm24xxp/wctdm24xxp.h?view=diff&rev=3592&r1=3591&r2=3592
==============================================================================
--- branches/1.4/wctdm24xxp/wctdm24xxp.h (original)
+++ branches/1.4/wctdm24xxp/wctdm24xxp.h Wed Jan  2 14:30:58 2008
@@ -156,7 +156,7 @@
 	unsigned long desiredecstate;
 	unsigned long curdtmfmutestate;
 	unsigned long desireddtmfmutestate;
-	struct vpm150m_cmd cmdq[MAX_COMMANDS];
+	struct vpm150m_cmd cmdq[VPM150M_MAX_COMMANDS];
 	unsigned char curtone[24];
 };
 

Modified: branches/1.4/wcte12xp/vpmadt032.c
URL: http://svn.digium.com/view/zaptel/branches/1.4/wcte12xp/vpmadt032.c?view=diff&rev=3592&r1=3591&r2=3592
==============================================================================
--- branches/1.4/wcte12xp/vpmadt032.c (original)
+++ branches/1.4/wcte12xp/vpmadt032.c Wed Jan  2 14:30:58 2008
@@ -289,7 +289,7 @@
 {
 	unsigned int x;
 
-	for (x = 0; x < sizeof(wc->vpm150m->cmdq) / sizeof(wc->vpm150m->cmdq[0]); x++) {
+	for (x = 0; x < VPM150M_MAX_COMMANDS; x++) {
 		if (!wc->vpm150m->cmdq[x].flags) {
 			return &wc->vpm150m->cmdq[x];
 		}
@@ -297,50 +297,92 @@
 	return NULL;
 }
 
-unsigned short t1_vpm150m_getreg_full(struct t1 *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
-{
+/* Wait for any outstanding commands to be completed. */
+static inline int vpm150m_io_wait(struct t1 *wc)
+{
+	int x;
+	int ret=0;
+	for (x=0; x < VPM150M_MAX_COMMANDS;) {
+		if (wc->vpm150m->cmdq[x].flags) {
+			if ((ret=schluffen(&wc->regq))) {
+				return ret;
+			}
+			x=0;
+		}
+		else {
+			++x;
+		}
+	}
+	return ret;
+}
+
+int t1_vpm150m_getreg_full_async(struct t1 *wc, int pagechange, unsigned int len, 
+	unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
+{
+	int ret=0;
 	unsigned long flags;
-	volatile struct vpm150m_cmd *hit;
-	unsigned short ret = 0;
-	int i;
-
+	BUG_ON(!hit_p);
+	spin_lock_irqsave(&wc->reglock, flags);
+	(*hit_p) = vpm150m_empty_slot(wc);
+	if (*hit_p) {
+		(*hit_p)->flags = __VPM150M_RD;
+		if (pagechange) {
+			(*hit_p)->flags |= __VPM150M_RWPAGE;
+		}
+		(*hit_p)->datalen = len;
+		(*hit_p)->address = addr;
+		memset((*hit_p)->data, 0, len*sizeof(outbuf[0]));
+	}
+	else {
+		ret = -EBUSY;
+	}
+	spin_unlock_irqrestore(&wc->reglock, flags);
+	return ret;
+}
+
+int t1_vpm150m_getreg_full_return(struct t1 *wc, int pagechange, unsigned int len,
+	unsigned short addr, unsigned short *outbuf, struct vpm150m_cmd **hit_p)
+{
+	int ret = 0;
+	unsigned long flags;
+	BUG_ON(!hit_p);
+	spin_lock_irqsave(&wc->reglock, flags);
 	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		hit = vpm150m_empty_slot(wc);
-		if (hit) {
-			hit->flags = __VPM150M_RD;
-			if(pagechange)
-				hit->flags |= __VPM150M_RWPAGE;
-			hit->datalen = len;
-			hit->address = addr;
-			for (i=0; i < hit->datalen; i++)
-				hit->data[i] = 0x0000;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
+		if ((*hit_p)->flags & __VPM150M_FIN) {
+			memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0])));
+			(*hit_p)->flags = 0;
+			(*hit_p) = NULL;
+			ret = 0;
+		}
+		else {
+			spin_unlock_irqrestore(&wc->reglock, flags);
+			if ((ret=schluffen(&wc->regq))) {
+				return ret;
+			}
+			spin_lock_irqsave(&wc->reglock, flags);
+			ret = -EBUSY;
+		}
+	} while (-EBUSY == ret);
+	spin_unlock_irqrestore(&wc->reglock, flags);
+	return ret;
+}
+
+int t1_vpm150m_getreg_full(struct t1 *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf)
+{
+	struct vpm150m_cmd *hit = 0;
+	int ret = 0;
+	do {
+		ret = t1_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit);
 		if (!hit) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
+			if ( -EBUSY == ret ) {
+				if ((ret = schluffen(&wc->regq))) 
+					return ret;
+			}
+			BUG_ON( 0 != ret);
 		}
 	} while (!hit);
 
-#if 1
-	do {
-		spin_lock_irqsave(&wc->reglock, flags);
-		if (hit->flags & __VPM150M_FIN) {
-			for (i = 0; i < hit->datalen; i++)
-				outbuf[i] = hit->data[i];
-			hit->flags = 0;
-			hit=NULL;
-		}
-		spin_unlock_irqrestore(&wc->reglock, flags);
-		if (hit) {
-			if ((ret = schluffen(&wc->regq)))
-				return ret;
-		}
-	} while (hit);
-
-#endif
-
+	ret = t1_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit);
 	return ret;
 }
 
@@ -403,20 +445,10 @@
 unsigned short t1_vpm150m_getreg(struct t1 *wc, unsigned int len, unsigned int addr, unsigned short *data)
 {
 	unsigned short res;
-	unsigned short count=0;
-	unsigned short first_data=0;
-	do {
-		t1_vpm150m_setpage(wc, addr >> 16);
-		if ((addr >> 16) != ((addr + len) >> 16))
-			module_printk("getreg: You found it!\n");
-		if (count > 0) {
-			first_data = *data;
-		}
-		res = t1_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
-	} while (((0==count++) || (first_data != *data)) && (count < 100));
-	if (count >= 100) {
-		module_printk(" %s:%d\n", __FILE__, __LINE__);
-	}
+	t1_vpm150m_setpage(wc, addr >> 16);
+	if ((addr >> 16) != ((addr + len) >> 16))
+		module_printk("getreg: You found it!\n");
+	res = t1_vpm150m_getreg_full(wc, 0, len, addr & 0xffff, data);
 	return res;
 }
 
@@ -985,8 +1017,31 @@
 	struct t1 *wc = wc_find_iface(DspId);
 	int i;
 	int transcount;
-
-	if (wc && wc->vpm150m) {
+	int ret;
+
+	vpm150m_io_wait(wc);
+	if ( NumWords < VPM150M_MAX_COMMANDS ) {
+		struct vpm150m_cmd* cmds[VPM150M_MAX_COMMANDS] = {0};
+		t1_vpm150m_setpage(wc, DspAddress >> 16);
+		DspAddress &= 0xffff;
+		for (i=0; i < NumWords; ++i) {
+			ret = t1_vpm150m_getreg_full_async(wc,0,1,DspAddress+i,&pWordValues[i],
+				&cmds[i]);
+			if (0 != ret) {
+				dump_stack();
+				return;
+			}
+		}
+		for (i=NumWords-1; i >=0; --i) {
+			ret = t1_vpm150m_getreg_full_return(wc,0,1,DspAddress+i,&pWordValues[i],
+				&cmds[i]);
+			if (0 != ret) {
+				dump_stack();
+				return;
+			}
+		}
+	}
+	else {
 		for (i = 0; i < NumWords;) {
 			if ((NumWords - i) > VPM150M_MAX_DATA)
 				transcount = VPM150M_MAX_DATA;




More information about the zaptel-commits mailing list