Merge branch 'next/dt2' into HEAD
[cascardo/linux.git] / drivers / staging / comedi / drivers / adv_pci1710.c
index 6b4d0d6..def37bc 100644 (file)
@@ -45,6 +45,7 @@ Configuration options:
 
 #include "../comedidev.h"
 
+#include "comedi_fc.h"
 #include "8253.h"
 #include "amcc_s5933.h"
 
@@ -52,17 +53,6 @@ Configuration options:
                                 * correct channel number on every 12 bit
                                 * sample */
 
-#undef PCI171X_EXTDEBUG
-
-#define DRV_NAME "adv_pci1710"
-
-#undef DPRINTK
-#ifdef PCI171X_EXTDEBUG
-#define DPRINTK(fmt, args...) printk(fmt, ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
 #define PCI_VENDOR_ID_ADVANTECH                0x13fe
 
 /* hardware types of the cards */
@@ -211,44 +201,101 @@ struct boardtype {
 };
 
 static const struct boardtype boardtypes[] = {
-       {"pci1710", 0x1710,
-        IORANGE_171x, 1, TYPE_PCI171X,
-        16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
-        &range_pci1710_3, range_codes_pci1710_3,
-        &range_pci171x_da,
-        10000, 2048},
-       {"pci1710hg", 0x1710,
-        IORANGE_171x, 1, TYPE_PCI171X,
-        16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
-        &range_pci1710hg, range_codes_pci1710hg,
-        &range_pci171x_da,
-        10000, 2048},
-       {"pci1711", 0x1711,
-        IORANGE_171x, 1, TYPE_PCI171X,
-        16, 0, 2, 16, 16, 1, 0x0fff, 0x0fff,
-        &range_pci17x1, range_codes_pci17x1, &range_pci171x_da,
-        10000, 512},
-       {"pci1713", 0x1713,
-        IORANGE_171x, 1, TYPE_PCI1713,
-        32, 16, 0, 0, 0, 0, 0x0fff, 0x0000,
-        &range_pci1710_3, range_codes_pci1710_3, NULL,
-        10000, 2048},
-       {"pci1720", 0x1720,
-        IORANGE_1720, 0, TYPE_PCI1720,
-        0, 0, 4, 0, 0, 0, 0x0000, 0x0fff,
-        NULL, NULL, &range_pci1720,
-        0, 0},
-       {"pci1731", 0x1731,
-        IORANGE_171x, 1, TYPE_PCI171X,
-        16, 0, 0, 16, 16, 0, 0x0fff, 0x0000,
-        &range_pci17x1, range_codes_pci17x1, NULL,
-        10000, 512},
-       /*  dummy entry corresponding to driver name */
-       {.name = DRV_NAME},
+       {
+               .name           = "pci1710",
+               .device_id      = 0x1710,
+               .iorange        = IORANGE_171x,
+               .have_irq       = 1,
+               .cardtype       = TYPE_PCI171X,
+               .n_aichan       = 16,
+               .n_aichand      = 8,
+               .n_aochan       = 2,
+               .n_dichan       = 16,
+               .n_dochan       = 16,
+               .n_counter      = 1,
+               .ai_maxdata     = 0x0fff,
+               .ao_maxdata     = 0x0fff,
+               .rangelist_ai   = &range_pci1710_3,
+               .rangecode_ai   = range_codes_pci1710_3,
+               .rangelist_ao   = &range_pci171x_da,
+               .ai_ns_min      = 10000,
+               .fifo_half_size = 2048,
+       }, {
+               .name           = "pci1710hg",
+               .device_id      = 0x1710,
+               .iorange        = IORANGE_171x,
+               .have_irq       = 1,
+               .cardtype       = TYPE_PCI171X,
+               .n_aichan       = 16,
+               .n_aichand      = 8,
+               .n_aochan       = 2,
+               .n_dichan       = 16,
+               .n_dochan       = 16,
+               .n_counter      = 1,
+               .ai_maxdata     = 0x0fff,
+               .ao_maxdata     = 0x0fff,
+               .rangelist_ai   = &range_pci1710hg,
+               .rangecode_ai   = range_codes_pci1710hg,
+               .rangelist_ao   = &range_pci171x_da,
+               .ai_ns_min      = 10000,
+               .fifo_half_size = 2048,
+       }, {
+               .name           = "pci1711",
+               .device_id      = 0x1711,
+               .iorange        = IORANGE_171x,
+               .have_irq       = 1,
+               .cardtype       = TYPE_PCI171X,
+               .n_aichan       = 16,
+               .n_aochan       = 2,
+               .n_dichan       = 16,
+               .n_dochan       = 16,
+               .n_counter      = 1,
+               .ai_maxdata     = 0x0fff,
+               .ao_maxdata     = 0x0fff,
+               .rangelist_ai   = &range_pci17x1,
+               .rangecode_ai   = range_codes_pci17x1,
+               .rangelist_ao   = &range_pci171x_da,
+               .ai_ns_min      = 10000,
+               .fifo_half_size = 512,
+       }, {
+               .name           = "pci1713",
+               .device_id      = 0x1713,
+               .iorange        = IORANGE_171x,
+               .have_irq       = 1,
+               .cardtype       = TYPE_PCI1713,
+               .n_aichan       = 32,
+               .n_aichand      = 16,
+               .ai_maxdata     = 0x0fff,
+               .rangelist_ai   = &range_pci1710_3,
+               .rangecode_ai   = range_codes_pci1710_3,
+               .ai_ns_min      = 10000,
+               .fifo_half_size = 2048,
+       }, {
+               .name           = "pci1720",
+               .device_id      = 0x1720,
+               .iorange        = IORANGE_1720,
+               .cardtype       = TYPE_PCI1720,
+               .n_aochan       = 4,
+               .ao_maxdata     = 0x0fff,
+               .rangelist_ao   = &range_pci1720,
+       }, {
+               .name           = "pci1731",
+               .device_id      = 0x1731,
+               .iorange        = IORANGE_171x,
+               .have_irq       = 1,
+               .cardtype       = TYPE_PCI171X,
+               .n_aichan       = 16,
+               .n_dichan       = 16,
+               .n_dochan       = 16,
+               .ai_maxdata     = 0x0fff,
+               .rangelist_ai   = &range_pci17x1,
+               .rangecode_ai   = range_codes_pci17x1,
+               .ai_ns_min      = 10000,
+               .fifo_half_size = 512,
+       },
 };
 
 struct pci1710_private {
-       char valid;             /*  card is usable */
        char neverending_ai;    /*  we do unlimited AI */
        unsigned int CntrlReg;  /*  Control register */
        unsigned int i8254_osc_base;    /*  frequence of onboard oscilator */
@@ -278,33 +325,108 @@ struct pci1710_private {
                                         * internal state */
 };
 
-#define devpriv ((struct pci1710_private *)dev->private)
-#define this_board ((const struct boardtype *)dev->board_ptr)
+/*  used for gain list programming */
+static const unsigned int muxonechan[] = {
+       0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,
+       0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
+       0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
+       0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
+};
 
 /*
 ==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic.
+ This works for all cards.
 */
-
 static int check_channel_list(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             unsigned int *chanlist, unsigned int n_chan);
+                             unsigned int *chanlist, unsigned int n_chan)
+{
+       unsigned int chansegment[32];
+       unsigned int i, nowmustbechan, seglen, segpos;
+
+       /* correct channel and range number check itself comedi/range.c */
+       if (n_chan < 1) {
+               comedi_error(dev, "range/channel list is empty!");
+               return 0;
+       }
+
+       if (n_chan == 1)
+               return 1; /* seglen=1 */
+
+       chansegment[0] = chanlist[0]; /*  first channel is every time ok */
+       for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {
+               if (chanlist[0] == chanlist[i])
+                       break;  /*  we detected a loop, stop */
+               if ((CR_CHAN(chanlist[i]) & 1) &&
+                   (CR_AREF(chanlist[i]) == AREF_DIFF)) {
+                       comedi_error(dev, "Odd channel cannot be differential input!\n");
+                       return 0;
+               }
+               nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
+               if (CR_AREF(chansegment[i - 1]) == AREF_DIFF)
+                       nowmustbechan = (nowmustbechan + 1) % s->n_chan;
+               if (nowmustbechan != CR_CHAN(chanlist[i])) {
+                       printk("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
+                              i, CR_CHAN(chanlist[i]), nowmustbechan,
+                              CR_CHAN(chanlist[0]));
+                       return 0;
+               }
+               chansegment[i] = chanlist[i]; /* next correct channel in list */
+       }
+
+       for (i = 0, segpos = 0; i < n_chan; i++) {
+               if (chanlist[i] != chansegment[i % seglen]) {
+                       printk("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+                              i, CR_CHAN(chansegment[i]),
+                              CR_RANGE(chansegment[i]),
+                              CR_AREF(chansegment[i]),
+                              CR_CHAN(chanlist[i % seglen]),
+                              CR_RANGE(chanlist[i % seglen]),
+                              CR_AREF(chansegment[i % seglen]));
+                       return 0;
+               }
+       }
+       return seglen;
+}
+
 static void setup_channel_list(struct comedi_device *dev,
                               struct comedi_subdevice *s,
                               unsigned int *chanlist, unsigned int n_chan,
-                              unsigned int seglen);
-static void start_pacer(struct comedi_device *dev, int mode,
-                       unsigned int divisor1, unsigned int divisor2);
-static int pci1710_reset(struct comedi_device *dev);
-static int pci171x_ai_cancel(struct comedi_device *dev,
-                            struct comedi_subdevice *s);
+                              unsigned int seglen)
+{
+       const struct boardtype *this_board = comedi_board(dev);
+       struct pci1710_private *devpriv = dev->private;
+       unsigned int i, range, chanprog;
 
-/*  used for gain list programming */
-static const unsigned int muxonechan[] = {
-       0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,
-       0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
-       0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
-       0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
-};
+       devpriv->act_chanlist_len = seglen;
+       devpriv->act_chanlist_pos = 0;
+
+       for (i = 0; i < seglen; i++) {  /*  store range list to card */
+               chanprog = muxonechan[CR_CHAN(chanlist[i])];
+               outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */
+               range = this_board->rangecode_ai[CR_RANGE(chanlist[i])];
+               if (CR_AREF(chanlist[i]) == AREF_DIFF)
+                       range |= 0x0020;
+               outw(range, dev->iobase + PCI171x_RANGE); /* select gain */
+#ifdef PCI171x_PARANOIDCHECK
+               devpriv->act_chanlist[i] =
+                       (CR_CHAN(chanlist[i]) << 12) & 0xf000;
+#endif
+       }
+#ifdef PCI171x_PARANOIDCHECK
+       for ( ; i < n_chan; i++) { /* store remainder of channel list */
+               devpriv->act_chanlist[i] =
+                       (CR_CHAN(chanlist[i]) << 12) & 0xf000;
+       }
+#endif
+
+       devpriv->ai_et_MuxVal =
+               CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
+       /* select channel interval to scan */
+       outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);
+}
 
 /*
 ==============================================================================
@@ -313,12 +435,13 @@ static int pci171x_insn_read_ai(struct comedi_device *dev,
                                struct comedi_subdevice *s,
                                struct comedi_insn *insn, unsigned int *data)
 {
+       struct pci1710_private *devpriv = dev->private;
        int n, timeout;
 #ifdef PCI171x_PARANOIDCHECK
+       const struct boardtype *this_board = comedi_board(dev);
        unsigned int idata;
 #endif
 
-       DPRINTK("adv_pci1710 EDBG: BGN: pci171x_insn_read_ai(...)\n");
        devpriv->CntrlReg &= Control_CNT0;
        devpriv->CntrlReg |= Control_SW;        /*  set software trigger */
        outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
