dahdi: A little cleanup in the dahdi_ioctl_iomux function.

The primary change is to make clear that the wait result is not ever to
be returned by the function.  There are also edits to remove some
comments that were expressed clearly in the source already and ensure
that the iomux member of 'struct dahdi_chan' is only accessed under the
chan->lock.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Sean Bright <sean.bright@gmail.com>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9497 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
Shaun Ruffell 2010-11-25 00:07:10 +00:00
parent f406bba4c6
commit 75c33ce64e
2 changed files with 26 additions and 34 deletions

View File

@ -4981,70 +4981,62 @@ static int dahdi_ioctl_iomux(struct file *file, unsigned long data)
{ {
struct dahdi_chan *const chan = chan_from_file(file); struct dahdi_chan *const chan = chan_from_file(file);
unsigned long flags; unsigned long flags;
int ret; unsigned int iomask;
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
if (!chan) if (get_user(iomask, (int __user *)data))
return -EINVAL; return -EFAULT;
get_user(chan->iomask, (int __user *)data); if (unlikely(!iomask || !chan))
if (!chan->iomask)
return -EINVAL; return -EINVAL;
while (1) { while (1) {
unsigned int wait_result;
ret = 0; wait_result = 0;
prepare_to_wait(&chan->eventbufq, &wait, TASK_INTERRUPTIBLE); prepare_to_wait(&chan->eventbufq, &wait, TASK_INTERRUPTIBLE);
spin_lock_irqsave(&chan->lock, flags); spin_lock_irqsave(&chan->lock, flags);
/* if looking for read */ chan->iomask = iomask;
if (chan->iomask & DAHDI_IOMUX_READ) { if (iomask & DAHDI_IOMUX_READ) {
/* if read available */
if ((chan->outreadbuf > -1) && !chan->rxdisable) if ((chan->outreadbuf > -1) && !chan->rxdisable)
ret |= DAHDI_IOMUX_READ; wait_result |= DAHDI_IOMUX_READ;
} }
if (iomask & DAHDI_IOMUX_WRITE) {
/* if looking for write avail */
if (chan->iomask & DAHDI_IOMUX_WRITE) {
if (chan->inwritebuf > -1) if (chan->inwritebuf > -1)
ret |= DAHDI_IOMUX_WRITE; wait_result |= DAHDI_IOMUX_WRITE;
} }
/* if looking for write empty */ if (iomask & DAHDI_IOMUX_WRITEEMPTY) {
if (chan->iomask & DAHDI_IOMUX_WRITEEMPTY) {
/* if everything empty -- be sure the transmitter is /* if everything empty -- be sure the transmitter is
* enabled */ * enabled */
chan->txdisable = 0; chan->txdisable = 0;
if (chan->outwritebuf < 0) if (chan->outwritebuf < 0)
ret |= DAHDI_IOMUX_WRITEEMPTY; wait_result |= DAHDI_IOMUX_WRITEEMPTY;
} }
/* if looking for signalling event */ if (iomask & DAHDI_IOMUX_SIGEVENT) {
if (chan->iomask & DAHDI_IOMUX_SIGEVENT) {
/* if event */
if (chan->eventinidx != chan->eventoutidx) if (chan->eventinidx != chan->eventoutidx)
ret |= DAHDI_IOMUX_SIGEVENT; wait_result |= DAHDI_IOMUX_SIGEVENT;
} }
spin_unlock_irqrestore(&chan->lock, flags); spin_unlock_irqrestore(&chan->lock, flags);
/* if something to return, or not to wait */ if (wait_result || (iomask & DAHDI_IOMUX_NOWAIT)) {
if (ret || (chan->iomask & DAHDI_IOMUX_NOWAIT)) { put_user(wait_result, (int __user *)data);
/* set return value */
put_user(ret, (int __user *)data);
ret = 0;
break; /* get out of loop */
}
if (!signal_pending(current)) {
schedule();
continue;
}
ret = -ERESTARTSYS;
break; break;
} }
if (signal_pending(current)) {
finish_wait(&chan->eventbufq, &wait); finish_wait(&chan->eventbufq, &wait);
return -ERESTARTSYS;
}
schedule();
}
finish_wait(&chan->eventbufq, &wait);
spin_lock_irqsave(&chan->lock, flags);
chan->iomask = 0; chan->iomask = 0;
return ret; spin_unlock_irqrestore(&chan->lock, flags);
return 0;
} }
#ifdef CONFIG_DAHDI_MIRROR #ifdef CONFIG_DAHDI_MIRROR

View File

@ -509,7 +509,7 @@ struct dahdi_chan {
int cadencepos; /*!< Where in the cadence we are */ int cadencepos; /*!< Where in the cadence we are */
/* I/O Mask */ /* I/O Mask */
int iomask; /*! I/O Mux signal mask */ unsigned int iomask; /*! I/O Mux signal mask */
wait_queue_head_t sel; /*! thingy for select stuff */ wait_queue_head_t sel; /*! thingy for select stuff */
/* HDLC state machines */ /* HDLC state machines */