Commit c6de95f4 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: amplc_pci230: use comedi_async 'scans_done' to detect AI EOA

Remove the private data member 'ai_scan_count' and use the comedi_async 'scans_done'
member to detect the analog input end-of-acquisition.

Use the comedi_nsamples_left() helper to work out the number of 'wake' samples in
pci230_ai_update_fifo_trigger_level() and the number of 'todo' samples actually
added to the async buffer in pci230_handle_ai().

Remove the unnecessary COMEDI_CB_OVERFLOW event for the hardware FIFO overflow
error. The COMEDI_CB_ERROR event will terminate the command.

comedi_buf_write_samples() can fail if the async buffer does not have room for
the sample. The it will set the COMEDI_CB_OVERFLOW event and return 0. Detect
this and quit trying to read and add more samples. The event will terminate the
command.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f615915e
...@@ -490,7 +490,6 @@ struct pci230_private { ...@@ -490,7 +490,6 @@ struct pci230_private {
spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */ spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */
spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */ spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */
unsigned long daqio; /* PCI230's DAQ I/O space */ unsigned long daqio; /* PCI230's DAQ I/O space */
unsigned int ai_scan_count; /* Number of AI scans remaining */
int intr_cpuid; /* ID of CPU running ISR */ int intr_cpuid; /* ID of CPU running ISR */
unsigned short hwver; /* Hardware version (for '+' models) */ unsigned short hwver; /* Hardware version (for '+' models) */
unsigned short adccon; /* ADCCON register value */ unsigned short adccon; /* ADCCON register value */
...@@ -1720,19 +1719,15 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev, ...@@ -1720,19 +1719,15 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
{ {
struct pci230_private *devpriv = dev->private; struct pci230_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd; struct comedi_cmd *cmd = &s->async->cmd;
unsigned int scanlen = cmd->scan_end_arg;
unsigned int wake; unsigned int wake;
unsigned short triglev; unsigned short triglev;
unsigned short adccon; unsigned short adccon;
if (cmd->flags & CMDF_WAKE_EOS) if (cmd->flags & CMDF_WAKE_EOS)
wake = scanlen - s->async->cur_chan; wake = cmd->scan_end_arg - s->async->cur_chan;
else if (cmd->stop_src != TRIG_COUNT ||
devpriv->ai_scan_count >= PCI230_ADC_FIFOLEVEL_HALFFULL ||
scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)
wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
else else
wake = devpriv->ai_scan_count * scanlen - s->async->cur_chan; wake = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL);
if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) { if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
triglev = PCI230_ADC_INT_FIFO_HALF; triglev = PCI230_ADC_INT_FIFO_HALF;
} else if (wake > 1 && devpriv->hwver > 0) { } else if (wake > 1 && devpriv->hwver > 0) {
...@@ -2025,8 +2020,6 @@ static void pci230_handle_ai(struct comedi_device *dev, ...@@ -2025,8 +2020,6 @@ static void pci230_handle_ai(struct comedi_device *dev,
struct pci230_private *devpriv = dev->private; struct pci230_private *devpriv = dev->private;
struct comedi_async *async = s->async; struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd; struct comedi_cmd *cmd = &async->cmd;
unsigned int scanlen = cmd->scan_end_arg;
unsigned int events = 0;
unsigned int status_fifo; unsigned int status_fifo;
unsigned int i; unsigned int i;
unsigned int todo; unsigned int todo;
...@@ -2034,20 +2027,10 @@ static void pci230_handle_ai(struct comedi_device *dev, ...@@ -2034,20 +2027,10 @@ static void pci230_handle_ai(struct comedi_device *dev,
unsigned short val; unsigned short val;
/* Determine number of samples to read. */ /* Determine number of samples to read. */
if (cmd->stop_src != TRIG_COUNT) { todo = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL);
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else if (devpriv->ai_scan_count == 0) {
todo = 0;
} else if (devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL ||
scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL) {
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else {
todo = devpriv->ai_scan_count * scanlen - async->cur_chan;
if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL)
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
}
if (todo == 0) if (todo == 0)
return; return;
fifoamount = 0; fifoamount = 0;
for (i = 0; i < todo; i++) { for (i = 0; i < todo; i++) {
if (fifoamount == 0) { if (fifoamount == 0) {
...@@ -2059,7 +2042,7 @@ static void pci230_handle_ai(struct comedi_device *dev, ...@@ -2059,7 +2042,7 @@ static void pci230_handle_ai(struct comedi_device *dev,
* unnoticed by the caller. * unnoticed by the caller.
*/ */
dev_err(dev->class_dev, "AI FIFO overrun\n"); dev_err(dev->class_dev, "AI FIFO overrun\n");
events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; async->events |= COMEDI_CB_ERROR;
break; break;
} else if (status_fifo & PCI230_ADC_FIFO_EMPTY) { } else if (status_fifo & PCI230_ADC_FIFO_EMPTY) {
/* FIFO empty. */ /* FIFO empty. */
...@@ -2080,21 +2063,21 @@ static void pci230_handle_ai(struct comedi_device *dev, ...@@ -2080,21 +2063,21 @@ static void pci230_handle_ai(struct comedi_device *dev,
} }
val = pci230_ai_read(dev); val = pci230_ai_read(dev);
comedi_buf_write_samples(s, &val, 1); if (!comedi_buf_write_samples(s, &val, 1))
break;
fifoamount--; fifoamount--;
if (async->cur_chan == 0)
devpriv->ai_scan_count--; if (cmd->stop_src == TRIG_COUNT &&
async->scans_done >= cmd->stop_arg) {
async->events |= COMEDI_CB_EOA;
break;
} }
if (cmd->stop_src == TRIG_COUNT && devpriv->ai_scan_count == 0) {
/* End of acquisition. */
events |= COMEDI_CB_EOA;
} }
async->events |= events;
if (!(async->events & COMEDI_CB_CANCEL_MASK)) { /* update FIFO interrupt trigger level if still running */
/* update FIFO interrupt trigger level */ if (!(async->events & COMEDI_CB_CANCEL_MASK))
pci230_ai_update_fifo_trigger_level(dev, s); pci230_ai_update_fifo_trigger_level(dev, s);
}
} }
static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
...@@ -2130,8 +2113,6 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ...@@ -2130,8 +2113,6 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (!pci230_claim_shared(dev, res_mask, OWNER_AICMD)) if (!pci230_claim_shared(dev, res_mask, OWNER_AICMD))
return -EBUSY; return -EBUSY;
devpriv->ai_scan_count = cmd->stop_arg;
/* /*
* Steps: * Steps:
* - Set channel scan list. * - Set channel scan list.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment