diff options
author | sruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2008-01-02 20:30:58 +0000 |
---|---|---|
committer | sruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2008-01-02 20:30:58 +0000 |
commit | 9148e9d9c1c245d2efaab859abf6e4c166655a07 (patch) | |
tree | 3b88050e2dcac67b188abe4ef2189866e9a6d73a | |
parent | 5440c67be10914b1e8ab931f3862c365d562a024 (diff) |
VPMADT032 stability changes for wctdm24xxp and wcte12xp:
- Remove double reads.
- Wait for writes to complete before starting reads.
- Optimize reads of multi-word register.
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@3592 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r-- | wctdm24xxp/GpakCust.c | 152 | ||||
-rw-r--r-- | wctdm24xxp/base.c | 3 | ||||
-rw-r--r-- | wctdm24xxp/wctdm24xxp.h | 2 | ||||
-rw-r--r-- | wcte12xp/vpmadt032.c | 155 |
4 files changed, 211 insertions, 101 deletions
diff --git a/wctdm24xxp/GpakCust.c b/wctdm24xxp/GpakCust.c index e8e91c4..1291e33 100644 --- a/wctdm24xxp/GpakCust.c +++ b/wctdm24xxp/GpakCust.c @@ -105,51 +105,97 @@ static inline struct vpm150m_cmd * vpm150m_empty_slot(struct wctdm *wc) 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; } +/* 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; +} -unsigned short wctdm_vpm150m_getreg_full(struct wctdm *wc, int pagechange, unsigned int len, unsigned short addr, unsigned short *outbuf) +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; + if ((*hit_p)->desc & __VPM150M_FIN) { + memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0]))); + (*hit_p)->desc = 0; + (*hit_p) = NULL; + ret = 0; } - spin_unlock_irqrestore(&wc->reglock, flags); - if (!hit) { - if ((ret = schluffen(&wc->regq))) + else { + spin_unlock_irqrestore(&wc->reglock, flags); + if ((ret=schluffen(&wc->regq))) { return ret; + } + spin_lock_irqsave(&wc->reglock, flags); + ret = -EBUSY; } - } while (!hit); + } 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 { - 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; + ret = wctdm_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit); + if (!hit) { + if ( -EBUSY == ret ) { + if ((ret = schluffen(&wc->regq))) + return ret; + } + BUG_ON(0 != ret); } - } while (hit); + } while (!hit); + ret = wctdm_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit); return ret; } @@ -202,17 +248,10 @@ unsigned char wctdm_vpm150m_getpage(struct wctdm *wc) 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 @@ void gpakReadDspMemory( 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 @@ void gpakReadDspMemory( return; } - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * gpakWriteDspMemory - Write DSP memory. * diff --git a/wctdm24xxp/base.c b/wctdm24xxp/base.c index 208579c..aa74c1e 100644 --- a/wctdm24xxp/base.c +++ b/wctdm24xxp/base.c @@ -3730,8 +3730,6 @@ static enum vpmadt032_init_result wctdm_vpm150m_init(struct wctdm *wc) 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 @@ static enum vpmadt032_init_result wctdm_vpm150m_init(struct wctdm *wc) while (test_bit(VPM150M_SWRESET, &vpm150m->control)) schluffen(&wc->regq); - msleep(1000); #if 0 } #endif diff --git a/wctdm24xxp/wctdm24xxp.h b/wctdm24xxp/wctdm24xxp.h index cff4fd6..46375a2 100644 --- a/wctdm24xxp/wctdm24xxp.h +++ b/wctdm24xxp/wctdm24xxp.h @@ -156,7 +156,7 @@ struct vpm150m { 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]; }; diff --git a/wcte12xp/vpmadt032.c b/wcte12xp/vpmadt032.c index 14af1ed..3affadd 100644 --- a/wcte12xp/vpmadt032.c +++ b/wcte12xp/vpmadt032.c @@ -289,7 +289,7 @@ static struct vpm150m_cmd * vpm150m_empty_slot(struct t1 *wc) { 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 @@ static struct vpm150m_cmd * vpm150m_empty_slot(struct t1 *wc) 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; + if ((*hit_p)->flags & __VPM150M_FIN) { + memcpy(outbuf, (*hit_p)->data, len*(sizeof(outbuf[0]))); + (*hit_p)->flags = 0; + (*hit_p) = NULL; + ret = 0; } - spin_unlock_irqrestore(&wc->reglock, flags); - if (!hit) { - if ((ret = schluffen(&wc->regq))) + else { + spin_unlock_irqrestore(&wc->reglock, flags); + if ((ret=schluffen(&wc->regq))) { return ret; + } + spin_lock_irqsave(&wc->reglock, flags); + ret = -EBUSY; } - } while (!hit); + } while (-EBUSY == ret); + spin_unlock_irqrestore(&wc->reglock, flags); + return ret; +} -#if 1 +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 { - 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; + ret = t1_vpm150m_getreg_full_async(wc, pagechange, len, addr, outbuf, &hit); + if (!hit) { + if ( -EBUSY == ret ) { + if ((ret = schluffen(&wc->regq))) + return ret; + } + BUG_ON( 0 != ret); } - } while (hit); - -#endif + } while (!hit); + ret = t1_vpm150m_getreg_full_return(wc, pagechange, len, addr, outbuf, &hit); return ret; } @@ -403,20 +445,10 @@ int t1_vpm150m_setreg(struct t1 *wc, unsigned int len, unsigned int addr, unsign 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 @@ void gpakReadDspMemory( 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; |