summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-04-07 16:43:47 +0000
committermattf <mattf@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-04-07 16:43:47 +0000
commitb458d3c90603033918494e30e0e29cd5254dd027 (patch)
tree738972468279c9e4546852a3268fe197f3dd841a
parent155a71d04637d8bdd00d7f6727a041006ba9dbeb (diff)
chan variables are accessed without a lock, so they could change underneath us.
Make sure we use a local variable for access to them. (#9208) git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2396 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r--zaptel.c59
1 files changed, 31 insertions, 28 deletions
diff --git a/zaptel.c b/zaptel.c
index 3d27b28..c43db21 100644
--- a/zaptel.c
+++ b/zaptel.c
@@ -769,16 +769,19 @@ static int schluffen(wait_queue_head_t *q)
if (!signal_pending(current)) schedule();
current->state = TASK_RUNNING;
remove_wait_queue(q, &wait);
- if (signal_pending(current)) return -ERESTARTSYS;
+ if (signal_pending(current)) {
+ printk(KERN_WARNING "zaptel.c:%d (pid %d: %s) got signal %08lX\n", __LINE__, current->pid, current->comm, current->pending.signal.sig[0]);
+ return -ERESTARTSYS;
+ }
return(0);
}
-static inline void calc_fcs(struct zt_chan *ss)
+static inline void calc_fcs(struct zt_chan *ss, int inwritebuf)
{
int x;
unsigned int fcs=PPP_INITFCS;
- unsigned char *data = ss->writebuf[ss->inwritebuf];
- int len = ss->writen[ss->inwritebuf];
+ unsigned char *data = ss->writebuf[inwritebuf];
+ int len = ss->writen[inwritebuf];
/* Not enough space to do FCS calculation */
if (len < 2)
return;
@@ -1765,8 +1768,8 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u
if ((unit == 24) || (unit == 48) || (unit == 16) || (unit == 47)) {
int myamnt = amnt;
int x;
- if (amnt > chan->readn[chan->outreadbuf])
- myamnt = chan->readn[chan->outreadbuf];
+ if (amnt > chan->readn[res])
+ myamnt = chan->readn[res];
printk("zt_chan_read(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d\n",
unit, chan->inwritebuf, chan->outwritebuf, myamnt);
printk("\t("); for (x = 0; x < myamnt; x++) printk((x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]);
@@ -1775,8 +1778,8 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u
#endif
/* end addition */
if (chan->flags & ZT_FLAG_LINEAR) {
- if (amnt > (chan->readn[chan->outreadbuf] << 1))
- amnt = chan->readn[chan->outreadbuf] << 1;
+ if (amnt > (chan->readn[res] << 1))
+ amnt = chan->readn[res] << 1;
if (amnt) {
/* There seems to be a max stack size, so we have
to do this in smaller pieces */
@@ -1789,7 +1792,7 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u
if (pass > 128)
pass = 128;
for (x=0;x<pass;x++)
- lindata[x] = ZT_XLAW(chan->readbuf[chan->outreadbuf][x + pos], chan);
+ lindata[x] = ZT_XLAW(chan->readbuf[res][x + pos], chan);
if (copy_to_user(usrbuf + (pos << 1), lindata, pass << 1))
return -EFAULT;
left -= pass;
@@ -1797,18 +1800,18 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u
}
}
} else {
- if (amnt > chan->readn[chan->outreadbuf])
- amnt = chan->readn[chan->outreadbuf];
+ if (amnt > chan->readn[res])
+ amnt = chan->readn[res];
if (amnt) {
- if (copy_to_user(usrbuf, chan->readbuf[chan->outreadbuf], amnt))
+ if (copy_to_user(usrbuf, chan->readbuf[res], amnt))
return -EFAULT;
}
}
spin_lock_irqsave(&chan->lock, flags);
- chan->readidx[chan->outreadbuf] = 0;
- chan->readn[chan->outreadbuf] = 0;
- oldbuf = chan->outreadbuf;
- chan->outreadbuf = (chan->outreadbuf + 1) % chan->numbufs;
+ chan->readidx[res] = 0;
+ chan->readn[res] = 0;
+ oldbuf = res;
+ res = (chan->outreadbuf + 1) % chan->numbufs;
if (chan->outreadbuf == chan->inreadbuf) {
/* Out of stuff */
chan->outreadbuf = -1;
@@ -1870,14 +1873,14 @@ static ssize_t zt_chan_write(struct file *file, const char *usrbuf, size_t count
}
#ifdef CONFIG_ZAPATA_DEBUG
- printk("zt_chan_write(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d\n",
- unit, chan->inwritebuf, chan->outwritebuf, amnt);
+ printk("zt_chan_write(unit: %d, res: %d, outwritebuf: %d amnt: %d\n",
+ unit, chan->res, chan->outwritebuf, amnt);
#endif
#if 0
if ((unit == 24) || (unit == 48) || (unit == 16) || (unit == 47)) {
int x;
- printk("zt_chan_write/in(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d, txdisable: %d)\n",
- unit, chan->inwritebuf, chan->outwritebuf, amnt, chan->txdisable);
+ printk("zt_chan_write/in(unit: %d, res: %d, outwritebuf: %d amnt: %d, txdisable: %d)\n",
+ unit, res, chan->outwritebuf, amnt, chan->txdisable);
printk("\t("); for (x = 0; x < amnt; x++) printk((x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]);
printk(")\n");
}
@@ -1899,21 +1902,21 @@ static ssize_t zt_chan_write(struct file *file, const char *usrbuf, size_t count
return -EFAULT;
left -= pass;
for (x=0;x<pass;x++)
- chan->writebuf[chan->inwritebuf][x + pos] = ZT_LIN2X(lindata[x], chan);
+ chan->writebuf[res][x + pos] = ZT_LIN2X(lindata[x], chan);
pos += pass;
}
- chan->writen[chan->inwritebuf] = amnt >> 1;
+ chan->writen[res] = amnt >> 1;
} else {
- if (copy_from_user(chan->writebuf[chan->inwritebuf], usrbuf, amnt))
+ if (copy_from_user(chan->writebuf[res], usrbuf, amnt))
return -EFAULT;
- chan->writen[chan->inwritebuf] = amnt;
+ chan->writen[res] = amnt;
}
- chan->writeidx[chan->inwritebuf] = 0;
+ chan->writeidx[res] = 0;
if (chan->flags & ZT_FLAG_FCS)
- calc_fcs(chan);
- oldbuf = chan->inwritebuf;
+ calc_fcs(chan, res);
+ oldbuf = res;
spin_lock_irqsave(&chan->lock, flags);
- chan->inwritebuf = (chan->inwritebuf + 1) % chan->numbufs;
+ chan->inwritebuf = (res + 1) % chan->numbufs;
if (chan->inwritebuf == chan->outwritebuf) {
/* Don't stomp on the transmitter, just wait for them to
wake us up */