@@ -327,32 +450,18 @@ static int pci171x_insn_read_ai(struct comedi_device *dev,
 
        setup_channel_list(dev, s, &insn->chanspec, 1, 1);
 
-       DPRINTK("adv_pci1710 A ST=%4x IO=%x\n",
-               inw(dev->iobase + PCI171x_STATUS),
-               dev->iobase + PCI171x_STATUS);
        for (n = 0; n < insn->n; n++) {
                outw(0, dev->iobase + PCI171x_SOFTTRG); /* start conversion */
-               DPRINTK("adv_pci1710 B n=%d ST=%4x\n", n,
-                       inw(dev->iobase + PCI171x_STATUS));
                /* udelay(1); */
-               DPRINTK("adv_pci1710 C n=%d ST=%4x\n", n,
-                       inw(dev->iobase + PCI171x_STATUS));
                timeout = 100;
                while (timeout--) {
                        if (!(inw(dev->iobase + PCI171x_STATUS) & Status_FE))
                                goto conv_finish;
-                       if (!(timeout % 10))
-                               DPRINTK("adv_pci1710 D n=%d tm=%d ST=%4x\n", n,
-                                       timeout,
-                                       inw(dev->iobase + PCI171x_STATUS));
                }
                comedi_error(dev, "A/D insn timeout");
                outb(0, dev->iobase + PCI171x_CLRFIFO);
                outb(0, dev->iobase + PCI171x_CLRINT);
                data[n] = 0;
-               DPRINTK
-                   ("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n",
-                    n);
                return -ETIME;
 
 conv_finish:
@@ -373,7 +482,6 @@ conv_finish:
        outb(0, dev->iobase + PCI171x_CLRFIFO);
        outb(0, dev->iobase + PCI171x_CLRINT);
 
-       DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n);
        return n;
 }
 
