diff options
author | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-02-01 20:17:23 +0000 |
---|---|---|
committer | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-02-01 20:17:23 +0000 |
commit | b2af10d896f48ec605ada4af4df70f53bca6badb (patch) | |
tree | cb33562d0111d965cee0aae1088ff2be7b794433 | |
parent | 13179eb2fc4b2384550a1681513986584634bfd6 (diff) |
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
-rw-r--r-- | wctc4xxp/base.c | 18 | ||||
-rw-r--r-- | zaptel.h | 18 | ||||
-rw-r--r-- | zttranscode.c | 85 |
3 files changed, 64 insertions, 57 deletions
diff --git a/wctc4xxp/base.c b/wctc4xxp/base.c index c98f2d3..f42c577 100644 --- a/wctc4xxp/base.c +++ b/wctc4xxp/base.c @@ -626,7 +626,7 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op) switch (op) { case ZT_TCOP_ALLOCATE: - if (ztc->chan_built) + if (ztc->flags.chan_built) break; down(&wc->chansem); if (st->encoder) @@ -638,7 +638,7 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op) st->timeslot_out_num, st->timeslot_in_num, &(st->chan_out_num), &(st->chan_in_num)); /* Mark this channel as built */ - ztc->chan_built = 1; + ztc->flags.chan_built = 1; ztc->built_fmts = zth->dstfmt | zth->srcfmt; /* Mark the channel complement (other half of encoder/decoder pair) as built */ @@ -646,7 +646,7 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op) compl_ztc = &(wc->udecode->channels[st->timeslot_in_num >> 1]); else compl_ztc = &(wc->uencode->channels[st->timeslot_in_num >> 1]); - compl_ztc->chan_built = 1; + compl_ztc->flags.chan_built = 1; compl_ztc->built_fmts = zth->dstfmt | zth->srcfmt; compl_st = compl_ztc->pvt; compl_st->chan_in_num = st->chan_out_num; @@ -662,20 +662,20 @@ static int dte_operation(struct zt_transcoder_channel *ztc, int op) compl_ztc = &(wc->uencode->channels[st->timeslot_in_num >> 1]); /* If the channel complement (other half of the encoder/decoder pair) is not being used... */ - if (!compl_ztc->busy) { + if (!compl_ztc->flags.busy) { if (st->encoder) destroy_channel(wc, st->chan_in_num, st->chan_out_num); else destroy_channel(wc, st->chan_out_num, st->chan_in_num); /* Mark this channel as not built */ - ztc->chan_built = 0; + ztc->flags.chan_built = 0; ztc->built_fmts = 0; st->chan_in_num = 999; st->chan_out_num = 999; /* Mark the channel complement as not built */ - compl_ztc->chan_built = 0; + compl_ztc->flags.chan_built = 0; compl_ztc->built_fmts = 0; compl_st = compl_ztc->pvt; compl_st->chan_in_num = 999; @@ -1509,8 +1509,10 @@ static int __devinit init_one(struct pci_dev *pdev, const struct pci_device_id * wc->udecode->channels[x].pvt = &decoders[x]; } - zt_transcoder_register(wc->uencode, THIS_MODULE); - zt_transcoder_register(wc->udecode, THIS_MODULE); + wc->uencode->owner = wc->udecode->owner = THIS_MODULE; + + zt_transcoder_register(wc->uencode); + zt_transcoder_register(wc->udecode); /* Enable bus mastering */ pci_set_master(pdev); @@ -49,7 +49,6 @@ #endif #include <linux/fs.h> -#include <linux/list.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #define LINUX26 @@ -709,7 +708,7 @@ struct zt_transcode_header { __u32 magic; /* Magic value -- ZT_TRANSCODE_MAGIC, read by user */ __u32 config; /* Read/write by user */ - __u32 busy:1; /* Read/write by user */ + __u32 busy:1; /* Read/write by user */ __u8 userhdr[ZT_TRANSCODE_HDRLEN - (sizeof(__u32) * 10)]; /* Storage for user parameters */ __u8 srcdata[ZT_TRANSCODE_BUFSIZ / 2]; /* Storage of source data */ __u8 dstdata[ZT_TRANSCODE_BUFSIZ / 2]; /* Storage of destination data */ @@ -1379,19 +1378,20 @@ struct zt_transcoder_channel { wait_queue_head_t ready; int errorstatus; int offset; - unsigned int chan_built:1; - unsigned int have_reference:1; - unsigned int busy:1; - unsigned int transient:1; + struct { + unsigned int chan_built:1; + unsigned int busy:1; + unsigned int transient:1; + unsigned int have_reference:1; + } flags; unsigned int built_fmts; - unsigned int flags; unsigned int srcfmt; unsigned int dstfmt; struct zt_transcode_header *tch; }; struct zt_transcoder { - struct list_head list; + struct zt_transcoder *next; struct module *owner; char name[80]; int numchannels; @@ -1456,7 +1456,7 @@ struct zt_transcoder *zt_transcoder_alloc(int numchans); void zt_transcoder_free(struct zt_transcoder *ztc); /* Register a transcoder */ -int zt_transcoder_register(struct zt_transcoder *tc, struct module *owner); +int zt_transcoder_register(struct zt_transcoder *tc); /* Unregister a transcoder */ int zt_transcoder_unregister(struct zt_transcoder *tc); 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, "<unspecified>"); ztc->numchannels = numchans; - INIT_LIST_HEAD(&ztc->list); for (x=0;x<ztc->numchannels;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: |