staging: comedi: pcl816: tidy up pcl818_check()
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Wed, 19 Feb 2014 17:11:31 +0000 (10:11 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Feb 2014 20:39:38 +0000 (12:39 -0800)
This function probes a number of the boards registers during the
(*attach) to verify that it is actually a PCL-816 compatible board.
For aesthetics, move the function closer to the (*attach).

To better match the pcl818 driver, allocate the private data before
calling pcl816_check().

Refactor the function to return an errno if fails. Change the errno
from -EIO to -ENODEV and remove the unnecessary dev_err() noise.

Make sure the CONTROL register is reset to a known state after the
check. The 0x18 value actually defines an invalid interrupt selection
and sets an undefined bit.

Add a couple comments to clarify the magic values.

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>
drivers/staging/comedi/drivers/pcl816.c

index aae2947281df1519cf1bdee0833dbb18afc14abc..2e383ebde11999ac66def832f93aa5594ebba9d5 100644 (file)
@@ -614,25 +614,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
        return 0;
 }
 
-static int pcl816_check(unsigned long iobase)
-{
-       outb(0x00, iobase + PCL816_MUX);
-       udelay(1);
-       if (inb(iobase + PCL816_MUX) != 0x00)
-               return 1;       /* there isn't card */
-       outb(0x55, iobase + PCL816_MUX);
-       udelay(1);
-       if (inb(iobase + PCL816_MUX) != 0x55)
-               return 1;       /* there isn't card */
-       outb(0x00, iobase + PCL816_MUX);
-       udelay(1);
-       outb(0x18, iobase + PCL816_CONTROL);
-       udelay(1);
-       if (inb(iobase + PCL816_CONTROL) != 0x18)
-               return 1;       /* there isn't card */
-       return 0;               /*  ok, card exist */
-}
-
 static void pcl816_reset(struct comedi_device *dev)
 {
        unsigned long timer_base = dev->iobase + PCL816_TIMER_BASE;
@@ -733,6 +714,30 @@ setup_channel_list(struct comedi_device *dev,
             dev->iobase + PCL816_MUX);
 }
 
+static int pcl816_check(struct comedi_device *dev)
+{
+       /* the MUX register should return the same value written */
+       outb(0x00, dev->iobase + PCL816_MUX);
+       if (inb(dev->iobase + PCL816_MUX) != 0x00)
+               return -ENODEV;
+       outb(0x55, dev->iobase + PCL816_MUX);
+       if (inb(dev->iobase + PCL816_MUX) != 0x55)
+               return -ENODEV;
+
+       /* reset the MUX register to a known state */
+       outb(0x00, dev->iobase + PCL816_MUX);
+
+       /* the CONTROL register should return the same value written */
+       outb(0x18, dev->iobase + PCL816_CONTROL);
+       if (inb(dev->iobase + PCL816_CONTROL) != 0x18)
+               return -ENODEV;
+
+       /* reset the CONTROL register to a known state */
+       outb(0x00, dev->iobase + PCL816_CONTROL);
+
+       return 0;
+}
+
 static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
        const struct pcl816_board *board = comedi_board(dev);
@@ -741,18 +746,17 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        int ret;
        int i;
 
+       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+       if (!devpriv)
+               return -ENOMEM;
+
        ret = comedi_request_region(dev, it->options[0], 0x10);
        if (ret)
                return ret;
 
-       if (pcl816_check(dev->iobase)) {
-               dev_err(dev->class_dev, "I can't detect board. FAIL!\n");
-               return -EIO;
-       }
-
-       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-       if (!devpriv)
-               return -ENOMEM;
+       ret = pcl816_check(dev);
+       if (ret)
+               return ret;
 
        /* we can use IRQ 2-7 for async command support */
        if (it->options[1] >= 2 && it->options[1] <= 7) {