@@ -384,6 +492,7 @@ static int pci171x_insn_write_ao(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
                                 struct comedi_insn *insn, unsigned int *data)
 {
+       struct pci1710_private *devpriv = dev->private;
        int n, chan, range, ofs;
 
        chan = CR_CHAN(insn->chanspec);
@@ -416,6 +525,7 @@ static int pci171x_insn_read_ao(struct comedi_device *dev,
                                struct comedi_subdevice *s,
                                struct comedi_insn *insn, unsigned int *data)
 {
+       struct pci1710_private *devpriv = dev->private;
        int n, chan;
 
        chan = CR_CHAN(insn->chanspec);
@@ -454,6 +564,23 @@ static int pci171x_insn_bits_do(struct comedi_device *dev,
        return insn->n;
 }
 
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device *dev, int mode,
+                       unsigned int divisor1, unsigned int divisor2)
+{
+       outw(0xb4, dev->iobase + PCI171x_CNTCTRL);
+       outw(0x74, dev->iobase + PCI171x_CNTCTRL);
+
+       if (mode == 1) {
+               outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2);
+               outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2);
+               outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1);
+               outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1);
+       }
+}
+
 /*
 ==============================================================================
 */
@@ -486,6 +613,7 @@ static int pci171x_insn_counter_write(struct comedi_device *dev,
                                      struct comedi_insn *insn,
                                      unsigned int *data)
 {
+       struct pci1710_private *devpriv = dev->private;
        uint msb, lsb, ccntrl, status;
 
        lsb = data[0] & 0x00FF;
@@ -517,6 +645,7 @@ static int pci171x_insn_counter_config(struct comedi_device *dev,
 {
 #ifdef unused
        /* This doesn't work like a normal Comedi counter config */
+       struct pci1710_private *devpriv = dev->private;
        uint ccntrl = 0;
 
        devpriv->cnt0_write_wait = data[0] & 0x20;
@@ -552,6 +681,7 @@ static int pci1720_insn_write_ao(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
                                 struct comedi_insn *insn, unsigned int *data)
 {
+       struct pci1710_private *devpriv = dev->private;
        int n, rangereg, chan;
 
        chan = CR_CHAN(insn->chanspec);
@@ -572,19 +702,50 @@ static int pci1720_insn_write_ao(struct comedi_device *dev,
        return n;
 }
 
+/*
+==============================================================================
+*/
+static int pci171x_ai_cancel(struct comedi_device *dev,
+                            struct comedi_subdevice *s)
+{
+       const struct boardtype *this_board = comedi_board(dev);
+       struct pci1710_private *devpriv = dev->private;
+
+       switch (this_board->cardtype) {
+       default:
+               devpriv->CntrlReg &= Control_CNT0;
+               devpriv->CntrlReg |= Control_SW;
+
+               outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /*  reset any operations */
+               start_pacer(dev, -1, 0, 0);
+               outb(0, dev->iobase + PCI171x_CLRFIFO);
+               outb(0, dev->iobase + PCI171x_CLRINT);
+               break;
+       }
+
+       devpriv->ai_do = 0;
+       devpriv->ai_act_scan = 0;
+       s->async->cur_chan = 0;
+       devpriv->ai_buf_ptr = 0;
+       devpriv->neverending_ai = 0;
+
+       return 0;
+}
+
 /*
 ==============================================================================
 */
 static void interrupt_pci1710_every_sample(void *d)
 {
        struct comedi_device *dev = d;
-       struct comedi_subdevice *s = dev->subdevices + 0;
+       struct pci1710_private *devpriv = dev->private;
+       struct comedi_subdevice *s = &dev->subdevices[0];
        int m;
 #ifdef PCI171x_PARANOIDCHECK
+       const struct boardtype *this_board = comedi_board(dev);
        short sampl;
 #endif
 
-       DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_every_sample(...)\n");
        m = inw(dev->iobase + PCI171x_STATUS);
        if (m & Status_FE) {
                printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m);
@@ -605,11 +766,9 @@ static void interrupt_pci1710_every_sample(void *d)
 
        outb(0, dev->iobase + PCI171x_CLRINT);  /*  clear our INT request */
 
-       DPRINTK("FOR ");
        for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) {
 #ifdef PCI171x_PARANOIDCHECK
                sampl = inw(dev->iobase + PCI171x_AD_DATA);
-               DPRINTK("%04x:", sampl);
                if (this_board->cardtype != TYPE_PCI1713)
                        if ((sampl & 0xf000) !=
                            devpriv->act_chanlist[s->async->cur_chan]) {
@@ -626,8 +785,6 @@ static void interrupt_pci1710_every_sample(void *d)
                                comedi_event(dev, s);
                                return;
                        }
-               DPRINTK("%8d %2d %8d~", s->async->buf_int_ptr,
-                       s->async->cur_chan, s->async->buf_int_count);
                comedi_buf_put(s->async, sampl & 0x0fff);
 #else
                comedi_buf_put(s->async,
@@ -641,11 +798,6 @@ static void interrupt_pci1710_every_sample(void *d)
 
                if (s->async->cur_chan == 0) {  /*  one scan done */
                        devpriv->ai_act_scan++;
-                       DPRINTK
-                           ("adv_pci1710 EDBG: EOS1 bic %d bip %d buc %d bup %d\n",
-                            s->async->buf_int_count, s->async->buf_int_ptr,
-                            s->async->buf_user_count, s->async->buf_user_ptr);
-                       DPRINTK("adv_pci1710 EDBG: EOS2\n");
                        if ((!devpriv->neverending_ai) &&
                            (devpriv->ai_act_scan >= devpriv->ai_scans)) {
                                /*  all data sampled */
@@ -658,7 +810,6 @@ static void interrupt_pci1710_every_sample(void *d)
        }
 
        outb(0, dev->iobase + PCI171x_CLRINT);  /*  clear our INT request */
-       DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_every_sample(...)\n");
 
        comedi_event(dev, s);
 }
@@ -669,12 +820,13 @@ static void interrupt_pci1710_every_sample(void *d)
 static int move_block_from_fifo(struct comedi_device *dev,
                                struct comedi_subdevice *s, int n, int turn)
 {
+       struct pci1710_private *devpriv = dev->private;
        int i, j;
 #ifdef PCI171x_PARANOIDCHECK
+       const struct boardtype *this_board = comedi_board(dev);
        int sampl;
 #endif
-       DPRINTK("adv_pci1710 EDBG: BGN: move_block_from_fifo(...,%d,%d)\n", n,
-               turn);
+
        j = s->async->cur_chan;
        for (i = 0; i < n; i++) {
 #ifdef PCI171x_PARANOIDCHECK
@@ -705,7 +857,6 @@ static int move_block_from_fifo(struct comedi_device *dev,
                }
        }
        s->async->cur_chan = j;
-       DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
        return 0;
 }
 
@@ -715,10 +866,11 @@ static int move_block_from_fifo(struct comedi_device *dev,
 static void interrupt_pci1710_half_fifo(void *d)
 {
        struct comedi_device *dev = d;
-       struct comedi_subdevice *s = dev->subdevices + 0;
+       const struct boardtype *this_board = comedi_board(dev);
+       struct pci1710_private *devpriv = dev->private;
+       struct comedi_subdevice *s = &dev->subdevices[0];
        int m, samplesinbuf;
 
-       DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_half_fifo(...)\n");
        m = inw(dev->iobase + PCI171x_STATUS);
        if (!(m & Status_FH)) {
                printk("comedi%d: A/D FIFO not half full! (%4x)\n",
@@ -760,7 +912,6 @@ static void interrupt_pci1710_half_fifo(void *d)
                        return;
                }
        outb(0, dev->iobase + PCI171x_CLRINT);  /*  clear our INT request */
-       DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_half_fifo(...)\n");
 
        comedi_event(dev, s);
 }
@@ -771,18 +922,14 @@ static void interrupt_pci1710_half_fifo(void *d)
 static irqreturn_t interrupt_service_pci1710(int irq, void *d)
 {
        struct comedi_device *dev = d;
+       struct pci1710_private *devpriv = dev->private;
 
-       DPRINTK("adv_pci1710 EDBG: BGN: interrupt_service_pci1710(%d,...)\n",
-               irq);
        if (!dev->attached)     /*  is device attached? */
                return IRQ_NONE;        /*  no, exit */
        /*  is this interrupt from our board? */
        if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ))
                return IRQ_NONE;        /*  no, exit */
 
-       DPRINTK("adv_pci1710 EDBG: interrupt_service_pci1710() ST: %4x\n",
-               inw(dev->iobase + PCI171x_STATUS));
-
        if (devpriv->ai_et) {   /*  Switch from initial TRIG_EXT to TRIG_xxx. */
                devpriv->ai_et = 0;
                devpriv->CntrlReg &= Control_CNT0;
@@ -802,7 +949,6 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d)
        } else {
                interrupt_pci1710_half_fifo(d);
        }
-       DPRINTK("adv_pci1710 EDBG: END: interrupt_service_pci1710(...)\n");
        return IRQ_HANDLED;
 }
 
@@ -812,11 +958,11 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d)
 static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
                                     struct comedi_subdevice *s)
 {
+       const struct boardtype *this_board = comedi_board(dev);
+       struct pci1710_private *devpriv = dev->private;
        unsigned int divisor1 = 0, divisor2 = 0;
        unsigned int seglen;
 
-       DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_docmd_and_mode(%d,...)\n",
-               mode);
        start_pacer(dev, -1, 0, 0);     /*  stop pacer */
 
        seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
@@ -869,10 +1015,6 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
                i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
                                          &divisor2, &devpriv->ai_timer1,
                                          devpriv->ai_flags & TRIG_ROUND_MASK);
-               DPRINTK
-                   ("adv_pci1710 EDBG: OSC base=%u div1=%u div2=%u timer=%u\n",
-                    devpriv->i8254_osc_base, divisor1, divisor2,
-                    devpriv->ai_timer1);
                outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
                if (mode != 2) {
                        /*  start pacer */
@@ -888,27 +1030,9 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
                break;
        }
 
-       DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_docmd_and_mode(...)\n");
        return 0;
 }
 
-#ifdef PCI171X_EXTDEBUG
-/*
-==============================================================================
-*/
-static void pci171x_cmdtest_out(int e, struct comedi_cmd *cmd)
-{
-       printk("adv_pci1710 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
-              cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
-       printk("adv_pci1710 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
-              cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
-       printk("adv_pci1710 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
-              cmd->scan_end_src);
-       printk("adv_pci1710 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",
-              e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
-}
-#endif
-
 /*
 ==============================================================================
 */
@@ -916,83 +1040,33 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
                              struct comedi_subdevice *s,
                              struct comedi_cmd *cmd)
 {
+       const struct boardtype *this_board = comedi_board(dev);
+       struct pci1710_private *devpriv = dev->private;
        int err = 0;
        int tmp;
        unsigned int divisor1 = 0, divisor2 = 0;
 
-       DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...)\n");
-#ifdef PCI171X_EXTDEBUG
-       pci171x_cmdtest_out(-1, cmd);
-#endif
-       /* step 1: make sure trigger sources are trivially valid */
+       /* Step 1 : check if triggers are trivially valid */
 
-       tmp = cmd->start_src;
-       cmd->start_src &= TRIG_NOW | TRIG_EXT;
-       if (!cmd->start_src || tmp != cmd->start_src)
-               err++;
-
-       tmp = cmd->scan_begin_src;
-       cmd->scan_begin_src &= TRIG_FOLLOW;
-       if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
-               err++;
+       err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
+       err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
+       err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
+       err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+       err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 
-       tmp = cmd->convert_src;
-       cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
-       if (!cmd->convert_src || tmp != cmd->convert_src)
-               err++;
-
-       tmp = cmd->scan_end_src;
-       cmd->scan_end_src &= TRIG_COUNT;
-       if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
-               err++;
-
-       tmp = cmd->stop_src;
-       cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
-       if (!cmd->stop_src || tmp != cmd->stop_src)
-               err++;
-
-       if (err) {
-#ifdef PCI171X_EXTDEBUG
-               pci171x_cmdtest_out(1, cmd);
-#endif
-               DPRINTK(
-               "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n",
-               err);
+       if (err)
                return 1;
-       }
-
-       /* step2: make sure trigger srcs are unique and mutually compatible */
-
-       if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
-               cmd->start_src = TRIG_NOW;
-               err++;
-       }
 
-       if (cmd->scan_begin_src != TRIG_FOLLOW) {
-               cmd->scan_begin_src = TRIG_FOLLOW;
-               err++;
-       }
+       /* step 2a: make sure trigger sources are unique */
 
-       if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
-               err++;
+       err |= cfc_check_trigger_is_unique(cmd->start_src);
+       err |= cfc_check_trigger_is_unique(cmd->convert_src);
+       err |= cfc_check_trigger_is_unique(cmd->stop_src);
 
-       if (cmd->scan_end_src != TRIG_COUNT) {
-               cmd->scan_end_src = TRIG_COUNT;
-               err++;
-       }
-
-       if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
-               err++;
+       /* step 2b: and mutually compatible */
 
-       if (err) {
-#ifdef PCI171X_EXTDEBUG
-               pci171x_cmdtest_out(2, cmd);
-#endif
-               DPRINTK(
-               "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n",
-               err);
+       if (err)
                return 2;
-       }
 
        /* step 3: make sure arguments are trivially compatible */
 
@@ -1034,15 +1108,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
                }
        }
 
