staging: comedi: usbduxsigma: cleanup the private data 'outBuffer'
This buffer is used to cache the analog output values that are written to the analog output channels. Currently it only caches the single writes to the channels using the (*insn_write) callback. The async command writes are not cached. The buffer is also being kzalloc'ed during the attach of the driver to a size much larger that required. Rename the CamelCase buffer and change it to an array in the private data of the correct size to cache the analog output channel values. Modify the analog output urb callback so it updates the cached values with those used for the asynchronous command to allow readback after the command completes. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2dd87acb1a
commit
44d3fcaece
1 changed files with 12 additions and 13 deletions
|
@ -98,6 +98,8 @@ Status: testing
|
||||||
/* Number of channels (16 AD and offset)*/
|
/* Number of channels (16 AD and offset)*/
|
||||||
#define NUMCHANNELS 16
|
#define NUMCHANNELS 16
|
||||||
|
|
||||||
|
#define USBDUXSIGMA_NUM_AO_CHAN 4
|
||||||
|
|
||||||
/* Size of one A/D value */
|
/* Size of one A/D value */
|
||||||
#define SIZEADIN ((sizeof(int32_t)))
|
#define SIZEADIN ((sizeof(int32_t)))
|
||||||
|
|
||||||
|
@ -174,8 +176,8 @@ struct usbduxsigma_private {
|
||||||
int32_t *inBuffer;
|
int32_t *inBuffer;
|
||||||
/* input buffer for single insn */
|
/* input buffer for single insn */
|
||||||
int8_t *insnBuffer;
|
int8_t *insnBuffer;
|
||||||
/* output buffer for single DA outputs */
|
|
||||||
int16_t *outBuffer;
|
unsigned int ao_readback[USBDUXSIGMA_NUM_AO_CHAN];
|
||||||
|
|
||||||
unsigned high_speed:1;
|
unsigned high_speed:1;
|
||||||
unsigned ai_cmd_running:1;
|
unsigned ai_cmd_running:1;
|
||||||
|
@ -435,11 +437,9 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
|
||||||
len = s->async->cmd.chanlist_len;
|
len = s->async->cmd.chanlist_len;
|
||||||
*datap++ = len;
|
*datap++ = len;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
|
unsigned int chan = devpriv->dac_commands[i];
|
||||||
short val;
|
short val;
|
||||||
|
|
||||||
if (i >= NUMOUTCHANNELS)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ret = comedi_buf_get(s->async, &val);
|
ret = comedi_buf_get(s->async, &val);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev->class_dev, "buffer underflow\n");
|
dev_err(dev->class_dev, "buffer underflow\n");
|
||||||
|
@ -447,7 +447,8 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
|
||||||
COMEDI_CB_OVERFLOW);
|
COMEDI_CB_OVERFLOW);
|
||||||
}
|
}
|
||||||
*datap++ = val;
|
*datap++ = val;
|
||||||
*datap++ = devpriv->dac_commands[i];
|
*datap++ = chan;
|
||||||
|
devpriv->ao_readback[chan] = val;
|
||||||
|
|
||||||
s->async->events |= COMEDI_CB_BLOCK;
|
s->async->events |= COMEDI_CB_BLOCK;
|
||||||
comedi_event(dev, s);
|
comedi_event(dev, s);
|
||||||
|
@ -864,7 +865,7 @@ static int usbduxsigma_ao_insn_read(struct comedi_device *dev,
|
||||||
|
|
||||||
down(&devpriv->sem);
|
down(&devpriv->sem);
|
||||||
for (i = 0; i < insn->n; i++)
|
for (i = 0; i < insn->n; i++)
|
||||||
data[i] = devpriv->outBuffer[chan];
|
data[i] = devpriv->ao_readback[chan];
|
||||||
up(&devpriv->sem);
|
up(&devpriv->sem);
|
||||||
|
|
||||||
return insn->n;
|
return insn->n;
|
||||||
|
@ -895,7 +896,7 @@ static int usbduxsigma_ao_insn_write(struct comedi_device *dev,
|
||||||
up(&devpriv->sem);
|
up(&devpriv->sem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
devpriv->outBuffer[chan] = data[i];
|
devpriv->ao_readback[chan] = data[i];
|
||||||
}
|
}
|
||||||
up(&devpriv->sem);
|
up(&devpriv->sem);
|
||||||
|
|
||||||
|
@ -1462,8 +1463,8 @@ static int usbduxsigma_attach_common(struct comedi_device *dev)
|
||||||
dev->write_subdev = s;
|
dev->write_subdev = s;
|
||||||
s->type = COMEDI_SUBD_AO;
|
s->type = COMEDI_SUBD_AO;
|
||||||
s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
|
s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
|
||||||
s->n_chan = 4;
|
s->n_chan = USBDUXSIGMA_NUM_AO_CHAN;
|
||||||
s->len_chanlist = 4;
|
s->len_chanlist = s->n_chan;
|
||||||
s->maxdata = 0x00ff;
|
s->maxdata = 0x00ff;
|
||||||
s->range_table = &range_unipolar2_5;
|
s->range_table = &range_unipolar2_5;
|
||||||
s->insn_write = usbduxsigma_ao_insn_write;
|
s->insn_write = usbduxsigma_ao_insn_write;
|
||||||
|
@ -1589,14 +1590,13 @@ static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
|
||||||
devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
|
devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
|
||||||
devpriv->inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
|
devpriv->inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
|
||||||
devpriv->insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
|
devpriv->insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
|
||||||
devpriv->outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
|
|
||||||
devpriv->urbIn = kcalloc(devpriv->numOfInBuffers, sizeof(*urb),
|
devpriv->urbIn = kcalloc(devpriv->numOfInBuffers, sizeof(*urb),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
devpriv->urbOut = kcalloc(devpriv->numOfOutBuffers, sizeof(*urb),
|
devpriv->urbOut = kcalloc(devpriv->numOfOutBuffers, sizeof(*urb),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!devpriv->dac_commands || !devpriv->dux_commands ||
|
if (!devpriv->dac_commands || !devpriv->dux_commands ||
|
||||||
!devpriv->inBuffer || !devpriv->insnBuffer ||
|
!devpriv->inBuffer || !devpriv->insnBuffer ||
|
||||||
!devpriv->outBuffer || !devpriv->urbIn || !devpriv->urbOut)
|
!devpriv->urbIn || !devpriv->urbOut)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < devpriv->numOfInBuffers; i++) {
|
for (i = 0; i < devpriv->numOfInBuffers; i++) {
|
||||||
|
@ -1701,7 +1701,6 @@ static void usbduxsigma_free_usb_buffers(struct comedi_device *dev)
|
||||||
}
|
}
|
||||||
kfree(devpriv->urbIn);
|
kfree(devpriv->urbIn);
|
||||||
}
|
}
|
||||||
kfree(devpriv->outBuffer);
|
|
||||||
kfree(devpriv->insnBuffer);
|
kfree(devpriv->insnBuffer);
|
||||||
kfree(devpriv->inBuffer);
|
kfree(devpriv->inBuffer);
|
||||||
kfree(devpriv->dux_commands);
|
kfree(devpriv->dux_commands);
|
||||||
|
|
Loading…
Add table
Reference in a new issue