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