From b2af10d896f48ec605ada4af4df70f53bca6badb Mon Sep 17 00:00:00 2001 From: kpfleming Date: Thu, 1 Feb 2007 20:17:23 +0000 Subject: revert some code that appears to be causing crashes git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@2078 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- zttranscode.c | 85 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 40 deletions(-) (limited to 'zttranscode.c') diff --git a/zttranscode.c b/zttranscode.c index aad71cc..39e84ae 100644 --- a/zttranscode.c +++ b/zttranscode.c @@ -47,7 +47,7 @@ #endif static int debug = 0; -static LIST_HEAD(trans); +static struct zt_transcoder *trans; static spinlock_t translock = SPIN_LOCK_UNLOCKED; EXPORT_SYMBOL(zt_transcoder_register); @@ -68,12 +68,11 @@ struct zt_transcoder *zt_transcoder_alloc(int numchans) memset(ztc, 0, size); strcpy(ztc->name, ""); ztc->numchannels = numchans; - INIT_LIST_HEAD(&ztc->list); for (x=0;xnumchannels;x++) { init_waitqueue_head(&ztc->channels[x].ready); ztc->channels[x].parent = ztc; ztc->channels[x].offset = x; - ztc->channels[x].chan_built = 0; + ztc->channels[x].flags.chan_built = 0; ztc->channels[x].built_fmts = 0; } @@ -104,50 +103,58 @@ void zt_transcoder_free(struct zt_transcoder *ztc) kfree(ztc); } -int zt_transcoder_register(struct zt_transcoder *tc, struct module *owner) +/* Register a transcoder */ +int zt_transcoder_register(struct zt_transcoder *tc) { struct zt_transcoder *cur; + int res = -EBUSY; spin_lock(&translock); - list_for_each_entry(cur, &trans, list) { + for (cur = trans; cur; cur = cur->next) { if (cur == tc) { spin_unlock(&translock); - return -EBUSY; + return res; } } - tc->owner = owner; - list_add(&tc->list, &trans); + tc->next = trans; + trans = tc; printk("Registered codec translator '%s' with %d transcoders (srcs=%08x, dsts=%08x)\n", tc->name, tc->numchannels, tc->srcfmts, tc->dstfmts); + res = 0; spin_unlock(&translock); - return 0; + return res; } /* Unregister a transcoder */ int zt_transcoder_unregister(struct zt_transcoder *tc) { - struct zt_transcoder *cur, *next; + struct zt_transcoder *cur, *prev; + int res = -EINVAL; spin_lock(&translock); - list_for_each_entry_safe(cur, next, &trans, list) { - if (cur == tc) { - list_del_init(&cur->list); + for (cur = trans, prev = NULL; cur; prev = cur, cur = cur->next) { + if (cur == tc) break; - } } if (!cur) { spin_unlock(&translock); - return -EINVAL; + return res; } + if (prev) + prev->next = tc->next; + else + trans = tc->next; + tc->next = NULL; printk("Unregistered codec translator '%s' with %d transcoders (srcs=%08x, dsts=%08x)\n", tc->name, tc->numchannels, tc->srcfmts, tc->dstfmts); + res = 0; spin_unlock(&translock); - return 0; + return res; } /* Alert a transcoder */ @@ -178,8 +185,7 @@ static int zt_tc_open(struct inode *inode, struct file *file) memset(ztc, 0, sizeof(*ztc)); memset(zth, 0, sizeof(*zth)); - ztc->transient = 1; - ztc->busy = 1; + ztc->flags.transient = ztc->flags.busy = 1; ztc->tch = zth; if (debug) printk("Allocated Transcoder Channel, header is at %p!\n", zth); @@ -201,7 +207,7 @@ static void ztc_release(struct zt_transcoder_channel *ztc) if (!ztc) return; - ztc->busy = 0; + ztc->flags.busy = 0; if (ztc->tch) { for (page = virt_to_page(zth); @@ -213,12 +219,12 @@ static void ztc_release(struct zt_transcoder_channel *ztc) ztc->tch = NULL; - if (ztc->have_reference) { + if (ztc->flags.have_reference) { module_put(ztc->parent->owner); - ztc->have_reference = 0; + ztc->flags.have_reference = 0; } - if (ztc->transient); + if (ztc->flags.transient) kfree(ztc); if (debug) @@ -244,7 +250,7 @@ static int do_allocate(struct zt_transcoder_channel **ztc) ((*ztc)->dstfmt != zth->dstfmt)) { /* Find new transcoder */ spin_lock(&translock); - list_for_each_entry(tc, &trans, list) { + for (tc = trans; tc && !newztc; tc = tc->next) { if (!(tc->srcfmts & zth->srcfmt)) continue; @@ -253,10 +259,9 @@ static int do_allocate(struct zt_transcoder_channel **ztc) match = 1; for (x = 0; x < tc->numchannels; x++) { - if (tc->channels[x].busy) + if (tc->channels[x].flags.busy) continue; - - if (tc->channels[x].chan_built && + if (tc->channels[x].flags.chan_built && ((zth->srcfmt | zth->dstfmt) != tc->channels[x].built_fmts)) continue; @@ -264,8 +269,7 @@ static int do_allocate(struct zt_transcoder_channel **ztc) continue; newztc = &tc->channels[x]; - newztc->busy = 1; - newztc->have_reference = 1; + newztc->flags.busy = 1; break; } } @@ -279,7 +283,14 @@ static int do_allocate(struct zt_transcoder_channel **ztc) (*ztc) = newztc; (*ztc)->tch = origztc->tch; origztc->tch = NULL; - (*ztc)->transient = 0; + /* ensure that the 'busy' flag doesn't get cleared, + even for a short time, so no other thread will + grab this channel + */ + origztc->flags.busy = 1; + (*ztc)->flags = origztc->flags; + (*ztc)->flags.transient = 0; + (*ztc)->flags.have_reference = 1; ztc_release(origztc); } @@ -295,7 +306,7 @@ static int wait_busy(struct zt_transcoder_channel *ztc) int ret; for (;;) { - if (!(ztc->tch->busy)) + if (!ztc->tch->busy) return 0; if ((ret = schluffen(&ztc->ready))) return ret; @@ -312,16 +323,10 @@ static int zt_tc_getinfo(unsigned long data) return -EFAULT; spin_lock(&translock); - x = info.tcnum; - list_for_each_entry(tc, &trans, list) { - if (!x) - break; - else - x--; - } + for (tc = trans, x = info.tcnum; tc && x; tc = tc->next, x--); spin_unlock(&translock); - if (x || !tc) + if (!tc) return -ENOSYS; strncpy(info.name, tc->name, sizeof(info.name) - 1); @@ -357,9 +362,9 @@ static int zt_tc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, break; case ZT_TCOP_RELEASE: ret = ztc->parent->operation(ztc, ZT_TCOP_RELEASE); - if (ztc->have_reference) { + if (ztc->flags.have_reference) { module_put(ztc->parent->owner); - ztc->have_reference = 0; + ztc->flags.have_reference = 0; } break; case ZT_TCOP_TRANSCODE: -- cgit v1.2.3