-       if (err) {
-#ifdef PCI171X_EXTDEBUG
-               pci171x_cmdtest_out(3, cmd);
-#endif
-               DPRINTK(
-               "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n",
-               err);
+       if (err)
                return 3;
-       }
 
        /* step 4: fix up any arguments */
 
@@ -1057,12 +1124,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
                        err++;
        }
 
-       if (err) {
-               DPRINTK
-                   ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n",
-                    err);
+       if (err)
                return 4;
-       }
 
        /* step 5: complain about special chanlist considerations */
 
@@ -1072,7 +1135,6 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
                        return 5;       /*  incorrect channels list */
        }
 
-       DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) ret=0\n");
        return 0;
 }
 
@@ -1081,9 +1143,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
 */
 static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
+       struct pci1710_private *devpriv = dev->private;
        struct comedi_cmd *cmd = &s->async->cmd;
 
-       DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmd(...)\n");
        devpriv->ai_n_chan = cmd->chanlist_len;
        devpriv->ai_chanlist = cmd->chanlist;
        devpriv->ai_flags = cmd->flags;
@@ -1113,164 +1175,14 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        return -1;
 }
 
-/*
-==============================================================================
- Check if channel list from user is builded correctly
- If it's ok, then program scan/gain logic.
- This works for all cards.
-*/
-static int check_channel_list(struct comedi_device *dev,
-                             struct comedi_subdevice *s,
-                             unsigned int *chanlist, unsigned int n_chan)
-{
-       unsigned int chansegment[32];
-       unsigned int i, nowmustbechan, seglen, segpos;
-
-       DPRINTK("adv_pci1710 EDBG:  check_channel_list(...,%d)\n", n_chan);
-       /* correct channel and range number check itself comedi/range.c */
-       if (n_chan < 1) {
-               comedi_error(dev, "range/channel list is empty!");
-               return 0;
-       }
-
-       if (n_chan == 1)
-               return 1; /* seglen=1 */
-
-       chansegment[0] = chanlist[0]; /*  first channel is every time ok */
-       for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {
-               if (chanlist[0] == chanlist[i])
-                       break;  /*  we detected a loop, stop */
-               if ((CR_CHAN(chanlist[i]) & 1) &&
-                   (CR_AREF(chanlist[i]) == AREF_DIFF)) {
-                       comedi_error(dev, "Odd channel cannot be differential input!\n");
-                       return 0;
-               }
-               nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
-               if (CR_AREF(chansegment[i - 1]) == AREF_DIFF)
-                       nowmustbechan = (nowmustbechan + 1) % s->n_chan;
-               if (nowmustbechan != CR_CHAN(chanlist[i])) {
-                       printk("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
-                              i, CR_CHAN(chanlist[i]), nowmustbechan,
-                              CR_CHAN(chanlist[0]));
-                       return 0;
-               }
-               chansegment[i] = chanlist[i]; /* next correct channel in list */
-       }
-
-       for (i = 0, segpos = 0; i < n_chan; i++) {
-               if (chanlist[i] != chansegment[i % seglen]) {
-                       printk("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
-                              i, CR_CHAN(chansegment[i]),
-                              CR_RANGE(chansegment[i]),
-                              CR_AREF(chansegment[i]),
-                              CR_CHAN(chanlist[i % seglen]),
-                              CR_RANGE(chanlist[i % seglen]),
-                              CR_AREF(chansegment[i % seglen]));
-                       return 0;
-               }
-       }
-       return seglen;
-}
-
-static void setup_channel_list(struct comedi_device *dev,
-                              struct comedi_subdevice *s,
-                              unsigned int *chanlist, unsigned int n_chan,
-                              unsigned int seglen)
-{
-       unsigned int i, range, chanprog;
-
-       DPRINTK("adv_pci1710 EDBG:  setup_channel_list(...,%d,%d)\n", n_chan,
-               seglen);
-       devpriv->act_chanlist_len = seglen;
-       devpriv->act_chanlist_pos = 0;
-
-       DPRINTK("SegLen: %d\n", seglen);
-       for (i = 0; i < seglen; i++) {  /*  store range list to card */
-               chanprog = muxonechan[CR_CHAN(chanlist[i])];
-               outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */
-               range = this_board->rangecode_ai[CR_RANGE(chanlist[i])];
-               if (CR_AREF(chanlist[i]) == AREF_DIFF)
-                       range |= 0x0020;
-               outw(range, dev->iobase + PCI171x_RANGE); /* select gain */
-#ifdef PCI171x_PARANOIDCHECK
-               devpriv->act_chanlist[i] =
-                       (CR_CHAN(chanlist[i]) << 12) & 0xf000;
-#endif
-               DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
-                       devpriv->act_chanlist[i]);
-       }
-#ifdef PCI171x_PARANOIDCHECK
-       for ( ; i < n_chan; i++) { /* store remainder of channel list */
-               devpriv->act_chanlist[i] =
-                       (CR_CHAN(chanlist[i]) << 12) & 0xf000;
-       }
-#endif
-
-       devpriv->ai_et_MuxVal =
-               CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
-       /* select channel interval to scan */
-       outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);
-       DPRINTK("MUX: %4x L%4x.H%4x\n",
-               CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8),
-               CR_CHAN(chanlist[0]), CR_CHAN(chanlist[seglen - 1]));
-}
-
-/*
-==============================================================================
-*/
-static void start_pacer(struct comedi_device *dev, int mode,
-                       unsigned int divisor1, unsigned int divisor2)
-{
-       DPRINTK("adv_pci1710 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode,
-               divisor1, divisor2);
-       outw(0xb4, dev->iobase + PCI171x_CNTCTRL);
-       outw(0x74, dev->iobase + PCI171x_CNTCTRL);
-
-       if (mode == 1) {
-               outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2);
-               outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2);
-               outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1);
-               outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1);
-       }
-       DPRINTK("adv_pci1710 EDBG: END: start_pacer(...)\n");
-}
-
-/*
-==============================================================================
-*/
-static int pci171x_ai_cancel(struct comedi_device *dev,
-                            struct comedi_subdevice *s)
-{
-       DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cancel(...)\n");
-
-       switch (this_board->cardtype) {
-       default:
-               devpriv->CntrlReg &= Control_CNT0;
-               devpriv->CntrlReg |= Control_SW;
-
-               outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /*  reset any operations */
-               start_pacer(dev, -1, 0, 0);
-               outb(0, dev->iobase + PCI171x_CLRFIFO);
-               outb(0, dev->iobase + PCI171x_CLRINT);
-               break;
-       }
-
-       devpriv->ai_do = 0;
-       devpriv->ai_act_scan = 0;
-       s->async->cur_chan = 0;
-       devpriv->ai_buf_ptr = 0;
-       devpriv->neverending_ai = 0;
-
-       DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_cancel(...)\n");
-       return 0;
-}
-
 /*
 ==============================================================================
 */
 static int pci171x_reset(struct comedi_device *dev)
 {
-       DPRINTK("adv_pci1710 EDBG: BGN: pci171x_reset(...)\n");
+       const struct boardtype *this_board = comedi_board(dev);
+       struct pci1710_private *devpriv = dev->private;
+
        outw(0x30, dev->iobase + PCI171x_CNTCTRL);
        devpriv->CntrlReg = Control_SW | Control_CNT0;  /*  Software trigger, CNT0=external */
        outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /*  reset any operations */
@@ -1291,7 +1203,6 @@ static int pci171x_reset(struct comedi_device *dev)
        outb(0, dev->iobase + PCI171x_CLRFIFO); /*  clear FIFO */
        outb(0, dev->iobase + PCI171x_CLRINT);  /*  clear INT request */
 
-       DPRINTK("adv_pci1710 EDBG: END: pci171x_reset(...)\n");
        return 0;
 }
 
