summaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi
diff options
context:
space:
mode:
authorH Hartley Sweeten2014-09-09 22:05:32 +0200
committerGreg Kroah-Hartman2014-09-11 23:34:24 +0200
commitf16a7b85168af1dc6621a7edb7925fca577e1017 (patch)
tree5bdac87567cc124c7a24e9b701bc6661468e0e89 /drivers/staging/comedi
parentstaging: comedi: adl_pci9118: handle error detection in main interrupt handler (diff)
downloadkernel-qcow2-linux-f16a7b85168af1dc6621a7edb7925fca577e1017.tar.gz
kernel-qcow2-linux-f16a7b85168af1dc6621a7edb7925fca577e1017.tar.xz
kernel-qcow2-linux-f16a7b85168af1dc6621a7edb7925fca577e1017.zip
staging: comedi: adl_pci9118: handle hardware errors in interrupt handler
Hardware errors will now always terminate an async command. For aesthetics, absorb pci9118_decode_error_status() into the interrupt handler and use the register map defines to remove the "magic" numbers. Refactor the code to set the appropriate comedi event bits and handle the event. Remove the unnecessary 'ai_maskerr' and 'ai_maskharderr' members from the private data. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi')
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c69
1 files changed, 27 insertions, 42 deletions
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index c10d35adb7a9..48d09de6ffc9 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -283,8 +283,6 @@ struct pci9118_private {
* polarity of S&H signal
* in hold state
*/
- unsigned int ai_maskerr; /* which warning was printed */
- unsigned int ai_maskharderr; /* on which error bits stops */
unsigned int ai_ns_min;
};
@@ -671,39 +669,6 @@ static int pci9118_ai_cancel(struct comedi_device *dev,
return 0;
}
-static char pci9118_decode_error_status(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned char m)
-{
- struct pci9118_private *devpriv = dev->private;
-
- if (m & 0x100) {
- dev_err(dev->class_dev,
- "A/D FIFO Full status (Fatal Error!)\n");
- devpriv->ai_maskerr &= ~0x100L;
- }
- if (m & 0x008) {
- dev_err(dev->class_dev,
- "A/D Burst Mode Overrun Status (Fatal Error!)\n");
- devpriv->ai_maskerr &= ~0x008L;
- }
- if (m & 0x004) {
- dev_err(dev->class_dev, "A/D Over Speed Status (Warning!)\n");
- devpriv->ai_maskerr &= ~0x004L;
- }
- if (m & 0x002) {
- dev_err(dev->class_dev, "A/D Overrun Status (Fatal Error!)\n");
- devpriv->ai_maskerr &= ~0x002L;
- }
- if (m & devpriv->ai_maskharderr) {
- s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- cfc_handle_events(dev, s);
- return 1;
- }
-
- return 0;
-}
-
static void pci9118_ai_munge(struct comedi_device *dev,
struct comedi_subdevice *s, void *data,
unsigned int num_bytes,
@@ -848,10 +813,33 @@ static irqreturn_t pci9118_interrupt(int irq, void *d)
return IRQ_HANDLED;
}
- adstat = inl(dev->iobase + PCI9118_AI_STATUS_REG) & 0x1ff;
- if (adstat & devpriv->ai_maskerr)
- if (pci9118_decode_error_status(dev, s, adstat))
- return IRQ_HANDLED;
+ adstat = inl(dev->iobase + PCI9118_AI_STATUS_REG);
+ if ((adstat & PCI9118_AI_STATUS_NFULL) == 0) {
+ dev_err(dev->class_dev,
+ "A/D FIFO Full status (Fatal Error!)\n");
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
+ cfc_handle_events(dev, s);
+ return IRQ_HANDLED;
+ }
+ if (adstat & PCI9118_AI_STATUS_BOVER) {
+ dev_err(dev->class_dev,
+ "A/D Burst Mode Overrun Status (Fatal Error!)\n");
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
+ cfc_handle_events(dev, s);
+ return IRQ_HANDLED;
+ }
+ if (adstat & PCI9118_AI_STATUS_ADOS) {
+ dev_err(dev->class_dev, "A/D Over Speed Status (Warning!)\n");
+ s->async->events |= COMEDI_CB_ERROR;
+ cfc_handle_events(dev, s);
+ return IRQ_HANDLED;
+ }
+ if (adstat & PCI9118_AI_STATUS_ADOR) {
+ dev_err(dev->class_dev, "A/D Overrun Status (Fatal Error!)\n");
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
+ cfc_handle_events(dev, s);
+ return IRQ_HANDLED;
+ }
if (!devpriv->ai_do)
return IRQ_HANDLED;
@@ -1338,7 +1326,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ai_flags = cmd->flags;
devpriv->ai_add_front = 0;
devpriv->ai_add_back = 0;
- devpriv->ai_maskerr = 0x10e;
/* prepare for start/stop conditions */
if (cmd->start_src == TRIG_EXT)
@@ -1868,8 +1855,6 @@ static int pci9118_common_attach(struct comedi_device *dev,
/* get the current state of the digital outputs */
s->state = inl(dev->iobase + PCI9118_DIO_REG) >> 4;
- devpriv->ai_maskharderr = 0x10a;
-
return 0;
}