Got rid of unnecessary casts when initializing comedi_driver.board_name
[comedi.git] / comedi / drivers / ni_daq_dio24.c
1 /*
2     ni_daq_dio24.c driver for National Instruments PCMCIA DAQ-Card DIO-24
3     Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es>
4
5     PCMCIA crap at end of file is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
6     from the pcmcia package.
7     The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
8     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
9     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
10
11     This program is free software; you can redistribute it and/or modify
12     it under the terms of the GNU General Public License as published by
13     the Free Software Foundation; either version 2 of the License, or
14     (at your option) any later version.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     You should have received a copy of the GNU General Public License
22     along with this program; if not, write to the Free Software
23     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25 ************************************************************************
26 */
27 /*
28 Driver: ni_daq_dio24.o
29 Description: National Instruments PCMCIA DAQ-Card DIO-24
30 Author: Daniel Vecino Castel <dvecino@able.es>
31 Devices: [National Instruments] PCMCIA DAQ-Card DIO-24 (ni_daq_dio24)
32 Status: ?
33 Updated: Thu, 07 Nov 2002 21:53:06 -0800
34
35 This is just a wrapper around the 8255.o driver to properly handle
36 the PCMCIA interface.
37 */
38
39
40 //#define LABPC_DEBUG   // enable debugging messages
41 #undef LABPC_DEBUG
42
43 #include <linux/comedidev.h>
44
45 #include <linux/ioport.h>
46 #include <linux/version.h>
47
48 #include "8255.h"
49
50 #include <pcmcia/cs_types.h>
51 #include <pcmcia/cs.h>
52 #include <pcmcia/cistpl.h>
53 #include <pcmcia/cisreg.h>
54 #include <pcmcia/ds.h>
55
56 /*
57    A linked list of "instances" of the dummy device.  Each actual
58    PCMCIA card corresponds to one device instance, and is described
59    by one dev_link_t structure (defined in ds.h).
60
61    You may not want to use a linked list for this -- for example, the
62    memory card driver uses an array of dev_link_t pointers, where minor
63    device numbers are used to derive the corresponding array index.
64 */
65
66 static dev_link_t *pcmcia_dev_list = NULL;
67
68 #define DIO24_SIZE 4    // size of io region used by board
69
70 static int dio24_attach(comedi_device *dev,comedi_devconfig *it);
71 static int dio24_detach(comedi_device *dev);
72
73 enum dio24_bustype {pcmcia_bustype};
74
75 typedef struct dio24_board_struct{
76         const char *name;
77         int device_id;  // device id for pcmcia board
78         enum dio24_bustype bustype;     // PCMCIA
79         int have_dio;   // have 8255 chip
80         // function pointers so we can use inb/outb or readb/writeb as appropriate
81         unsigned int (*read_byte)(unsigned int address);
82         void (*write_byte)(unsigned int byte, unsigned int address);
83 }dio24_board;
84
85
86 static dio24_board dio24_boards[] =
87 {
88         {
89                 name:   "daqcard-dio24",
90                 device_id:      0x475c, // 0x10b is manufacturer id, 0x475c is device id
91                 bustype:        pcmcia_bustype,
92                 have_dio:       1,
93         },
94         {
95                 name:   "ni_daq_dio24",
96                 device_id:      0x475c, // 0x10b is manufacturer id, 0x475c is device id
97                 bustype:        pcmcia_bustype,
98                 have_dio:       1,
99         },
100 };
101
102 /*
103  * Useful for shorthand access to the particular board structure
104  */
105 #define thisboard ((dio24_board *)dev->board_ptr)
106
107 typedef struct{
108         int data;  /* number of data points left to be taken */
109 }dio24_private;
110
111 #define devpriv ((dio24_private *)dev->private)
112
113 static comedi_driver driver_dio24={
114         driver_name:    "ni_daq_dio24",
115         module:         THIS_MODULE,
116         attach:         dio24_attach,
117         detach:         dio24_detach,
118         num_names:      sizeof(dio24_boards) / sizeof(dio24_board),
119         board_name:     &dio24_boards[0].name,
120         offset:         sizeof(dio24_board),
121 };
122
123 static int dio24_attach(comedi_device *dev, comedi_devconfig *it)
124 {
125         comedi_subdevice *s;
126         unsigned long iobase = 0;
127 #ifdef incomplete
128         unsigned int irq = 0;
129 #endif
130         dev_link_t *link;
131
132         /* allocate and initialize dev->private */
133         if(alloc_private(dev, sizeof(dio24_private)) < 0)
134                 return -ENOMEM;
135
136         // get base address, irq etc. based on bustype
137         switch(thisboard->bustype)
138         {
139                 case pcmcia_bustype:
140                         link = pcmcia_dev_list; /* XXX hack */
141                         if(!link) return -EIO;
142                         iobase = link->io.BasePort1;
143 #ifdef incomplete
144                         irq = link->irq.AssignedIRQ;
145 #endif
146                         break;
147                 default:
148                         printk("bug! couldn't determine board type\n");
149                         return -EINVAL;
150                         break;
151         }
152         printk("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor, thisboard->name, iobase);
153 #ifdef incomplete
154         if(irq)
155         {
156                 printk(", irq %u", irq);
157         }
158 #endif
159
160         printk("\n");
161
162         if(iobase == 0)
163         {
164                 printk("io base address is zero!\n");
165                 return -EINVAL;
166         }
167
168         dev->iobase = iobase;
169
170 #ifdef incomplete
171         /* grab our IRQ */
172         dev->irq = irq;
173 #endif
174
175         dev->board_name = thisboard->name;
176
177         if(alloc_subdevices(dev, 1) < 0)
178                 return -ENOMEM;
179
180         /* 8255 dio */
181         s = dev->subdevices + 0;
182         subdev_8255_init(dev, s, NULL, dev->iobase);
183
184         return 0;
185 };
186
187 static int dio24_detach(comedi_device *dev)
188 {
189         printk("comedi%d: ni_daq_dio24: remove\n", dev->minor);
190
191         if(dev->subdevices)
192                 subdev_8255_cleanup(dev,dev->subdevices + 0);
193
194         if(thisboard->bustype != pcmcia_bustype &&
195                 dev->iobase)
196                 release_region(dev->iobase, DIO24_SIZE);
197         if(dev->irq)
198                 comedi_free_irq(dev->irq, dev);
199
200         return 0;
201 };
202
203
204
205 // PCMCIA crap
206
207 /*
208    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
209    you do not define PCMCIA_DEBUG at all, all the debug code will be
210    left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
211    be present but disabled -- but it can then be enabled for specific
212    modules at load time with a 'pc_debug=#' option to insmod.
213 */
214 #ifdef PCMCIA_DEBUG
215 static int pc_debug = PCMCIA_DEBUG;
216 module_param(pc_debug, int, 0644);
217 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
218 static char *version =
219 "ni_daq_dio24.c, based on dummy_cs.c";
220 #else
221 #define DEBUG(n, args...)
222 #endif
223
224 /*====================================================================*/
225
226 static void dio24_config(dev_link_t *link);
227 static void dio24_release(u_long arg);
228 static int dio24_cs_suspend(struct pcmcia_device *p_dev);
229 static int dio24_cs_resume(struct pcmcia_device *p_dev);
230
231 /*
232    The attach() and detach() entry points are used to create and destroy
233    "instances" of the driver, where each instance represents everything
234    needed to manage one actual PCMCIA card.
235 */
236
237 static int dio24_cs_attach(struct pcmcia_device *);
238 static void dio24_cs_detach(struct pcmcia_device *);
239
240 /*
241    You'll also need to prototype all the functions that will actually
242    be used to talk to your device.  See 'memory_cs' for a good example
243    of a fully self-sufficient driver; the other drivers rely more or
244    less on other parts of the kernel.
245 */
246
247 /*
248    The dev_info variable is the "key" that is used to match up this
249    device driver with appropriate cards, through the card configuration
250    database.
251 */
252
253 static dev_info_t dev_info = "ni_daq_dio24";
254
255 /*
256    A dev_link_t structure has fields for most things that are needed
257    to keep track of a socket, but there will usually be some device
258    specific information that also needs to be kept track of.  The
259    'priv' pointer in a dev_link_t structure can be used to point to
260    a device-specific private data structure, like this.
261
262    To simplify the data structure handling, we actually include the
263    dev_link_t structure in the device's private data structure.
264
265    A driver needs to provide a dev_node_t structure for each device
266    on a card.  In some cases, there is only one device per card (for
267    example, ethernet cards, modems).  In other cases, there may be
268    many actual or logical devices (SCSI adapters, memory cards with
269    multiple partitions).  The dev_node_t structures need to be kept
270    in a linked list starting at the 'dev' field of a dev_link_t
271    structure.  We allocate them in the card's private data structure,
272    because they generally shouldn't be allocated dynamically.
273
274    In this case, we also provide a flag to indicate if a device is
275    "stopped" due to a power management event, or card ejection.  The
276    device IO routines can use a flag like this to throttle IO to a
277    card that is not ready to accept it.
278
279    The bus_operations pointer is used on platforms for which we need
280    to use special socket-specific versions of normal IO primitives
281    (inb, outb, readb, writeb, etc) for card IO.
282 */
283
284 typedef struct local_info_t {
285     dev_link_t          link;
286     dev_node_t          node;
287     int                 stop;
288     struct bus_operations *bus;
289 } local_info_t;
290
291 /*======================================================================
292
293     dio24_cs_attach() creates an "instance" of the driver, allocating
294     local data structures for one device.  The device is registered
295     with Card Services.
296
297     The dev_link structure is initialized, but we don't actually
298     configure the card at this point -- we wait until we receive a
299     card insertion event.
300
301 ======================================================================*/
302
303 static int dio24_cs_attach(struct pcmcia_device *p_dev)
304 {
305     local_info_t *local;
306     dev_link_t *link;
307
308     printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
309
310     DEBUG(0, "dio24_cs_attach()\n");
311
312     /* Allocate space for private device-specific data */
313     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
314     if (!local) return -ENOMEM;
315     memset(local, 0, sizeof(local_info_t));
316     link = &local->link; link->priv = local;
317
318     /* Interrupt setup */
319     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
320     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
321     link->irq.Handler = NULL;
322
323     /*
324       General socket configuration defaults can go here.  In this
325       client, we assume very little, and rely on the CIS for almost
326       everything.  In most clients, many details (i.e., number, sizes,
327       and attributes of IO windows) are fixed by the nature of the
328       device, and can be hard-wired here.
329     */
330     link->conf.Attributes = 0;
331     link->conf.Vcc = 50;
332     link->conf.IntType = INT_MEMORY_AND_IO;
333
334     link->next = pcmcia_dev_list;
335     pcmcia_dev_list = link;
336
337     link->handle = p_dev;
338     p_dev->instance = link;
339     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
340     dio24_config(link);
341
342     return 0;
343 } /* dio24_cs_attach */
344
345 /*======================================================================
346
347     This deletes a driver "instance".  The device is de-registered
348     with Card Services.  If it has been released, all local data
349     structures are freed.  Otherwise, the structures will be freed
350     when the device is released.
351
352 ======================================================================*/
353
354 static void dio24_cs_detach(struct pcmcia_device *p_dev)
355 {
356     dev_link_t *link = dev_to_instance(p_dev);
357     dev_link_t **linkp;
358
359     printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
360
361     DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
362
363     /* Locate device structure */
364     for (linkp = &pcmcia_dev_list; *linkp; linkp = &(*linkp)->next)
365         if (*linkp == link) break;
366     if (*linkp == NULL)
367         return;
368
369     /*
370        If the device is currently configured and active, we won't
371        actually delete it yet.  Instead, it is marked so that when
372        the release() function is called, that will trigger a proper
373        detach().
374     */
375     if (link->state & DEV_CONFIG) {
376         ((local_info_t *)link->priv)->stop = 1;
377         dio24_release((u_long)link);
378     }
379
380     /* Unlink device structure, and free it */
381     *linkp = link->next;
382     /* This points to the parent local_info_t struct */
383     kfree(link->priv);
384
385 } /* dio24_cs_detach */
386
387 /*======================================================================
388
389     dio24_config() is scheduled to run after a CARD_INSERTION event
390     is received, to configure the PCMCIA socket, and to make the
391     device available to the system.
392
393 ======================================================================*/
394
395
396 static void dio24_config(dev_link_t *link)
397 {
398     client_handle_t handle = link->handle;
399     local_info_t *dev = link->priv;
400     tuple_t tuple;
401     cisparse_t parse;
402     int last_ret;
403     u_char buf[64];
404     config_info_t conf;
405     win_req_t req;
406     memreq_t map;
407     cistpl_cftable_entry_t dflt = { 0 };
408
409     printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
410
411     DEBUG(0, "dio24_config(0x%p)\n", link);
412
413     /*
414        This reads the card's CONFIG tuple to find its configuration
415        registers.
416     */
417     tuple.DesiredTuple = CISTPL_CONFIG;
418     tuple.Attributes = 0;
419     tuple.TupleData = buf;
420     tuple.TupleDataMax = sizeof(buf);
421     tuple.TupleOffset = 0;
422         if((last_ret = pcmcia_get_first_tuple(handle, &tuple)) != 0)
423         {
424             cs_error(handle, GetFirstTuple, last_ret);
425                 goto cs_failed;
426         }
427         if((last_ret = pcmcia_get_tuple_data(handle, &tuple)) != 0)
428         {
429             cs_error(handle, GetTupleData, last_ret);
430                 goto cs_failed;
431         }
432         if((last_ret = pcmcia_parse_tuple(handle, &tuple, &parse)) != 0)
433         {
434             cs_error(handle, ParseTuple, last_ret);
435                 goto cs_failed;
436         }
437     link->conf.ConfigBase = parse.config.base;
438     link->conf.Present = parse.config.rmask[0];
439
440     /* Configure card */
441     link->state |= DEV_CONFIG;
442
443     /* Look up the current Vcc */
444         if((last_ret = pcmcia_get_configuration_info(handle, &conf)) != 0)
445         {
446             cs_error(handle, GetConfigurationInfo, last_ret);
447                 goto cs_failed;
448         }
449     link->conf.Vcc = conf.Vcc;
450
451     /*
452       In this loop, we scan the CIS for configuration table entries,
453       each of which describes a valid card configuration, including
454       voltage, IO window, memory window, and interrupt settings.
455
456       We make no assumptions about the card to be configured: we use
457       just the information available in the CIS.  In an ideal world,
458       this would work for any PCMCIA card, but it requires a complete
459       and accurate CIS.  In practice, a driver usually "knows" most of
460       these things without consulting the CIS, and most client drivers
461       will only use the CIS to fill in implementation-defined details.
462     */
463     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
464         if((last_ret = pcmcia_get_first_tuple(handle, &tuple)) != 0)
465         {
466             cs_error(handle, GetFirstTuple, last_ret);
467                 goto cs_failed;
468         }
469     while (1) {
470         cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
471         if(pcmcia_get_tuple_data(handle, &tuple) != 0) goto next_entry;
472         if(pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry;
473
474         if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
475         if (cfg->index == 0) goto next_entry;
476         link->conf.ConfigIndex = cfg->index;
477
478         /* Does this card need audio output? */
479         if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
480             link->conf.Attributes |= CONF_ENABLE_SPKR;
481             link->conf.Status = CCSR_AUDIO_ENA;
482         }
483
484         /* Use power settings for Vcc and Vpp if present */
485         /*  Note that the CIS values need to be rescaled */
486         if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
487             if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
488                 goto next_entry;
489         } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
490             if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
491                 goto next_entry;
492         }
493
494         if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
495             link->conf.Vpp1 = link->conf.Vpp2 =
496                 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
497         else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
498             link->conf.Vpp1 = link->conf.Vpp2 =
499                 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
500
501         /* Do we need to allocate an interrupt? */
502         if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
503             link->conf.Attributes |= CONF_ENABLE_IRQ;
504
505         /* IO window settings */
506         link->io.NumPorts1 = link->io.NumPorts2 = 0;
507         if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
508             cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
509             link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
510             if (!(io->flags & CISTPL_IO_8BIT))
511                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
512             if (!(io->flags & CISTPL_IO_16BIT))
513                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
514             link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
515             link->io.BasePort1 = io->win[0].base;
516             link->io.NumPorts1 = io->win[0].len;
517             if (io->nwin > 1) {
518                 link->io.Attributes2 = link->io.Attributes1;
519                 link->io.BasePort2 = io->win[1].base;
520                 link->io.NumPorts2 = io->win[1].len;
521             }
522             /* This reserves IO space but doesn't actually enable it */
523                 if(pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry;
524         }
525
526         /*
527           Now set up a common memory window, if needed.  There is room
528           in the dev_link_t structure for one memory window handle,
529           but if the base addresses need to be saved, or if multiple
530           windows are needed, the info should go in the private data
531           structure for this device.
532
533           Note that the memory window base is a physical address, and
534           needs to be mapped to virtual space with ioremap() before it
535           is used.
536         */
537         if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
538             cistpl_mem_t *mem =
539                 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
540             req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
541             req.Attributes |= WIN_ENABLE;
542             req.Base = mem->win[0].host_addr;
543             req.Size = mem->win[0].len;
544             if (req.Size < 0x1000)
545                 req.Size = 0x1000;
546             req.AccessSpeed = 0;
547                 if(pcmcia_request_window(&link->handle, &req, &link->win)) goto next_entry;
548             map.Page = 0; map.CardOffset = mem->win[0].card_addr;
549                 if(pcmcia_map_mem_page(link->win, &map)) goto next_entry;
550         }
551         /* If we got this far, we're cool! */
552         break;
553
554     next_entry:
555         if (link->io.NumPorts1)
556                 pcmcia_release_io(link->handle, &link->io);
557         if((last_ret = pcmcia_get_next_tuple(link->handle, &tuple)) != 0)
558         {
559             cs_error(handle, GetNextTuple, last_ret);
560                 goto cs_failed;
561         }
562     }
563
564     /*
565        Allocate an interrupt line.  Note that this does not assign a
566        handler to the interrupt, unless the 'Handler' member of the
567        irq structure is initialized.
568     */
569     if (link->conf.Attributes & CONF_ENABLE_IRQ)
570                 if((last_ret = pcmcia_request_irq(link->handle, &link->irq)) != 0)
571                 {
572                     cs_error(handle, RequestIRQ, last_ret);
573                         goto cs_failed;
574                 }
575
576     /*
577        This actually configures the PCMCIA socket -- setting up
578        the I/O windows and the interrupt mapping, and putting the
579        card and host interface into "Memory and IO" mode.
580     */
581         if((last_ret = pcmcia_request_configuration(link->handle, &link->conf)) != 0)
582         {
583                 cs_error(handle, RequestConfiguration, last_ret);
584                 goto cs_failed;
585         }
586
587     /*
588       At this point, the dev_node_t structure(s) need to be
589       initialized and arranged in a linked list at link->dev.
590     */
591     sprintf(dev->node.dev_name, "ni_daq_dio24");
592     dev->node.major = dev->node.minor = 0;
593     link->dev = &dev->node;
594
595     /* Finally, report what we've done */
596     printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
597            dev->node.dev_name, link->conf.ConfigIndex,
598            link->conf.Vcc/10, link->conf.Vcc%10);
599     if (link->conf.Vpp1)
600         printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
601     if (link->conf.Attributes & CONF_ENABLE_IRQ)
602         printk(", irq %d", link->irq.AssignedIRQ);
603     if (link->io.NumPorts1)
604         printk(", io 0x%04x-0x%04x", link->io.BasePort1,
605                link->io.BasePort1+link->io.NumPorts1-1);
606     if (link->io.NumPorts2)
607         printk(" & 0x%04x-0x%04x", link->io.BasePort2,
608                link->io.BasePort2+link->io.NumPorts2-1);
609     if (link->win)
610         printk(", mem 0x%06lx-0x%06lx", req.Base,
611                req.Base+req.Size-1);
612     printk("\n");
613
614     link->state &= ~DEV_CONFIG_PENDING;
615     return;
616
617 cs_failed:
618     printk(KERN_INFO "Fallo");
619     dio24_release((u_long)link);
620
621 } /* dio24_config */
622
623 /*======================================================================
624
625     After a card is removed, dio24_release() will unregister the
626     device, and release the PCMCIA configuration.  If the device is
627     still open, this will be postponed until it is closed.
628
629 ======================================================================*/
630
631 static void dio24_release(u_long arg)
632 {
633     dev_link_t *link = (dev_link_t *)arg;
634
635     DEBUG(0, "dio24_release(0x%p)\n", link);
636
637     /* Unlink the device chain */
638     link->dev = NULL;
639
640     /*
641       In a normal driver, additional code may be needed to release
642       other kernel data structures associated with this device.
643     */
644
645     /* Don't bother checking to see if these succeed or not */
646     if (link->win)
647                 pcmcia_release_window(link->win);
648     pcmcia_release_configuration(link->handle);
649     if (link->io.NumPorts1)
650                 pcmcia_release_io(link->handle, &link->io);
651     if (link->irq.AssignedIRQ)
652                 pcmcia_release_irq(link->handle, &link->irq);
653     link->state &= ~DEV_CONFIG;
654
655 } /* dio24_release */
656
657 /*======================================================================
658
659     The card status event handler.  Mostly, this schedules other
660     stuff to run after an event is received.
661
662     When a CARD_REMOVAL event is received, we immediately set a
663     private flag to block future accesses to this device.  All the
664     functions that actually access the device should check this flag
665     to make sure the card is still present.
666
667 ======================================================================*/
668
669
670 static int dio24_cs_suspend(struct pcmcia_device *p_dev)
671 {
672         dev_link_t *link = dev_to_instance(p_dev);
673         local_info_t *local = link->priv;
674
675         link->state |= DEV_SUSPEND;
676         /* Mark the device as stopped, to block IO until later */
677         local->stop = 1;
678         if (link->state & DEV_CONFIG)
679                 pcmcia_release_configuration(link->handle);
680
681         return 0;
682 } /* dio24_cs_suspend */
683
684 static int dio24_cs_resume(struct pcmcia_device *p_dev)
685 {
686         dev_link_t *link = dev_to_instance(p_dev);
687         local_info_t *local = link->priv;
688
689         link->state &= ~DEV_SUSPEND;
690         if (link->state & DEV_CONFIG)
691                 pcmcia_request_configuration(link->handle, &link->conf);
692         local->stop = 0;
693         return 0;
694 } /* dio24_cs_resume */
695
696 /*====================================================================*/
697
698 static struct pcmcia_device_id dio24_cs_ids[] =
699 {
700         /* N.B. These IDs should match those in dio24_boards */
701         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c),        /* daqcard-dio24 */
702         PCMCIA_DEVICE_NULL
703 };
704
705 MODULE_DEVICE_TABLE(pcmcia, dio24_cs_ids);
706
707 struct pcmcia_driver dio24_cs_driver =
708 {
709         .probe = dio24_cs_attach,
710         .remove = dio24_cs_detach,
711         .suspend = dio24_cs_suspend,
712         .resume = dio24_cs_resume,
713         .id_table = dio24_cs_ids,
714         .owner = THIS_MODULE,
715         .drv = {
716                 .name = dev_info,
717         },      
718 };
719
720 static int __init init_dio24_cs(void)
721 {
722     printk("ni_daq_dio24: HOLA SOY YO!\n");
723     DEBUG(0, "%s\n", version);
724         pcmcia_register_driver(&dio24_cs_driver);
725     return 0;
726 }
727
728 static void __exit exit_dio24_cs(void)
729 {
730     DEBUG(0, "ni_dio24: unloading\n");
731         pcmcia_unregister_driver(&dio24_cs_driver);
732     while (pcmcia_dev_list != NULL) {
733                 if (pcmcia_dev_list->state & DEV_CONFIG)
734                         dio24_release((u_long)pcmcia_dev_list);
735                 dio24_cs_detach(pcmcia_dev_list->handle);
736     }
737 }
738
739 int __init init_module(void)
740 {
741         int ret;
742
743         ret = init_dio24_cs();
744         if(ret < 0)
745                 return ret;
746
747         return comedi_driver_register(&driver_dio24);
748 }
749
750 void __exit cleanup_module(void)
751 {
752         exit_dio24_cs();
753         comedi_driver_unregister(&driver_dio24);
754 }
755