@@ -1300,7 +1211,8 @@ static int pci171x_reset(struct comedi_device *dev)
 */
 static int pci1720_reset(struct comedi_device *dev)
 {
-       DPRINTK("adv_pci1710 EDBG: BGN: pci1720_reset(...)\n");
+       struct pci1710_private *devpriv = dev->private;
+
        outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT);       /*  set synchronous output mode */
        devpriv->da_ranges = 0xAA;
        outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE);  /*  set all ranges to +/-5V */
@@ -1313,7 +1225,6 @@ static int pci1720_reset(struct comedi_device *dev)
        devpriv->ao_data[1] = 0x0800;
        devpriv->ao_data[2] = 0x0800;
        devpriv->ao_data[3] = 0x0800;
-       DPRINTK("adv_pci1710 EDBG: END: pci1720_reset(...)\n");
        return 0;
 }
 
@@ -1322,82 +1233,55 @@ static int pci1720_reset(struct comedi_device *dev)
 */
 static int pci1710_reset(struct comedi_device *dev)
 {
-       DPRINTK("adv_pci1710 EDBG: BGN: pci1710_reset(...)\n");
+       const struct boardtype *this_board = comedi_board(dev);
+
        switch (this_board->cardtype) {
        case TYPE_PCI1720:
                return pci1720_reset(dev);
        default:
                return pci171x_reset(dev);
        }
-       DPRINTK("adv_pci1710 EDBG: END: pci1710_reset(...)\n");
 }
 
