ni_daq_700.c revision 34c43922e62708d45e9660eee4b4f1fb7b4bf2c7
1/*
2 *     comedi/drivers/ni_daq_700.c
3 *     Driver for DAQCard-700 DIO only
4 *     copied from 8255
5 *
6 *     COMEDI - Linux Control and Measurement Device Interface
7 *     Copyright (C) 1998 David A. Schleef <ds@schleef.org>
8 *
9 *     This program is free software; you can redistribute it and/or modify
10 *     it under the terms of the GNU General Public License as published by
11 *     the Free Software Foundation; either version 2 of the License, or
12 *     (at your option) any later version.
13 *
14 *     This program is distributed in the hope that it will be useful,
15 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *     GNU General Public License for more details.
18 *
19 *     You should have received a copy of the GNU General Public License
20 *     along with this program; if not, write to the Free Software
21 *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25/*
26Driver: ni_daq_700
27Description: National Instruments PCMCIA DAQCard-700 DIO only
28Author: Fred Brooks <nsaspook@nsaspook.com>,
29  based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
30Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
31Status: works
32Updated: Thu, 21 Feb 2008 12:07:20 +0000
33
34The daqcard-700 appears in Comedi as a single digital I/O subdevice with
3516 channels.  The channel 0 corresponds to the daqcard-700's output
36port, bit 0; channel 8 corresponds to the input port, bit 0.
37
38Direction configuration: channels 0-7 output, 8-15 input (8225 device
39emu as port A output, port B input, port C N/A).
40
41IRQ is assigned but not used.
42*/
43
44#include "../comedidev.h"
45
46#include <linux/ioport.h>
47
48#include <pcmcia/cs_types.h>
49#include <pcmcia/cs.h>
50#include <pcmcia/cistpl.h>
51#include <pcmcia/cisreg.h>
52#include <pcmcia/ds.h>
53
54static struct pcmcia_device *pcmcia_cur_dev = NULL;
55
56#define DIO700_SIZE 8		// size of io region used by board
57
58static int dio700_attach(struct comedi_device * dev, comedi_devconfig * it);
59static int dio700_detach(struct comedi_device * dev);
60
61enum dio700_bustype { pcmcia_bustype };
62
63typedef struct dio700_board_struct {
64	const char *name;
65	int device_id;		// device id for pcmcia board
66	enum dio700_bustype bustype;	// PCMCIA
67	int have_dio;		// have daqcard-700 dio
68	// function pointers so we can use inb/outb or readb/writeb
69	// as appropriate
70	unsigned int (*read_byte) (unsigned int address);
71	void (*write_byte) (unsigned int byte, unsigned int address);
72} dio700_board;
73
74static const dio700_board dio700_boards[] = {
75	{
76	      name:	"daqcard-700",
77	      device_id:0x4743,// 0x10b is manufacturer id, 0x4743 is device id
78	      bustype:	pcmcia_bustype,
79	      have_dio:1,
80		},
81	{
82	      name:	"ni_daq_700",
83	      device_id:0x4743,// 0x10b is manufacturer id, 0x4743 is device id
84	      bustype:	pcmcia_bustype,
85	      have_dio:1,
86		},
87};
88
89/*
90 * Useful for shorthand access to the particular board structure
91 */
92#define thisboard ((const dio700_board *)dev->board_ptr)
93
94typedef struct {
95	int data;		/* number of data points left to be taken */
96} dio700_private;
97
98#define devpriv ((dio700_private *)dev->private)
99
100static comedi_driver driver_dio700 = {
101      driver_name:"ni_daq_700",
102      module:THIS_MODULE,
103      attach:dio700_attach,
104      detach:dio700_detach,
105      num_names:sizeof(dio700_boards) / sizeof(dio700_board),
106      board_name:&dio700_boards[0].name,
107      offset:sizeof(dio700_board),
108};
109
110/*	the real driver routines	*/
111
112#define _700_SIZE 8
113
114#define _700_DATA 0
115
116#define DIO_W		0x04
117#define DIO_R		0x05
118
119struct subdev_700_struct {
120	unsigned long cb_arg;
121	int (*cb_func) (int, int, int, unsigned long);
122	int have_irq;
123};
124
125#define CALLBACK_ARG	(((struct subdev_700_struct *)s->private)->cb_arg)
126#define CALLBACK_FUNC	(((struct subdev_700_struct *)s->private)->cb_func)
127#define subdevpriv	((struct subdev_700_struct *)s->private)
128
129static void do_config(struct comedi_device * dev, struct comedi_subdevice * s);
130
131void subdev_700_interrupt(struct comedi_device * dev, struct comedi_subdevice * s)
132{
133	short d;
134
135	d = CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG);
136
137	comedi_buf_put(s->async, d);
138	s->async->events |= COMEDI_CB_EOS;
139
140	comedi_event(dev, s);
141}
142
143static int subdev_700_cb(int dir, int port, int data, unsigned long arg)
144{
145	/* port is always A for output and B for input (8255 emu) */
146	unsigned long iobase = arg;
147
148	if (dir) {
149		outb(data, iobase + DIO_W);
150		return 0;
151	} else {
152		return inb(iobase + DIO_R);
153	}
154}
155
156static int subdev_700_insn(struct comedi_device * dev, struct comedi_subdevice * s,
157	comedi_insn * insn, unsigned int * data)
158{
159	if (data[0]) {
160		s->state &= ~data[0];
161		s->state |= (data[0] & data[1]);
162
163		if (data[0] & 0xff)
164			CALLBACK_FUNC(1, _700_DATA, s->state & 0xff,
165				CALLBACK_ARG);
166	}
167
168	data[1] = s->state & 0xff;
169	data[1] |= CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG) << 8;
170
171	return 2;
172}
173
174static int subdev_700_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
175	comedi_insn * insn, unsigned int * data)
176{
177
178	switch (data[0]) {
179	case INSN_CONFIG_DIO_INPUT:
180		break;
181	case INSN_CONFIG_DIO_OUTPUT:
182		break;
183	case INSN_CONFIG_DIO_QUERY:
184		data[1] =
185			(s->io_bits & (1 << CR_CHAN(insn->
186					chanspec))) ? COMEDI_OUTPUT :
187			COMEDI_INPUT;
188		return insn->n;
189		break;
190	default:
191		return -EINVAL;
192	}
193
194	return 1;
195}
196
197static void do_config(struct comedi_device * dev, struct comedi_subdevice * s)
198{				/* use powerup defaults */
199	return;
200}
201
202static int subdev_700_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
203	comedi_cmd * cmd)
204{
205	int err = 0;
206	unsigned int tmp;
207
208	/* step 1 */
209
210	tmp = cmd->start_src;
211	cmd->start_src &= TRIG_NOW;
212	if (!cmd->start_src || tmp != cmd->start_src)
213		err++;
214
215	tmp = cmd->scan_begin_src;
216	cmd->scan_begin_src &= TRIG_EXT;
217	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
218		err++;
219
220	tmp = cmd->convert_src;
221	cmd->convert_src &= TRIG_FOLLOW;
222	if (!cmd->convert_src || tmp != cmd->convert_src)
223		err++;
224
225	tmp = cmd->scan_end_src;
226	cmd->scan_end_src &= TRIG_COUNT;
227	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
228		err++;
229
230	tmp = cmd->stop_src;
231	cmd->stop_src &= TRIG_NONE;
232	if (!cmd->stop_src || tmp != cmd->stop_src)
233		err++;
234
235	if (err)
236		return 1;
237
238	/* step 2 */
239
240	if (err)
241		return 2;
242
243	/* step 3 */
244
245	if (cmd->start_arg != 0) {
246		cmd->start_arg = 0;
247		err++;
248	}
249	if (cmd->scan_begin_arg != 0) {
250		cmd->scan_begin_arg = 0;
251		err++;
252	}
253	if (cmd->convert_arg != 0) {
254		cmd->convert_arg = 0;
255		err++;
256	}
257	if (cmd->scan_end_arg != 1) {
258		cmd->scan_end_arg = 1;
259		err++;
260	}
261	if (cmd->stop_arg != 0) {
262		cmd->stop_arg = 0;
263		err++;
264	}
265
266	if (err)
267		return 3;
268
269	/* step 4 */
270
271	if (err)
272		return 4;
273
274	return 0;
275}
276
277static int subdev_700_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
278{
279	/* FIXME */
280
281	return 0;
282}
283
284static int subdev_700_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
285{
286	/* FIXME */
287
288	return 0;
289}
290
291int subdev_700_init(struct comedi_device * dev, struct comedi_subdevice * s, int (*cb) (int,
292		int, int, unsigned long), unsigned long arg)
293{
294	s->type = COMEDI_SUBD_DIO;
295	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
296	s->n_chan = 16;
297	s->range_table = &range_digital;
298	s->maxdata = 1;
299
300	s->private = kmalloc(sizeof(struct subdev_700_struct), GFP_KERNEL);
301	if (!s->private)
302		return -ENOMEM;
303
304	CALLBACK_ARG = arg;
305	if (cb == NULL) {
306		CALLBACK_FUNC = subdev_700_cb;
307	} else {
308		CALLBACK_FUNC = cb;
309	}
310	s->insn_bits = subdev_700_insn;
311	s->insn_config = subdev_700_insn_config;
312
313	s->state = 0;
314	s->io_bits = 0x00ff;
315	do_config(dev, s);
316
317	return 0;
318}
319
320int subdev_700_init_irq(struct comedi_device * dev, struct comedi_subdevice * s,
321	int (*cb) (int, int, int, unsigned long), unsigned long arg)
322{
323	int ret;
324
325	ret = subdev_700_init(dev, s, cb, arg);
326	if (ret < 0)
327		return ret;
328
329	s->do_cmdtest = subdev_700_cmdtest;
330	s->do_cmd = subdev_700_cmd;
331	s->cancel = subdev_700_cancel;
332
333	subdevpriv->have_irq = 1;
334
335	return 0;
336}
337
338void subdev_700_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
339{
340	if (s->private) {
341		if (subdevpriv->have_irq) {
342		}
343
344		kfree(s->private);
345	}
346}
347
348EXPORT_SYMBOL(subdev_700_init);
349EXPORT_SYMBOL(subdev_700_init_irq);
350EXPORT_SYMBOL(subdev_700_cleanup);
351EXPORT_SYMBOL(subdev_700_interrupt);
352
353static int dio700_attach(struct comedi_device * dev, comedi_devconfig * it)
354{
355	struct comedi_subdevice *s;
356	unsigned long iobase = 0;
357#ifdef incomplete
358	unsigned int irq = 0;
359#endif
360	struct pcmcia_device *link;
361
362	/* allocate and initialize dev->private */
363	if (alloc_private(dev, sizeof(dio700_private)) < 0)
364		return -ENOMEM;
365
366	// get base address, irq etc. based on bustype
367	switch (thisboard->bustype) {
368	case pcmcia_bustype:
369		link = pcmcia_cur_dev;	/* XXX hack */
370		if (!link)
371			return -EIO;
372		iobase = link->io.BasePort1;
373#ifdef incomplete
374		irq = link->irq.AssignedIRQ;
375#endif
376		break;
377	default:
378		printk("bug! couldn't determine board type\n");
379		return -EINVAL;
380		break;
381	}
382	printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor,
383		thisboard->name, iobase);
384#ifdef incomplete
385	if (irq) {
386		printk(", irq %u", irq);
387	}
388#endif
389
390	printk("\n");
391
392	if (iobase == 0) {
393		printk("io base address is zero!\n");
394		return -EINVAL;
395	}
396
397	dev->iobase = iobase;
398
399#ifdef incomplete
400	/* grab our IRQ */
401	dev->irq = irq;
402#endif
403
404	dev->board_name = thisboard->name;
405
406	if (alloc_subdevices(dev, 1) < 0)
407		return -ENOMEM;
408
409	/* DAQCard-700 dio */
410	s = dev->subdevices + 0;
411	subdev_700_init(dev, s, NULL, dev->iobase);
412
413	return 0;
414};
415
416static int dio700_detach(struct comedi_device * dev)
417{
418	printk("comedi%d: ni_daq_700: cs-remove\n", dev->minor);
419
420	if (dev->subdevices)
421		subdev_700_cleanup(dev, dev->subdevices + 0);
422
423	if (thisboard->bustype != pcmcia_bustype && dev->iobase)
424		release_region(dev->iobase, DIO700_SIZE);
425	if (dev->irq)
426		comedi_free_irq(dev->irq, dev);
427
428	return 0;
429};
430
431// PCMCIA crap
432
433/*
434   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
435   you do not define PCMCIA_DEBUG at all, all the debug code will be
436   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
437   be present but disabled -- but it can then be enabled for specific
438   modules at load time with a 'pc_debug=#' option to insmod.
439*/
440#ifdef PCMCIA_DEBUG
441static int pc_debug = PCMCIA_DEBUG;
442module_param(pc_debug, int, 0644);
443#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
444static char *version = "ni_daq_700.c, based on dummy_cs.c";
445#else
446#define DEBUG(n, args...)
447#endif
448
449/*====================================================================*/
450
451static void dio700_config(struct pcmcia_device *link);
452static void dio700_release(struct pcmcia_device *link);
453static int dio700_cs_suspend(struct pcmcia_device *p_dev);
454static int dio700_cs_resume(struct pcmcia_device *p_dev);
455
456/*
457   The attach() and detach() entry points are used to create and destroy
458   "instances" of the driver, where each instance represents everything
459   needed to manage one actual PCMCIA card.
460*/
461
462static int dio700_cs_attach(struct pcmcia_device *);
463static void dio700_cs_detach(struct pcmcia_device *);
464
465/*
466   You'll also need to prototype all the functions that will actually
467   be used to talk to your device.  See 'memory_cs' for a good example
468   of a fully self-sufficient driver; the other drivers rely more or
469   less on other parts of the kernel.
470*/
471
472/*
473   The dev_info variable is the "key" that is used to match up this
474   device driver with appropriate cards, through the card configuration
475   database.
476*/
477
478static const dev_info_t dev_info = "ni_daq_700";
479
480typedef struct local_info_t {
481	struct pcmcia_device *link;
482	dev_node_t node;
483	int stop;
484	struct bus_operations *bus;
485} local_info_t;
486
487/*======================================================================
488
489    dio700_cs_attach() creates an "instance" of the driver, allocating
490    local data structures for one device.  The device is registered
491    with Card Services.
492
493    The dev_link structure is initialized, but we don't actually
494    configure the card at this point -- we wait until we receive a
495    card insertion event.
496
497======================================================================*/
498
499static int dio700_cs_attach(struct pcmcia_device *link)
500{
501	local_info_t *local;
502
503	printk(KERN_INFO "ni_daq_700:  cs-attach\n");
504
505	DEBUG(0, "dio700_cs_attach()\n");
506
507	/* Allocate space for private device-specific data */
508	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
509	if (!local)
510		return -ENOMEM;
511	local->link = link;
512	link->priv = local;
513
514	/* Interrupt setup */
515	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
516	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
517	link->irq.Handler = NULL;
518
519	/*
520	   General socket configuration defaults can go here.  In this
521	   client, we assume very little, and rely on the CIS for almost
522	   everything.  In most clients, many details (i.e., number, sizes,
523	   and attributes of IO windows) are fixed by the nature of the
524	   device, and can be hard-wired here.
525	 */
526	link->conf.Attributes = 0;
527	link->conf.IntType = INT_MEMORY_AND_IO;
528
529	pcmcia_cur_dev = link;
530
531	dio700_config(link);
532
533	return 0;
534}				/* dio700_cs_attach */
535
536/*======================================================================
537
538    This deletes a driver "instance".  The device is de-registered
539    with Card Services.  If it has been released, all local data
540    structures are freed.  Otherwise, the structures will be freed
541    when the device is released.
542
543======================================================================*/
544
545static void dio700_cs_detach(struct pcmcia_device *link)
546{
547
548	printk(KERN_INFO "ni_daq_700: cs-detach!\n");
549
550	DEBUG(0, "dio700_cs_detach(0x%p)\n", link);
551
552	if (link->dev_node) {
553		((local_info_t *) link->priv)->stop = 1;
554		dio700_release(link);
555	}
556
557	/* This points to the parent local_info_t struct */
558	if (link->priv)
559		kfree(link->priv);
560
561}				/* dio700_cs_detach */
562
563/*======================================================================
564
565    dio700_config() is scheduled to run after a CARD_INSERTION event
566    is received, to configure the PCMCIA socket, and to make the
567    device available to the system.
568
569======================================================================*/
570
571static void dio700_config(struct pcmcia_device *link)
572{
573	local_info_t *dev = link->priv;
574	tuple_t tuple;
575	cisparse_t parse;
576	int last_ret;
577	u_char buf[64];
578	win_req_t req;
579	memreq_t map;
580	cistpl_cftable_entry_t dflt = { 0 };
581
582	printk(KERN_INFO "ni_daq_700:  cs-config\n");
583
584	DEBUG(0, "dio700_config(0x%p)\n", link);
585
586	/*
587	   This reads the card's CONFIG tuple to find its configuration
588	   registers.
589	 */
590	tuple.DesiredTuple = CISTPL_CONFIG;
591	tuple.Attributes = 0;
592	tuple.TupleData = buf;
593	tuple.TupleDataMax = sizeof(buf);
594	tuple.TupleOffset = 0;
595	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
596		cs_error(link, GetFirstTuple, last_ret);
597		goto cs_failed;
598	}
599	if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
600		cs_error(link, GetTupleData, last_ret);
601		goto cs_failed;
602	}
603	if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
604		cs_error(link, ParseTuple, last_ret);
605		goto cs_failed;
606	}
607	link->conf.ConfigBase = parse.config.base;
608	link->conf.Present = parse.config.rmask[0];
609
610	/*
611	   In this loop, we scan the CIS for configuration table entries,
612	   each of which describes a valid card configuration, including
613	   voltage, IO window, memory window, and interrupt settings.
614
615	   We make no assumptions about the card to be configured: we use
616	   just the information available in the CIS.  In an ideal world,
617	   this would work for any PCMCIA card, but it requires a complete
618	   and accurate CIS.  In practice, a driver usually "knows" most of
619	   these things without consulting the CIS, and most client drivers
620	   will only use the CIS to fill in implementation-defined details.
621	 */
622	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
623	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
624		cs_error(link, GetFirstTuple, last_ret);
625		goto cs_failed;
626	}
627	while (1) {
628		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
629		if (pcmcia_get_tuple_data(link, &tuple) != 0)
630			goto next_entry;
631		if (pcmcia_parse_tuple(&tuple, &parse) != 0)
632			goto next_entry;
633
634		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
635			dflt = *cfg;
636		if (cfg->index == 0)
637			goto next_entry;
638		link->conf.ConfigIndex = cfg->index;
639
640		/* Does this card need audio output? */
641		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
642			link->conf.Attributes |= CONF_ENABLE_SPKR;
643			link->conf.Status = CCSR_AUDIO_ENA;
644		}
645
646		/* Do we need to allocate an interrupt? */
647		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
648			link->conf.Attributes |= CONF_ENABLE_IRQ;
649
650		/* IO window settings */
651		link->io.NumPorts1 = link->io.NumPorts2 = 0;
652		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
653			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
654			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
655			if (!(io->flags & CISTPL_IO_8BIT))
656				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
657			if (!(io->flags & CISTPL_IO_16BIT))
658				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
659			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
660			link->io.BasePort1 = io->win[0].base;
661			link->io.NumPorts1 = io->win[0].len;
662			if (io->nwin > 1) {
663				link->io.Attributes2 = link->io.Attributes1;
664				link->io.BasePort2 = io->win[1].base;
665				link->io.NumPorts2 = io->win[1].len;
666			}
667			/* This reserves IO space but doesn't actually enable it */
668			if (pcmcia_request_io(link, &link->io) != 0)
669				goto next_entry;
670		}
671
672		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
673			cistpl_mem_t *mem =
674				(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
675			req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
676			req.Attributes |= WIN_ENABLE;
677			req.Base = mem->win[0].host_addr;
678			req.Size = mem->win[0].len;
679			if (req.Size < 0x1000)
680				req.Size = 0x1000;
681			req.AccessSpeed = 0;
682			if (pcmcia_request_window(&link, &req, &link->win))
683				goto next_entry;
684			map.Page = 0;
685			map.CardOffset = mem->win[0].card_addr;
686			if (pcmcia_map_mem_page(link->win, &map))
687				goto next_entry;
688		}
689		/* If we got this far, we're cool! */
690		break;
691
692	      next_entry:
693		if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
694			cs_error(link, GetNextTuple, last_ret);
695			goto cs_failed;
696		}
697	}
698
699	/*
700	   Allocate an interrupt line.  Note that this does not assign a
701	   handler to the interrupt, unless the 'Handler' member of the
702	   irq structure is initialized.
703	 */
704	if (link->conf.Attributes & CONF_ENABLE_IRQ)
705		if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
706			cs_error(link, RequestIRQ, last_ret);
707			goto cs_failed;
708		}
709
710	/*
711	   This actually configures the PCMCIA socket -- setting up
712	   the I/O windows and the interrupt mapping, and putting the
713	   card and host interface into "Memory and IO" mode.
714	 */
715	if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
716		cs_error(link, RequestConfiguration, last_ret);
717		goto cs_failed;
718	}
719
720	/*
721	   At this point, the dev_node_t structure(s) need to be
722	   initialized and arranged in a linked list at link->dev.
723	 */
724	sprintf(dev->node.dev_name, "ni_daq_700");
725	dev->node.major = dev->node.minor = 0;
726	link->dev_node = &dev->node;
727
728	/* Finally, report what we've done */
729	printk(KERN_INFO "%s: index 0x%02x",
730		dev->node.dev_name, link->conf.ConfigIndex);
731	if (link->conf.Attributes & CONF_ENABLE_IRQ)
732		printk(", irq %d", link->irq.AssignedIRQ);
733	if (link->io.NumPorts1)
734		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
735			link->io.BasePort1 + link->io.NumPorts1 - 1);
736	if (link->io.NumPorts2)
737		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
738			link->io.BasePort2 + link->io.NumPorts2 - 1);
739	if (link->win)
740		printk(", mem 0x%06lx-0x%06lx", req.Base,
741			req.Base + req.Size - 1);
742	printk("\n");
743
744	return;
745
746      cs_failed:
747	printk(KERN_INFO "ni_daq_700 cs failed");
748	dio700_release(link);
749
750}				/* dio700_config */
751
752static void dio700_release(struct pcmcia_device *link)
753{
754	DEBUG(0, "dio700_release(0x%p)\n", link);
755
756	pcmcia_disable_device(link);
757}				/* dio700_release */
758
759/*======================================================================
760
761    The card status event handler.  Mostly, this schedules other
762    stuff to run after an event is received.
763
764    When a CARD_REMOVAL event is received, we immediately set a
765    private flag to block future accesses to this device.  All the
766    functions that actually access the device should check this flag
767    to make sure the card is still present.
768
769======================================================================*/
770
771static int dio700_cs_suspend(struct pcmcia_device *link)
772{
773	local_info_t *local = link->priv;
774
775	/* Mark the device as stopped, to block IO until later */
776	local->stop = 1;
777	return 0;
778}				/* dio700_cs_suspend */
779
780static int dio700_cs_resume(struct pcmcia_device *link)
781{
782	local_info_t *local = link->priv;
783
784	local->stop = 0;
785	return 0;
786}				/* dio700_cs_resume */
787
788/*====================================================================*/
789
790static struct pcmcia_device_id dio700_cs_ids[] = {
791	/* N.B. These IDs should match those in dio700_boards */
792	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743),	/* daqcard-700 */
793	PCMCIA_DEVICE_NULL
794};
795
796MODULE_LICENSE("GPL");
797MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids);
798
799struct pcmcia_driver dio700_cs_driver = {
800	.probe = dio700_cs_attach,
801	.remove = dio700_cs_detach,
802	.suspend = dio700_cs_suspend,
803	.resume = dio700_cs_resume,
804	.id_table = dio700_cs_ids,
805	.owner = THIS_MODULE,
806	.drv = {
807			.name = dev_info,
808		},
809};
810
811static int __init init_dio700_cs(void)
812{
813	printk("ni_daq_700:  cs-init \n");
814	DEBUG(0, "%s\n", version);
815	pcmcia_register_driver(&dio700_cs_driver);
816	return 0;
817}
818
819static void __exit exit_dio700_cs(void)
820{
821	DEBUG(0, "ni_daq_700: unloading\n");
822	pcmcia_unregister_driver(&dio700_cs_driver);
823}
824int __init init_module(void)
825{
826	int ret;
827
828	ret = init_dio700_cs();
829	if (ret < 0)
830		return ret;
831
832	return comedi_driver_register(&driver_dio700);
833}
834
835void __exit cleanup_module(void)
836{
837	exit_dio700_cs();
838	comedi_driver_unregister(&driver_dio700);
839}
840