summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-02-01 20:17:23 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-02-01 20:17:23 +0000
commitb2af10d896f48ec605ada4af4df70f53bca6badb (patch)
treecb33562d0111d965cee0aae1088ff2be7b794433
parent13179eb2fc4b2384550a1681513986584634bfd6 (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.c18
-rw-r--r--zaptel.h18
-rw-r--r--zttranscode.c85
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);
diff --git a/zaptel.h b/zaptel.h
index c974963..5434af3 100644
--- a/zaptel.h
+++ b/zaptel.h
@@ -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: