Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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