Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[sfrench/cifs-2.6.git] / drivers / staging / comedi / drivers / amplc_dio200.c
1 /*
2     comedi/drivers/amplc_dio200.c
3     Driver for Amplicon PC272E and PCI272 DIO boards.
4     (Support for other boards in Amplicon 200 series may be added at
5     a later date, e.g. PCI215.)
6
7     Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
8
9     COMEDI - Linux Control and Measurement Device Interface
10     Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
11
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20     GNU General Public License for more details.
21
22     You should have received a copy of the GNU General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 */
27 /*
28 Driver: amplc_dio200
29 Description: Amplicon 200 Series Digital I/O
30 Author: Ian Abbott <abbotti@mev.co.uk>
31 Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
32   PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e),
33   PCI272 (pci272 or amplc_dio200)
34 Updated: Wed, 22 Oct 2008 13:36:02 +0100
35 Status: works
36
37 Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
38   [0] - I/O port base address
39   [1] - IRQ (optional, but commands won't work without it)
40
41 Configuration options - PCI215, PCI272:
42   [0] - PCI bus of device (optional)
43   [1] - PCI slot of device (optional)
44   If bus/slot is not specified, the first available PCI device will
45   be used.
46
47 Passing a zero for an option is the same as leaving it unspecified.
48
49 SUBDEVICES
50
51                     PC218E         PC212E      PC215E/PCI215
52                  -------------  -------------  -------------
53   Subdevices           7              6              5
54    0                 CTR-X1         PPI-X          PPI-X
55    1                 CTR-X2         CTR-Y1         PPI-Y
56    2                 CTR-Y1         CTR-Y2         CTR-Z1
57    3                 CTR-Y2         CTR-Z1         CTR-Z2
58    4                 CTR-Z1         CTR-Z2       INTERRUPT
59    5                 CTR-Z2       INTERRUPT
60    6               INTERRUPT
61
62                     PC214E      PC272E/PCI272
63                  -------------  -------------
64   Subdevices           4              4
65    0                 PPI-X          PPI-X
66    1                 PPI-Y          PPI-Y
67    2                 CTR-Z1*        PPI-Z
68    3               INTERRUPT*     INTERRUPT
69
70 Each PPI is a 8255 chip providing 24 DIO channels.  The DIO channels
71 are configurable as inputs or outputs in four groups:
72
73   Port A  - channels  0 to  7
74   Port B  - channels  8 to 15
75   Port CL - channels 16 to 19
76   Port CH - channels 20 to 23
77
78 Only mode 0 of the 8255 chips is supported.
79
80 Each CTR is a 8254 chip providing 3 16-bit counter channels.  Each
81 channel is configured individually with INSN_CONFIG instructions.  The
82 specific type of configuration instruction is specified in data[0].
83 Some configuration instructions expect an additional parameter in
84 data[1]; others return a value in data[1].  The following configuration
85 instructions are supported:
86
87   INSN_CONFIG_SET_COUNTER_MODE.  Sets the counter channel's mode and
88     BCD/binary setting specified in data[1].
89
90   INSN_CONFIG_8254_READ_STATUS.  Reads the status register value for the
91     counter channel into data[1].
92
93   INSN_CONFIG_SET_CLOCK_SRC.  Sets the counter channel's clock source as
94     specified in data[1] (this is a hardware-specific value).  Not
95     supported on PC214E.  For the other boards, valid clock sources are
96     0 to 7 as follows:
97
98       0.  CLK n, the counter channel's dedicated CLK input from the SK1
99         connector.  (N.B. for other values, the counter channel's CLKn
100         pin on the SK1 connector is an output!)
101       1.  Internal 10 MHz clock.
102       2.  Internal 1 MHz clock.
103       3.  Internal 100 kHz clock.
104       4.  Internal 10 kHz clock.
105       5.  Internal 1 kHz clock.
106       6.  OUT n-1, the output of counter channel n-1 (see note 1 below).
107       7.  Ext Clock, the counter chip's dedicated Ext Clock input from
108         the SK1 connector.  This pin is shared by all three counter
109         channels on the chip.
110
111   INSN_CONFIG_GET_CLOCK_SRC.  Returns the counter channel's current
112     clock source in data[1].  For internal clock sources, data[2] is set
113     to the period in ns.
114
115   INSN_CONFIG_SET_GATE_SRC.  Sets the counter channel's gate source as
116     specified in data[2] (this is a hardware-specific value).  Not
117     supported on PC214E.  For the other boards, valid gate sources are 0
118     to 7 as follows:
119
120       0.  VCC (internal +5V d.c.), i.e. gate permanently enabled.
121       1.  GND (internal 0V d.c.), i.e. gate permanently disabled.
122       2.  GAT n, the counter channel's dedicated GAT input from the SK1
123         connector.  (N.B. for other values, the counter channel's GATn
124         pin on the SK1 connector is an output!)
125       3.  /OUT n-2, the inverted output of counter channel n-2 (see note
126         2 below).
127       4.  Reserved.
128       5.  Reserved.
129       6.  Reserved.
130       7.  Reserved.
131
132   INSN_CONFIG_GET_GATE_SRC.  Returns the counter channel's current gate
133     source in data[2].
134
135 Clock and gate interconnection notes:
136
137   1.  Clock source OUT n-1 is the output of the preceding channel on the
138   same counter subdevice if n > 0, or the output of channel 2 on the
139   preceding counter subdevice (see note 3) if n = 0.
140
141   2.  Gate source /OUT n-2 is the inverted output of channel 0 on the
142   same counter subdevice if n = 2, or the inverted output of channel n+1
143   on the preceding counter subdevice (see note 3) if n < 2.
144
145   3.  The counter subdevices are connected in a ring, so the highest
146   counter subdevice precedes the lowest.
147
148 The 'INTERRUPT' subdevice pretends to be a digital input subdevice.  The
149 digital inputs come from the interrupt status register.  The number of
150 channels matches the number of interrupt sources.  The PC214E does not
151 have an interrupt status register; see notes on 'INTERRUPT SOURCES'
152 below.
153
154 INTERRUPT SOURCES
155
156                     PC218E         PC212E      PC215E/PCI215
157                  -------------  -------------  -------------
158   Sources              6              6              6
159    0              CTR-X1-OUT      PPI-X-C0       PPI-X-C0
160    1              CTR-X2-OUT      PPI-X-C3       PPI-X-C3
161    2              CTR-Y1-OUT     CTR-Y1-OUT      PPI-Y-C0
162    3              CTR-Y2-OUT     CTR-Y2-OUT      PPI-Y-C3
163    4              CTR-Z1-OUT     CTR-Z1-OUT     CTR-Z1-OUT
164    5              CTR-Z2-OUT     CTR-Z2-OUT     CTR-Z2-OUT
165
166                     PC214E      PC272E/PCI272
167                  -------------  -------------
168   Sources              1              6
169    0               JUMPER-J5      PPI-X-C0
170    1                              PPI-X-C3
171    2                              PPI-Y-C0
172    3                              PPI-Y-C3
173    4                              PPI-Z-C0
174    5                              PPI-Z-C3
175
176 When an interrupt source is enabled in the interrupt source enable
177 register, a rising edge on the source signal latches the corresponding
178 bit to 1 in the interrupt status register.
179
180 When the interrupt status register value as a whole (actually, just the
181 6 least significant bits) goes from zero to non-zero, the board will
182 generate an interrupt.  For level-triggered hardware interrupts (PCI
183 card), the interrupt will remain asserted until the interrupt status
184 register is cleared to zero.  For edge-triggered hardware interrupts
185 (ISA card), no further interrupts will occur until the interrupt status
186 register is cleared to zero.  To clear a bit to zero in the interrupt
187 status register, the corresponding interrupt source must be disabled
188 in the interrupt source enable register (there is no separate interrupt
189 clear register).
190
191 The PC214E does not have an interrupt source enable register or an
192 interrupt status register; its 'INTERRUPT' subdevice has a single
193 channel and its interrupt source is selected by the position of jumper
194 J5.
195
196 COMMANDS
197
198 The driver supports a read streaming acquisition command on the
199 'INTERRUPT' subdevice.  The channel list selects the interrupt sources
200 to be enabled.  All channels will be sampled together (convert_src ==
201 TRIG_NOW).  The scan begins a short time after the hardware interrupt
202 occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
203 scan_begin_arg == 0).  The value read from the interrupt status register
204 is packed into a short value, one bit per requested channel, in the
205 order they appear in the channel list.
206 */
207
208 #include <linux/interrupt.h>
209 #include <linux/slab.h>
210
211 #include "../comedidev.h"
212
213 #include "comedi_pci.h"
214
215 #include "8255.h"
216 #include "8253.h"
217
218 #define DIO200_DRIVER_NAME      "amplc_dio200"
219
220 /* PCI IDs */
221 #define PCI_VENDOR_ID_AMPLICON 0x14dc
222 #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
223 #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
224 #define PCI_DEVICE_ID_INVALID 0xffff
225
226 /* 200 series registers */
227 #define DIO200_IO_SIZE          0x20
228 #define DIO200_XCLK_SCE         0x18    /* Group X clock selection register */
229 #define DIO200_YCLK_SCE         0x19    /* Group Y clock selection register */
230 #define DIO200_ZCLK_SCE         0x1a    /* Group Z clock selection register */
231 #define DIO200_XGAT_SCE         0x1b    /* Group X gate selection register */
232 #define DIO200_YGAT_SCE         0x1c    /* Group Y gate selection register */
233 #define DIO200_ZGAT_SCE         0x1d    /* Group Z gate selection register */
234 #define DIO200_INT_SCE          0x1e    /* Interrupt enable/status register */
235
236 /*
237  * Macros for constructing value for DIO_200_?CLK_SCE and
238  * DIO_200_?GAT_SCE registers:
239  *
240  * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
241  * 'chan' is the channel: 0, 1 or 2.
242  * 'source' is the signal source: 0 to 7.
243  */
244 #define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
245 #define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
246
247 /*
248  * Periods of the internal clock sources in nanoseconds.
249  */
250 static const unsigned clock_period[8] = {
251         0,                      /* dedicated clock input/output pin */
252         100,                    /* 10 MHz */
253         1000,                   /* 1 MHz */
254         10000,                  /* 100 kHz */
255         100000,                 /* 10 kHz */
256         1000000,                /* 1 kHz */
257         0,                      /* OUT N-1 */
258         0                       /* group clock input pin */
259 };
260
261 /*
262  * Board descriptions.
263  */
264
265 enum dio200_bustype { isa_bustype, pci_bustype };
266
267 enum dio200_model {
268         pc212e_model,
269         pc214e_model,
270         pc215e_model, pci215_model,
271         pc218e_model,
272         pc272e_model, pci272_model,
273         anypci_model
274 };
275
276 enum dio200_layout {
277         pc212_layout,
278         pc214_layout,
279         pc215_layout,
280         pc218_layout,
281         pc272_layout
282 };
283
284 struct dio200_board {
285         const char *name;
286         unsigned short devid;
287         enum dio200_bustype bustype;
288         enum dio200_model model;
289         enum dio200_layout layout;
290 };
291
292 static const struct dio200_board dio200_boards[] = {
293         {
294          .name = "pc212e",
295          .bustype = isa_bustype,
296          .model = pc212e_model,
297          .layout = pc212_layout,
298          },
299         {
300          .name = "pc214e",
301          .bustype = isa_bustype,
302          .model = pc214e_model,
303          .layout = pc214_layout,
304          },
305         {
306          .name = "pc215e",
307          .bustype = isa_bustype,
308          .model = pc215e_model,
309          .layout = pc215_layout,
310          },
311 #ifdef CONFIG_COMEDI_PCI
312         {
313          .name = "pci215",
314          .devid = PCI_DEVICE_ID_AMPLICON_PCI215,
315          .bustype = pci_bustype,
316          .model = pci215_model,
317          .layout = pc215_layout,
318          },
319 #endif
320         {
321          .name = "pc218e",
322          .bustype = isa_bustype,
323          .model = pc218e_model,
324          .layout = pc218_layout,
325          },
326         {
327          .name = "pc272e",
328          .bustype = isa_bustype,
329          .model = pc272e_model,
330          .layout = pc272_layout,
331          },
332 #ifdef CONFIG_COMEDI_PCI
333         {
334          .name = "pci272",
335          .devid = PCI_DEVICE_ID_AMPLICON_PCI272,
336          .bustype = pci_bustype,
337          .model = pci272_model,
338          .layout = pc272_layout,
339          },
340 #endif
341 #ifdef CONFIG_COMEDI_PCI
342         {
343          .name = DIO200_DRIVER_NAME,
344          .devid = PCI_DEVICE_ID_INVALID,
345          .bustype = pci_bustype,
346          .model = anypci_model, /* wildcard */
347          },
348 #endif
349 };
350
351 /*
352  * Layout descriptions - some ISA and PCI board descriptions share the same
353  * layout.
354  */
355
356 enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 };
357
358 #define DIO200_MAX_SUBDEVS      7
359 #define DIO200_MAX_ISNS         6
360
361 struct dio200_layout_struct {
362         unsigned short n_subdevs;       /* number of subdevices */
363         unsigned char sdtype[DIO200_MAX_SUBDEVS];       /* enum dio200_sdtype */
364         unsigned char sdinfo[DIO200_MAX_SUBDEVS];       /* depends on sdtype */
365         char has_int_sce;       /* has interrupt enable/status register */
366         char has_clk_gat_sce;   /* has clock/gate selection registers */
367 };
368
369 static const struct dio200_layout_struct dio200_layouts[] = {
370         [pc212_layout] = {
371                           .n_subdevs = 6,
372                           .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254,
373                                      sd_8254,
374                                      sd_intr},
375                           .sdinfo = {0x00, 0x08, 0x0C, 0x10, 0x14,
376                                      0x3F},
377                           .has_int_sce = 1,
378                           .has_clk_gat_sce = 1,
379                           },
380         [pc214_layout] = {
381                           .n_subdevs = 4,
382                           .sdtype = {sd_8255, sd_8255, sd_8254,
383                                      sd_intr},
384                           .sdinfo = {0x00, 0x08, 0x10, 0x01},
385                           .has_int_sce = 0,
386                           .has_clk_gat_sce = 0,
387                           },
388         [pc215_layout] = {
389                           .n_subdevs = 5,
390                           .sdtype = {sd_8255, sd_8255, sd_8254,
391                                      sd_8254,
392                                      sd_intr},
393                           .sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F},
394                           .has_int_sce = 1,
395                           .has_clk_gat_sce = 1,
396                           },
397         [pc218_layout] = {
398                           .n_subdevs = 7,
399                           .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254,
400                                      sd_8254,
401                                      sd_intr},
402                           .sdinfo = {0x00, 0x04, 0x08, 0x0C, 0x10,
403                                      0x14,
404                                      0x3F},
405                           .has_int_sce = 1,
406                           .has_clk_gat_sce = 1,
407                           },
408         [pc272_layout] = {
409                           .n_subdevs = 4,
410                           .sdtype = {sd_8255, sd_8255, sd_8255,
411                                      sd_intr},
412                           .sdinfo = {0x00, 0x08, 0x10, 0x3F},
413                           .has_int_sce = 1,
414                           .has_clk_gat_sce = 0,
415                           },
416 };
417
418 /*
419  * PCI driver table.
420  */
421
422 #ifdef CONFIG_COMEDI_PCI
423 static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
424         {
425         PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
426                     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
427         PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
428                     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
429         0}
430 };
431
432 MODULE_DEVICE_TABLE(pci, dio200_pci_table);
433 #endif /* CONFIG_COMEDI_PCI */
434
435 /*
436  * Useful for shorthand access to the particular board structure
437  */
438 #define thisboard ((const struct dio200_board *)dev->board_ptr)
439 #define thislayout (&dio200_layouts[((struct dio200_board *) \
440                     dev->board_ptr)->layout])
441
442 /* this structure is for data unique to this hardware driver.  If
443    several hardware drivers keep similar information in this structure,
444    feel free to suggest moving the variable to the struct comedi_device struct.
445  */
446 struct dio200_private {
447 #ifdef CONFIG_COMEDI_PCI
448         struct pci_dev *pci_dev;        /* PCI device */
449 #endif
450         int intr_sd;
451 };
452
453 #define devpriv ((struct dio200_private *)dev->private)
454
455 struct dio200_subdev_8254 {
456         unsigned long iobase;   /* Counter base address */
457         unsigned long clk_sce_iobase;   /* CLK_SCE base address */
458         unsigned long gat_sce_iobase;   /* GAT_SCE base address */
459         int which;              /* Bit 5 of CLK_SCE or GAT_SCE */
460         int has_clk_gat_sce;
461         unsigned clock_src[3];  /* Current clock sources */
462         unsigned gate_src[3];   /* Current gate sources */
463         spinlock_t spinlock;
464 };
465
466 struct dio200_subdev_intr {
467         unsigned long iobase;
468         spinlock_t spinlock;
469         int active;
470         int has_int_sce;
471         unsigned int valid_isns;
472         unsigned int enabled_isns;
473         unsigned int stopcount;
474         int continuous;
475 };
476
477 /*
478  * The struct comedi_driver structure tells the Comedi core module
479  * which functions to call to configure/deconfigure (attach/detach)
480  * the board, and also about the kernel module that contains
481  * the device code.
482  */
483 static int dio200_attach(struct comedi_device *dev,
484                          struct comedi_devconfig *it);
485 static int dio200_detach(struct comedi_device *dev);
486 static struct comedi_driver driver_amplc_dio200 = {
487         .driver_name = DIO200_DRIVER_NAME,
488         .module = THIS_MODULE,
489         .attach = dio200_attach,
490         .detach = dio200_detach,
491         .board_name = &dio200_boards[0].name,
492         .offset = sizeof(struct dio200_board),
493         .num_names = ARRAY_SIZE(dio200_boards),
494 };
495
496 #ifdef CONFIG_COMEDI_PCI
497 COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
498 #else
499 COMEDI_INITCLEANUP(driver_amplc_dio200);
500 #endif
501
502 /*
503  * This function looks for a PCI device matching the requested board name,
504  * bus and slot.
505  */
506 #ifdef CONFIG_COMEDI_PCI
507 static int
508 dio200_find_pci(struct comedi_device *dev, int bus, int slot,
509                 struct pci_dev **pci_dev_p)
510 {
511         struct pci_dev *pci_dev = NULL;
512
513         *pci_dev_p = NULL;
514
515         /* Look for matching PCI device. */
516         for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
517              pci_dev != NULL;
518              pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
519                                       PCI_ANY_ID, pci_dev)) {
520                 /* If bus/slot specified, check them. */
521                 if (bus || slot) {
522                         if (bus != pci_dev->bus->number
523                             || slot != PCI_SLOT(pci_dev->devfn))
524                                 continue;
525                 }
526                 if (thisboard->model == anypci_model) {
527                         /* Match any supported model. */
528                         int i;
529
530                         for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
531                                 if (dio200_boards[i].bustype != pci_bustype)
532                                         continue;
533                                 if (pci_dev->device == dio200_boards[i].devid) {
534                                         /* Change board_ptr to matched board. */
535                                         dev->board_ptr = &dio200_boards[i];
536                                         break;
537                                 }
538                         }
539                         if (i == ARRAY_SIZE(dio200_boards))
540                                 continue;
541                 } else {
542                         /* Match specific model name. */
543                         if (pci_dev->device != thisboard->devid)
544                                 continue;
545                 }
546
547                 /* Found a match. */
548                 *pci_dev_p = pci_dev;
549                 return 0;
550         }
551         /* No match found. */
552         if (bus || slot) {
553                 printk(KERN_ERR
554                        "comedi%d: error! no %s found at pci %02x:%02x!\n",
555                        dev->minor, thisboard->name, bus, slot);
556         } else {
557                 printk(KERN_ERR "comedi%d: error! no %s found!\n",
558                        dev->minor, thisboard->name);
559         }
560         return -EIO;
561 }
562 #endif
563
564 /*
565  * This function checks and requests an I/O region, reporting an error
566  * if there is a conflict.
567  */
568 static int
569 dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
570 {
571         if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
572                 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
573                        minor, from, extent);
574                 return -EIO;
575         }
576         return 0;
577 }
578
579 /*
580  * 'insn_bits' function for an 'INTERRUPT' subdevice.
581  */
582 static int
583 dio200_subdev_intr_insn_bits(struct comedi_device *dev,
584                              struct comedi_subdevice *s,
585                              struct comedi_insn *insn, unsigned int *data)
586 {
587         struct dio200_subdev_intr *subpriv = s->private;
588
589         if (subpriv->has_int_sce) {
590                 /* Just read the interrupt status register.  */
591                 data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
592         } else {
593                 /* No interrupt status register. */
594                 data[0] = 0;
595         }
596
597         return 2;
598 }
599
600 /*
601  * Called to stop acquisition for an 'INTERRUPT' subdevice.
602  */
603 static void dio200_stop_intr(struct comedi_device *dev,
604                              struct comedi_subdevice *s)
605 {
606         struct dio200_subdev_intr *subpriv = s->private;
607
608         subpriv->active = 0;
609         subpriv->enabled_isns = 0;
610         if (subpriv->has_int_sce)
611                 outb(0, subpriv->iobase);
612 }
613
614 /*
615  * Called to start acquisition for an 'INTERRUPT' subdevice.
616  */
617 static int dio200_start_intr(struct comedi_device *dev,
618                              struct comedi_subdevice *s)
619 {
620         unsigned int n;
621         unsigned isn_bits;
622         struct dio200_subdev_intr *subpriv = s->private;
623         struct comedi_cmd *cmd = &s->async->cmd;
624         int retval = 0;
625
626         if (!subpriv->continuous && subpriv->stopcount == 0) {
627                 /* An empty acquisition! */
628                 s->async->events |= COMEDI_CB_EOA;
629                 subpriv->active = 0;
630                 retval = 1;
631         } else {
632                 /* Determine interrupt sources to enable. */
633                 isn_bits = 0;
634                 if (cmd->chanlist) {
635                         for (n = 0; n < cmd->chanlist_len; n++)
636                                 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
637                 }
638                 isn_bits &= subpriv->valid_isns;
639                 /* Enable interrupt sources. */
640                 subpriv->enabled_isns = isn_bits;
641                 if (subpriv->has_int_sce)
642                         outb(isn_bits, subpriv->iobase);
643         }
644
645         return retval;
646 }
647
648 /*
649  * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
650  */
651 static int
652 dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
653                           unsigned int trignum)
654 {
655         struct dio200_subdev_intr *subpriv;
656         unsigned long flags;
657         int event = 0;
658
659         if (trignum != 0)
660                 return -EINVAL;
661
662         subpriv = s->private;
663
664         spin_lock_irqsave(&subpriv->spinlock, flags);
665         s->async->inttrig = NULL;
666         if (subpriv->active)
667                 event = dio200_start_intr(dev, s);
668
669         spin_unlock_irqrestore(&subpriv->spinlock, flags);
670
671         if (event)
672                 comedi_event(dev, s);
673
674         return 1;
675 }
676
677 /*
678  * This is called from the interrupt service routine to handle a read
679  * scan on an 'INTERRUPT' subdevice.
680  */
681 static int dio200_handle_read_intr(struct comedi_device *dev,
682                                    struct comedi_subdevice *s)
683 {
684         struct dio200_subdev_intr *subpriv = s->private;
685         unsigned triggered;
686         unsigned intstat;
687         unsigned cur_enabled;
688         unsigned int oldevents;
689         unsigned long flags;
690
691         triggered = 0;
692
693         spin_lock_irqsave(&subpriv->spinlock, flags);
694         oldevents = s->async->events;
695         if (subpriv->has_int_sce) {
696                 /*
697                  * Collect interrupt sources that have triggered and disable
698                  * them temporarily.  Loop around until no extra interrupt
699                  * sources have triggered, at which point, the valid part of
700                  * the interrupt status register will read zero, clearing the
701                  * cause of the interrupt.
702                  *
703                  * Mask off interrupt sources already seen to avoid infinite
704                  * loop in case of misconfiguration.
705                  */
706                 cur_enabled = subpriv->enabled_isns;
707                 while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
708                                    & ~triggered)) != 0) {
709                         triggered |= intstat;
710                         cur_enabled &= ~triggered;
711                         outb(cur_enabled, subpriv->iobase);
712                 }
713         } else {
714                 /*
715                  * No interrupt status register.  Assume the single interrupt
716                  * source has triggered.
717                  */
718                 triggered = subpriv->enabled_isns;
719         }
720
721         if (triggered) {
722                 /*
723                  * Some interrupt sources have triggered and have been
724                  * temporarily disabled to clear the cause of the interrupt.
725                  *
726                  * Reenable them NOW to minimize the time they are disabled.
727                  */
728                 cur_enabled = subpriv->enabled_isns;
729                 if (subpriv->has_int_sce)
730                         outb(cur_enabled, subpriv->iobase);
731
732                 if (subpriv->active) {
733                         /*
734                          * The command is still active.
735                          *
736                          * Ignore interrupt sources that the command isn't
737                          * interested in (just in case there's a race
738                          * condition).
739                          */
740                         if (triggered & subpriv->enabled_isns) {
741                                 /* Collect scan data. */
742                                 short val;
743                                 unsigned int n, ch, len;
744
745                                 val = 0;
746                                 len = s->async->cmd.chanlist_len;
747                                 for (n = 0; n < len; n++) {
748                                         ch = CR_CHAN(s->async->cmd.chanlist[n]);
749                                         if (triggered & (1U << ch))
750                                                 val |= (1U << n);
751                                 }
752                                 /* Write the scan to the buffer. */
753                                 if (comedi_buf_put(s->async, val)) {
754                                         s->async->events |= (COMEDI_CB_BLOCK |
755                                                              COMEDI_CB_EOS);
756                                 } else {
757                                         /* Error!  Stop acquisition.  */
758                                         dio200_stop_intr(dev, s);
759                                         s->async->events |= COMEDI_CB_ERROR
760                                             | COMEDI_CB_OVERFLOW;
761                                         comedi_error(dev, "buffer overflow");
762                                 }
763
764                                 /* Check for end of acquisition. */
765                                 if (!subpriv->continuous) {
766                                         /* stop_src == TRIG_COUNT */
767                                         if (subpriv->stopcount > 0) {
768                                                 subpriv->stopcount--;
769                                                 if (subpriv->stopcount == 0) {
770                                                         s->async->events |=
771                                                             COMEDI_CB_EOA;
772                                                         dio200_stop_intr(dev,
773                                                                          s);
774                                                 }
775                                         }
776                                 }
777                         }
778                 }
779         }
780         spin_unlock_irqrestore(&subpriv->spinlock, flags);
781
782         if (oldevents != s->async->events)
783                 comedi_event(dev, s);
784
785         return (triggered != 0);
786 }
787
788 /*
789  * 'cancel' function for an 'INTERRUPT' subdevice.
790  */
791 static int dio200_subdev_intr_cancel(struct comedi_device *dev,
792                                      struct comedi_subdevice *s)
793 {
794         struct dio200_subdev_intr *subpriv = s->private;
795         unsigned long flags;
796
797         spin_lock_irqsave(&subpriv->spinlock, flags);
798         if (subpriv->active)
799                 dio200_stop_intr(dev, s);
800
801         spin_unlock_irqrestore(&subpriv->spinlock, flags);
802
803         return 0;
804 }
805
806 /*
807  * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
808  */
809 static int
810 dio200_subdev_intr_cmdtest(struct comedi_device *dev,
811                            struct comedi_subdevice *s, struct comedi_cmd *cmd)
812 {
813         int err = 0;
814         unsigned int tmp;
815
816         /* step 1: make sure trigger sources are trivially valid */
817
818         tmp = cmd->start_src;
819         cmd->start_src &= (TRIG_NOW | TRIG_INT);
820         if (!cmd->start_src || tmp != cmd->start_src)
821                 err++;
822
823         tmp = cmd->scan_begin_src;
824         cmd->scan_begin_src &= TRIG_EXT;
825         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
826                 err++;
827
828         tmp = cmd->convert_src;
829         cmd->convert_src &= TRIG_NOW;
830         if (!cmd->convert_src || tmp != cmd->convert_src)
831                 err++;
832
833         tmp = cmd->scan_end_src;
834         cmd->scan_end_src &= TRIG_COUNT;
835         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
836                 err++;
837
838         tmp = cmd->stop_src;
839         cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
840         if (!cmd->stop_src || tmp != cmd->stop_src)
841                 err++;
842
843         if (err)
844                 return 1;
845
846         /* step 2: make sure trigger sources are unique and mutually
847                    compatible */
848
849         /* these tests are true if more than one _src bit is set */
850         if ((cmd->start_src & (cmd->start_src - 1)) != 0)
851                 err++;
852         if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
853                 err++;
854         if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
855                 err++;
856         if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
857                 err++;
858         if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
859                 err++;
860
861         if (err)
862                 return 2;
863
864         /* step 3: make sure arguments are trivially compatible */
865
866         /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
867         if (cmd->start_arg != 0) {
868                 cmd->start_arg = 0;
869                 err++;
870         }
871
872         /* cmd->scan_begin_src == TRIG_EXT */
873         if (cmd->scan_begin_arg != 0) {
874                 cmd->scan_begin_arg = 0;
875                 err++;
876         }
877
878         /* cmd->convert_src == TRIG_NOW */
879         if (cmd->convert_arg != 0) {
880                 cmd->convert_arg = 0;
881                 err++;
882         }
883
884         /* cmd->scan_end_src == TRIG_COUNT */
885         if (cmd->scan_end_arg != cmd->chanlist_len) {
886                 cmd->scan_end_arg = cmd->chanlist_len;
887                 err++;
888         }
889
890         switch (cmd->stop_src) {
891         case TRIG_COUNT:
892                 /* any count allowed */
893                 break;
894         case TRIG_NONE:
895                 if (cmd->stop_arg != 0) {
896                         cmd->stop_arg = 0;
897                         err++;
898                 }
899                 break;
900         default:
901                 break;
902         }
903
904         if (err)
905                 return 3;
906
907         /* step 4: fix up any arguments */
908
909         /* if (err) return 4; */
910
911         return 0;
912 }
913
914 /*
915  * 'do_cmd' function for an 'INTERRUPT' subdevice.
916  */
917 static int dio200_subdev_intr_cmd(struct comedi_device *dev,
918                                   struct comedi_subdevice *s)
919 {
920         struct comedi_cmd *cmd = &s->async->cmd;
921         struct dio200_subdev_intr *subpriv = s->private;
922         unsigned long flags;
923         int event = 0;
924
925         spin_lock_irqsave(&subpriv->spinlock, flags);
926         subpriv->active = 1;
927
928         /* Set up end of acquisition. */
929         switch (cmd->stop_src) {
930         case TRIG_COUNT:
931                 subpriv->continuous = 0;
932                 subpriv->stopcount = cmd->stop_arg;
933                 break;
934         default:
935                 /* TRIG_NONE */
936                 subpriv->continuous = 1;
937                 subpriv->stopcount = 0;
938                 break;
939         }
940
941         /* Set up start of acquisition. */
942         switch (cmd->start_src) {
943         case TRIG_INT:
944                 s->async->inttrig = dio200_inttrig_start_intr;
945                 break;
946         default:
947                 /* TRIG_NOW */
948                 event = dio200_start_intr(dev, s);
949                 break;
950         }
951         spin_unlock_irqrestore(&subpriv->spinlock, flags);
952
953         if (event)
954                 comedi_event(dev, s);
955
956         return 0;
957 }
958
959 /*
960  * This function initializes an 'INTERRUPT' subdevice.
961  */
962 static int
963 dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
964                         unsigned long iobase, unsigned valid_isns,
965                         int has_int_sce)
966 {
967         struct dio200_subdev_intr *subpriv;
968
969         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
970         if (!subpriv) {
971                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
972                        dev->minor);
973                 return -ENOMEM;
974         }
975         subpriv->iobase = iobase;
976         subpriv->has_int_sce = has_int_sce;
977         subpriv->valid_isns = valid_isns;
978         spin_lock_init(&subpriv->spinlock);
979
980         if (has_int_sce)
981                 outb(0, subpriv->iobase);       /* Disable interrupt sources. */
982
983         s->private = subpriv;
984         s->type = COMEDI_SUBD_DI;
985         s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
986         if (has_int_sce) {
987                 s->n_chan = DIO200_MAX_ISNS;
988                 s->len_chanlist = DIO200_MAX_ISNS;
989         } else {
990                 /* No interrupt source register.  Support single channel. */
991                 s->n_chan = 1;
992                 s->len_chanlist = 1;
993         }
994         s->range_table = &range_digital;
995         s->maxdata = 1;
996         s->insn_bits = dio200_subdev_intr_insn_bits;
997         s->do_cmdtest = dio200_subdev_intr_cmdtest;
998         s->do_cmd = dio200_subdev_intr_cmd;
999         s->cancel = dio200_subdev_intr_cancel;
1000
1001         return 0;
1002 }
1003
1004 /*
1005  * This function cleans up an 'INTERRUPT' subdevice.
1006  */
1007 static void
1008 dio200_subdev_intr_cleanup(struct comedi_device *dev,
1009                            struct comedi_subdevice *s)
1010 {
1011         struct dio200_subdev_intr *subpriv = s->private;
1012         kfree(subpriv);
1013 }
1014
1015 /*
1016  * Interrupt service routine.
1017  */
1018 static irqreturn_t dio200_interrupt(int irq, void *d)
1019 {
1020         struct comedi_device *dev = d;
1021         int handled;
1022
1023         if (!dev->attached)
1024                 return IRQ_NONE;
1025
1026         if (devpriv->intr_sd >= 0) {
1027                 handled = dio200_handle_read_intr(dev,
1028                                                   dev->subdevices +
1029                                                   devpriv->intr_sd);
1030         } else {
1031                 handled = 0;
1032         }
1033
1034         return IRQ_RETVAL(handled);
1035 }
1036
1037 /*
1038  * Handle 'insn_read' for an '8254' counter subdevice.
1039  */
1040 static int
1041 dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
1042                         struct comedi_insn *insn, unsigned int *data)
1043 {
1044         struct dio200_subdev_8254 *subpriv = s->private;
1045         int chan = CR_CHAN(insn->chanspec);
1046         unsigned long flags;
1047
1048         spin_lock_irqsave(&subpriv->spinlock, flags);
1049         data[0] = i8254_read(subpriv->iobase, 0, chan);
1050         spin_unlock_irqrestore(&subpriv->spinlock, flags);
1051
1052         return 1;
1053 }
1054
1055 /*
1056  * Handle 'insn_write' for an '8254' counter subdevice.
1057  */
1058 static int
1059 dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
1060                          struct comedi_insn *insn, unsigned int *data)
1061 {
1062         struct dio200_subdev_8254 *subpriv = s->private;
1063         int chan = CR_CHAN(insn->chanspec);
1064         unsigned long flags;
1065
1066         spin_lock_irqsave(&subpriv->spinlock, flags);
1067         i8254_write(subpriv->iobase, 0, chan, data[0]);
1068         spin_unlock_irqrestore(&subpriv->spinlock, flags);
1069
1070         return 1;
1071 }
1072
1073 /*
1074  * Set gate source for an '8254' counter subdevice channel.
1075  */
1076 static int
1077 dio200_set_gate_src(struct dio200_subdev_8254 *subpriv,
1078                     unsigned int counter_number, unsigned int gate_src)
1079 {
1080         unsigned char byte;
1081
1082         if (!subpriv->has_clk_gat_sce)
1083                 return -1;
1084         if (counter_number > 2)
1085                 return -1;
1086         if (gate_src > 7)
1087                 return -1;
1088
1089         subpriv->gate_src[counter_number] = gate_src;
1090         byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1091         outb(byte, subpriv->gat_sce_iobase);
1092
1093         return 0;
1094 }
1095
1096 /*
1097  * Get gate source for an '8254' counter subdevice channel.
1098  */
1099 static int
1100 dio200_get_gate_src(struct dio200_subdev_8254 *subpriv,
1101                     unsigned int counter_number)
1102 {
1103         if (!subpriv->has_clk_gat_sce)
1104                 return -1;
1105         if (counter_number > 2)
1106                 return -1;
1107
1108         return subpriv->gate_src[counter_number];
1109 }
1110
1111 /*
1112  * Set clock source for an '8254' counter subdevice channel.
1113  */
1114 static int
1115 dio200_set_clock_src(struct dio200_subdev_8254 *subpriv,
1116                      unsigned int counter_number, unsigned int clock_src)
1117 {
1118         unsigned char byte;
1119
1120         if (!subpriv->has_clk_gat_sce)
1121                 return -1;
1122         if (counter_number > 2)
1123                 return -1;
1124         if (clock_src > 7)
1125                 return -1;
1126
1127         subpriv->clock_src[counter_number] = clock_src;
1128         byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1129         outb(byte, subpriv->clk_sce_iobase);
1130
1131         return 0;
1132 }
1133
1134 /*
1135  * Get clock source for an '8254' counter subdevice channel.
1136  */
1137 static int
1138 dio200_get_clock_src(struct dio200_subdev_8254 *subpriv,
1139                      unsigned int counter_number, unsigned int *period_ns)
1140 {
1141         unsigned clock_src;
1142
1143         if (!subpriv->has_clk_gat_sce)
1144                 return -1;
1145         if (counter_number > 2)
1146                 return -1;
1147
1148         clock_src = subpriv->clock_src[counter_number];
1149         *period_ns = clock_period[clock_src];
1150         return clock_src;
1151 }
1152
1153 /*
1154  * Handle 'insn_config' for an '8254' counter subdevice.
1155  */
1156 static int
1157 dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
1158                           struct comedi_insn *insn, unsigned int *data)
1159 {
1160         struct dio200_subdev_8254 *subpriv = s->private;
1161         int ret = 0;
1162         int chan = CR_CHAN(insn->chanspec);
1163         unsigned long flags;
1164
1165         spin_lock_irqsave(&subpriv->spinlock, flags);
1166         switch (data[0]) {
1167         case INSN_CONFIG_SET_COUNTER_MODE:
1168                 ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
1169                 if (ret < 0)
1170                         ret = -EINVAL;
1171                 break;
1172         case INSN_CONFIG_8254_READ_STATUS:
1173                 data[1] = i8254_status(subpriv->iobase, 0, chan);
1174                 break;
1175         case INSN_CONFIG_SET_GATE_SRC:
1176                 ret = dio200_set_gate_src(subpriv, chan, data[2]);
1177                 if (ret < 0)
1178                         ret = -EINVAL;
1179                 break;
1180         case INSN_CONFIG_GET_GATE_SRC:
1181                 ret = dio200_get_gate_src(subpriv, chan);
1182                 if (ret < 0) {
1183                         ret = -EINVAL;
1184                         break;
1185                 }
1186                 data[2] = ret;
1187                 break;
1188         case INSN_CONFIG_SET_CLOCK_SRC:
1189                 ret = dio200_set_clock_src(subpriv, chan, data[1]);
1190                 if (ret < 0)
1191                         ret = -EINVAL;
1192                 break;
1193         case INSN_CONFIG_GET_CLOCK_SRC:
1194                 ret = dio200_get_clock_src(subpriv, chan, &data[2]);
1195                 if (ret < 0) {
1196                         ret = -EINVAL;
1197                         break;
1198                 }
1199                 data[1] = ret;
1200                 break;
1201         default:
1202                 ret = -EINVAL;
1203                 break;
1204         }
1205         spin_unlock_irqrestore(&subpriv->spinlock, flags);
1206         return ret < 0 ? ret : insn->n;
1207 }
1208
1209 /*
1210  * This function initializes an '8254' counter subdevice.
1211  *
1212  * Note: iobase is the base address of the board, not the subdevice;
1213  * offset is the offset to the 8254 chip.
1214  */
1215 static int
1216 dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
1217                         unsigned long iobase, unsigned offset,
1218                         int has_clk_gat_sce)
1219 {
1220         struct dio200_subdev_8254 *subpriv;
1221         unsigned int chan;
1222
1223         subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1224         if (!subpriv) {
1225                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1226                        dev->minor);
1227                 return -ENOMEM;
1228         }
1229
1230         s->private = subpriv;
1231         s->type = COMEDI_SUBD_COUNTER;
1232         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1233         s->n_chan = 3;
1234         s->maxdata = 0xFFFF;
1235         s->insn_read = dio200_subdev_8254_read;
1236         s->insn_write = dio200_subdev_8254_write;
1237         s->insn_config = dio200_subdev_8254_config;
1238
1239         spin_lock_init(&subpriv->spinlock);
1240         subpriv->iobase = offset + iobase;
1241         subpriv->has_clk_gat_sce = has_clk_gat_sce;
1242         if (has_clk_gat_sce) {
1243                 /* Derive CLK_SCE and GAT_SCE register offsets from
1244                  * 8254 offset. */
1245                 subpriv->clk_sce_iobase =
1246                     DIO200_XCLK_SCE + (offset >> 3) + iobase;
1247                 subpriv->gat_sce_iobase =
1248                     DIO200_XGAT_SCE + (offset >> 3) + iobase;
1249                 subpriv->which = (offset >> 2) & 1;
1250         }
1251
1252         /* Initialize channels. */
1253         for (chan = 0; chan < 3; chan++) {
1254                 i8254_set_mode(subpriv->iobase, 0, chan,
1255                                I8254_MODE0 | I8254_BINARY);
1256                 if (subpriv->has_clk_gat_sce) {
1257                         /* Gate source 0 is VCC (logic 1). */
1258                         dio200_set_gate_src(subpriv, chan, 0);
1259                         /* Clock source 0 is the dedicated clock input. */
1260                         dio200_set_clock_src(subpriv, chan, 0);
1261                 }
1262         }
1263
1264         return 0;
1265 }
1266
1267 /*
1268  * This function cleans up an '8254' counter subdevice.
1269  */
1270 static void
1271 dio200_subdev_8254_cleanup(struct comedi_device *dev,
1272                            struct comedi_subdevice *s)
1273 {
1274         struct dio200_subdev_intr *subpriv = s->private;
1275         kfree(subpriv);
1276 }
1277
1278 /*
1279  * Attach is called by the Comedi core to configure the driver
1280  * for a particular board.  If you specified a board_name array
1281  * in the driver structure, dev->board_ptr contains that
1282  * address.
1283  */
1284 static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1285 {
1286         struct comedi_subdevice *s;
1287         unsigned long iobase = 0;
1288         unsigned int irq = 0;
1289 #ifdef CONFIG_COMEDI_PCI
1290         struct pci_dev *pci_dev = NULL;
1291         int bus = 0, slot = 0;
1292 #endif
1293         const struct dio200_layout_struct *layout;
1294         int share_irq = 0;
1295         int sdx;
1296         unsigned n;
1297         int ret;
1298
1299         printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
1300                DIO200_DRIVER_NAME);
1301
1302         ret = alloc_private(dev, sizeof(struct dio200_private));
1303         if (ret < 0) {
1304                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1305                        dev->minor);
1306                 return ret;
1307         }
1308
1309         /* Process options. */
1310         switch (thisboard->bustype) {
1311         case isa_bustype:
1312                 iobase = it->options[0];
1313                 irq = it->options[1];
1314                 share_irq = 0;
1315                 break;
1316 #ifdef CONFIG_COMEDI_PCI
1317         case pci_bustype:
1318                 bus = it->options[0];
1319                 slot = it->options[1];
1320                 share_irq = 1;
1321
1322                 ret = dio200_find_pci(dev, bus, slot, &pci_dev);
1323                 if (ret < 0)
1324                         return ret;
1325                 devpriv->pci_dev = pci_dev;
1326                 break;
1327 #endif
1328         default:
1329                 printk(KERN_ERR
1330                        "comedi%d: %s: BUG! cannot determine board type!\n",
1331                        dev->minor, DIO200_DRIVER_NAME);
1332                 return -EINVAL;
1333                 break;
1334         }
1335
1336         devpriv->intr_sd = -1;
1337
1338         /* Enable device and reserve I/O spaces. */
1339 #ifdef CONFIG_COMEDI_PCI
1340         if (pci_dev) {
1341                 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1342                 if (ret < 0) {
1343                         printk(KERN_ERR
1344                                "comedi%d: error! cannot enable PCI device and request regions!\n",
1345                                dev->minor);
1346                         return ret;
1347                 }
1348                 iobase = pci_resource_start(pci_dev, 2);
1349                 irq = pci_dev->irq;
1350         } else
1351 #endif
1352         {
1353                 ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
1354                 if (ret < 0)
1355                         return ret;
1356         }
1357         dev->iobase = iobase;
1358
1359         layout = thislayout;
1360
1361         ret = alloc_subdevices(dev, layout->n_subdevs);
1362         if (ret < 0) {
1363                 printk(KERN_ERR "comedi%d: error! out of memory!\n",
1364                        dev->minor);
1365                 return ret;
1366         }
1367
1368         for (n = 0; n < dev->n_subdevices; n++) {
1369                 s = &dev->subdevices[n];
1370                 switch (layout->sdtype[n]) {
1371                 case sd_8254:
1372                         /* counter subdevice (8254) */
1373                         ret = dio200_subdev_8254_init(dev, s, iobase,
1374                                                       layout->sdinfo[n],
1375                                                       layout->has_clk_gat_sce);
1376                         if (ret < 0)
1377                                 return ret;
1378
1379                         break;
1380                 case sd_8255:
1381                         /* digital i/o subdevice (8255) */
1382                         ret = subdev_8255_init(dev, s, NULL,
1383                                                iobase + layout->sdinfo[n]);
1384                         if (ret < 0)
1385                                 return ret;
1386
1387                         break;
1388                 case sd_intr:
1389                         /* 'INTERRUPT' subdevice */
1390                         if (irq) {
1391                                 ret = dio200_subdev_intr_init(dev, s,
1392                                                               iobase +
1393                                                               DIO200_INT_SCE,
1394                                                               layout->sdinfo[n],
1395                                                               layout->
1396                                                               has_int_sce);
1397                                 if (ret < 0)
1398                                         return ret;
1399
1400                                 devpriv->intr_sd = n;
1401                         } else {
1402                                 s->type = COMEDI_SUBD_UNUSED;
1403                         }
1404                         break;
1405                 default:
1406                         s->type = COMEDI_SUBD_UNUSED;
1407                         break;
1408                 }
1409         }
1410
1411         sdx = devpriv->intr_sd;
1412         if (sdx >= 0 && sdx < dev->n_subdevices)
1413                 dev->read_subdev = &dev->subdevices[sdx];
1414
1415         dev->board_name = thisboard->name;
1416
1417         if (irq) {
1418                 unsigned long flags = share_irq ? IRQF_SHARED : 0;
1419
1420                 if (request_irq(irq, dio200_interrupt, flags,
1421                                 DIO200_DRIVER_NAME, dev) >= 0) {
1422                         dev->irq = irq;
1423                 } else {
1424                         printk(KERN_WARNING
1425                                "comedi%d: warning! irq %u unavailable!\n",
1426                                dev->minor, irq);
1427                 }
1428         }
1429
1430         printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1431         if (thisboard->bustype == isa_bustype) {
1432                 printk("(base %#lx) ", iobase);
1433         } else {
1434 #ifdef CONFIG_COMEDI_PCI
1435                 printk("(pci %s) ", pci_name(pci_dev));
1436 #endif
1437         }
1438         if (irq)
1439                 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1440         else
1441                 printk("(no irq) ");
1442
1443         printk("attached\n");
1444
1445         return 1;
1446 }
1447
1448 /*
1449  * _detach is called to deconfigure a device.  It should deallocate
1450  * resources.
1451  * This function is also called when _attach() fails, so it should be
1452  * careful not to release resources that were not necessarily
1453  * allocated by _attach().  dev->private and dev->subdevices are
1454  * deallocated automatically by the core.
1455  */
1456 static int dio200_detach(struct comedi_device *dev)
1457 {
1458         const struct dio200_layout_struct *layout;
1459         unsigned n;
1460
1461         printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
1462                DIO200_DRIVER_NAME);
1463
1464         if (dev->irq)
1465                 free_irq(dev->irq, dev);
1466         if (dev->subdevices) {
1467                 layout = thislayout;
1468                 for (n = 0; n < dev->n_subdevices; n++) {
1469                         struct comedi_subdevice *s = &dev->subdevices[n];
1470                         switch (layout->sdtype[n]) {
1471                         case sd_8254:
1472                                 dio200_subdev_8254_cleanup(dev, s);
1473                                 break;
1474                         case sd_8255:
1475                                 subdev_8255_cleanup(dev, s);
1476                                 break;
1477                         case sd_intr:
1478                                 dio200_subdev_intr_cleanup(dev, s);
1479                                 break;
1480                         default:
1481                                 break;
1482                         }
1483                 }
1484         }
1485         if (devpriv) {
1486 #ifdef CONFIG_COMEDI_PCI
1487                 if (devpriv->pci_dev) {
1488                         if (dev->iobase)
1489                                 comedi_pci_disable(devpriv->pci_dev);
1490                         pci_dev_put(devpriv->pci_dev);
1491                 } else
1492 #endif
1493                 {
1494                         if (dev->iobase)
1495                                 release_region(dev->iobase, DIO200_IO_SIZE);
1496                 }
1497         }
1498         if (dev->board_name)
1499                 printk(KERN_INFO "comedi%d: %s removed\n",
1500                        dev->minor, dev->board_name);
1501
1502         return 0;
1503 }