提交 2704f807 编写于 作者: H H Hartley Sweeten 提交者: Greg Kroah-Hartman

staging: comedi: usbdux: bug fix for accessing 'ao_chanlist' in private data

In usbdux_ao_cmd(), the channels for the command are transfered from the
cmd->chanlist and stored in the private data 'ao_chanlist'. The channel
numbers are bit-shifted when stored so that they become the "command"
that is transfered to the device. The channel to command conversion
results in the 'ao_chanlist' having these values for the channels:

  channel 0 -> ao_chanlist = 0x00
  channel 1 -> ao_chanlist = 0x40
  channel 2 -> ao_chanlist = 0x80
  channel 3 -> ao_chanlist = 0xc0

The problem is, the usbduxsub_ao_isoc_irq() function uses the 'chan' value
from 'ao_chanlist' to access the 'ao_readback' array in the private data.
So instead of accessing the array as 0, 1, 2, 3, it accesses it as 0x00,
0x40, 0x80, 0xc0.

Fix this by storing the raw channel number in 'ao_chanlist' and doing the
bit-shift when creating the command.

Fixes: a998a3db "staging: comedi: usbdux: cleanup the private data 'outBuffer'"
Cc: stable <stable@vger.kernel.org> # 3.12
Signed-off-by: NH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: NIan Abbott <abbotti@mev.co.uk>
Acked-by: NBernd Porr <mail@berndporr.me.uk>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 8b425aa1
...@@ -493,7 +493,7 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb) ...@@ -493,7 +493,7 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb)
/* pointer to the DA */ /* pointer to the DA */
*datap++ = val & 0xff; *datap++ = val & 0xff;
*datap++ = (val >> 8) & 0xff; *datap++ = (val >> 8) & 0xff;
*datap++ = chan; *datap++ = chan << 6;
devpriv->ao_readback[chan] = val; devpriv->ao_readback[chan] = val;
s->async->events |= COMEDI_CB_BLOCK; s->async->events |= COMEDI_CB_BLOCK;
...@@ -1040,11 +1040,8 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ...@@ -1040,11 +1040,8 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* set current channel of the running acquisition to zero */ /* set current channel of the running acquisition to zero */
s->async->cur_chan = 0; s->async->cur_chan = 0;
for (i = 0; i < cmd->chanlist_len; ++i) { for (i = 0; i < cmd->chanlist_len; ++i)
unsigned int chan = CR_CHAN(cmd->chanlist[i]); devpriv->ao_chanlist[i] = CR_CHAN(cmd->chanlist[i]);
devpriv->ao_chanlist[i] = chan << 6;
}
/* we count in steps of 1ms (125us) */ /* we count in steps of 1ms (125us) */
/* 125us mode not used yet */ /* 125us mode not used yet */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册