-static struct pci_dev *pci1710_find_pci_dev(struct comedi_device *dev,
-                                           struct comedi_devconfig *it)
+static const void *pci1710_find_boardinfo(struct comedi_device *dev,
+                                         struct pci_dev *pcidev)
 {
-       struct pci_dev *pcidev = NULL;
-       int bus = it->options[0];
-       int slot = it->options[1];
-       int board_index = this_board - boardtypes;
+       const struct boardtype *this_board;
        int i;
 
-       for_each_pci_dev(pcidev) {
-               if (bus || slot) {
-                       if (bus != pcidev->bus->number ||
-                           slot != PCI_SLOT(pcidev->devfn))
-                               continue;
-               }
-               if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH)
-                       continue;
-               if (strcmp(this_board->name, DRV_NAME) == 0) {
-                       for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) {
-                               if (pcidev->device == boardtypes[i].device_id) {
-                                       board_index = i;
-                                       break;
-                               }
-                       }
-                       if (i == ARRAY_SIZE(boardtypes))
-                               continue;
-               } else {
-                       if (pcidev->device != boardtypes[board_index].device_id)
-                               continue;
-               }
-               dev->board_ptr = &boardtypes[board_index];
-               return pcidev;
+       for (i = 0; i < ARRAY_SIZE(boardtypes); i++) {
+               this_board = &boardtypes[i];
+               if (pcidev->device == this_board->device_id)
+                       return this_board;
        }
-       dev_err(dev->class_dev,
-               "No supported board found! (req. bus %d, slot %d)\n",
-               bus, slot);
        return NULL;
 }
 
-static int pci1710_attach(struct comedi_device *dev,
-                         struct comedi_devconfig *it)
+static int pci1710_attach_pci(struct comedi_device *dev,
+                             struct pci_dev *pcidev)
 {
-       struct pci_dev *pcidev;
+       const struct boardtype *this_board;
+       struct pci1710_private *devpriv;
        struct comedi_subdevice *s;
        int ret, subdev, n_subdevices;
-       unsigned int irq;
 
-       dev_info(dev->class_dev, DRV_NAME ": attach\n");
+       comedi_set_hw_dev(dev, &pcidev->dev);
 
-       ret = alloc_private(dev, sizeof(struct pci1710_private));
-       if (ret < 0)
-               return -ENOMEM;
+       this_board = pci1710_find_boardinfo(dev, pcidev);
+       if (!this_board)
+               return -ENODEV;
+       dev->board_ptr = this_board;
+       dev->board_name = this_board->name;
 
-       pcidev = pci1710_find_pci_dev(dev, it);
-       if (!pcidev)
-               return -EIO;
-       comedi_set_hw_dev(dev, &pcidev->dev);
+       ret = alloc_private(dev, sizeof(*devpriv));
+       if (ret < 0)
+               return ret;
+       devpriv = dev->private;
 
-       ret = comedi_pci_enable(pcidev, DRV_NAME);
+       ret = comedi_pci_enable(pcidev, dev->board_name);
        if (ret)
                return ret;
-
        dev->iobase = pci_resource_start(pcidev, 2);
-       irq = pcidev->irq;
-
-       dev->board_name = this_board->name;
 
        n_subdevices = 0;
        if (this_board->n_aichan)
@@ -1417,30 +1301,17 @@ static int pci1710_attach(struct comedi_device *dev,
 
        pci1710_reset(dev);
 
-       if (this_board->have_irq) {
-               if (irq) {
-                       if (request_irq(irq, interrupt_service_pci1710,
-                                       IRQF_SHARED, "Advantech PCI-1710",
-                                       dev)) {
-                               dev_dbg(dev->class_dev,
-                                       "unable to allocate IRQ %d, DISABLING IT",
-                                       irq);
-                               irq = 0;        /* Can't use IRQ */
-                       } else {
-                               dev_dbg(dev->class_dev, "irq=%u", irq);
-                       }
-               } else {
-                       dev_dbg(dev->class_dev, "IRQ disabled");
-               }
-       } else {
-               irq = 0;
+       if (this_board->have_irq && pcidev->irq) {
+               ret = request_irq(pcidev->irq, interrupt_service_pci1710,
+                                 IRQF_SHARED, dev->board_name, dev);
+               if (ret == 0)
+                       dev->irq = pcidev->irq;
        }
 
-       dev->irq = irq;
        subdev = 0;
 
        if (this_board->n_aichan) {
-               s = dev->subdevices + subdev;
+               s = &dev->subdevices[subdev];
                dev->read_subdev = s;
                s->type = COMEDI_SUBD_AI;
                s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
@@ -1452,7 +1323,7 @@ static int pci1710_attach(struct comedi_device *dev,
                s->range_table = this_board->rangelist_ai;
                s->cancel = pci171x_ai_cancel;
                s->insn_read = pci171x_insn_read_ai;
-               if (irq) {
+               if (dev->irq) {
                        s->subdev_flags |= SDF_CMD_READ;
                        s->do_cmdtest = pci171x_ai_cmdtest;
                        s->do_cmd = pci171x_ai_cmd;
@@ -1462,7 +1333,7 @@ static int pci1710_attach(struct comedi_device *dev,
        }
 
        if (this_board->n_aochan) {
-               s = dev->subdevices + subdev;
+               s = &dev->subdevices[subdev];
                s->type = COMEDI_SUBD_AO;
                s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
                s->n_chan = this_board->n_aochan;
@@ -1482,7 +1353,7 @@ static int pci1710_attach(struct comedi_device *dev,
        }
 
        if (this_board->n_dichan) {
-               s = dev->subdevices + subdev;
+               s = &dev->subdevices[subdev];
                s->type = COMEDI_SUBD_DI;
                s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
                s->n_chan = this_board->n_dichan;
@@ -1495,7 +1366,7 @@ static int pci1710_attach(struct comedi_device *dev,
        }
 
        if (this_board->n_dochan) {
-               s = dev->subdevices + subdev;
+               s = &dev->subdevices[subdev];
                s->type = COMEDI_SUBD_DO;
                s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
                s->n_chan = this_board->n_dochan;
@@ -1510,7 +1381,7 @@ static int pci1710_attach(struct comedi_device *dev,
        }
 
        if (this_board->n_counter) {
-               s = dev->subdevices + subdev;
+               s = &dev->subdevices[subdev];
                s->type = COMEDI_SUBD_COUNTER;
                s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
                s->n_chan = this_board->n_counter;
@@ -1523,7 +1394,8 @@ static int pci1710_attach(struct comedi_device *dev,
                subdev++;
        }
 
-       devpriv->valid = 1;
+       dev_info(dev->class_dev, "%s attached, irq %sabled\n",
+               dev->board_name, dev->irq ? "en" : "dis");
 
        return 0;
 }
@@ -1532,27 +1404,21 @@ static void pci1710_detach(struct comedi_device *dev)
 {
        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 
-       if (dev->private) {
-               if (devpriv->valid)
-                       pci1710_reset(dev);
-               if (dev->irq)
-                       free_irq(dev->irq, dev);
-       }
+       if (dev->iobase)
+               pci1710_reset(dev);
+       if (dev->irq)
+               free_irq(dev->irq, dev);
        if (pcidev) {
                if (dev->iobase)
                        comedi_pci_disable(pcidev);
-               pci_dev_put(pcidev);
        }
 }
 
 static struct comedi_driver adv_pci1710_driver = {
        .driver_name    = "adv_pci1710",
        .module         = THIS_MODULE,
-       .attach         = pci1710_attach,
+       .attach_pci     = pci1710_attach_pci,
        .detach         = pci1710_detach,
-       .num_names      = ARRAY_SIZE(boardtypes),
-       .board_name     = &boardtypes[0].name,
-       .offset         = sizeof(struct boardtype),
 };
 
 static int __devinit adv_pci1710_pci_probe(struct pci_dev *dev,