ni_pcidio.c revision ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3f
1/*
2    comedi/drivers/ni_pcidio.c
3    driver for National Instruments PCI-DIO-96/PCI-6508
4               National Instruments PCI-DIO-32HS
5               National Instruments PCI-6503
6
7    COMEDI - Linux Control and Measurement Device Interface
8    Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25/*
26Driver: ni_pcidio
27Description: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503
28Author: ds
29Status: works
30Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533,
31  PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,
32  PXI-6503, PCI-6533, PCI-6534
33Updated: Sun, 21 Apr 2002 21:03:38 -0700
34
35The DIO-96 appears as four 8255 subdevices.  See the 8255
36driver notes for details.
37
38The DIO32HS board appears as one subdevice, with 32 channels.
39Each channel is individually I/O configurable.  The channel order
40is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0.  The driver only
41supports simple digital I/O; no handshaking is supported.
42
43DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
44
45This driver could be easily modified to support AT-MIO32HS and
46AT-MIO96.
47
48The PCI-6534 requires a firmware upload after power-up to work, the
49firmware data and instructions for loading it with comedi_config
50it are contained in the
51comedi_nonfree_firmware tarball available from http://www.comedi.org
52*/
53
54/*
55   This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96,
56   which have very different architectures.  But, since the '96 is
57   so simple, it is included here.
58
59   Manuals (available from ftp://ftp.natinst.com/support/manuals)
60
61	320938c.pdf	PCI-DIO-96/PXI-6508/PCI-6503 User Manual
62	321464b.pdf	AT/PCI-DIO-32HS User Manual
63	341329A.pdf	PCI-6533 Register-Level Programmer Manual
64	341330A.pdf	DAQ-DIO Technical Reference Manual
65
66 */
67
68#define USE_DMA
69//#define DEBUG 1
70//#define DEBUG_FLAGS
71
72#include "../comedidev.h"
73
74#include "mite.h"
75#include "8255.h"
76
77#undef DPRINTK
78#ifdef DEBUG
79#define DPRINTK(format, args...)	printk(format, ## args)
80#else
81#define DPRINTK(format, args...)
82#endif
83
84#define PCI_VENDOR_ID_NATINST	0x1093
85
86#define PCI_DIO_SIZE 4096
87#define PCI_MITE_SIZE 4096
88
89/* defines for the PCI-DIO-96 */
90
91#define NIDIO_8255_BASE(x)	((x)*4)
92#define NIDIO_A 0
93#define NIDIO_B 4
94#define NIDIO_C 8
95#define NIDIO_D 12
96
97/* defines for the PCI-DIO-32HS */
98
99#define Window_Address			4	/* W */
100#define Interrupt_And_Window_Status	4	/* R */
101#define IntStatus1				(1<<0)
102#define IntStatus2				(1<<1)
103#define WindowAddressStatus_mask		0x7c
104
105#define Master_DMA_And_Interrupt_Control 5	/* W */
106#define InterruptLine(x)			((x)&3)
107#define OpenInt				(1<<2)
108#define Group_Status			5	/* R */
109#define DataLeft				(1<<0)
110#define Req					(1<<2)
111#define StopTrig				(1<<3)
112
113#define Group_1_Flags			6	/* R */
114#define Group_2_Flags			7	/* R */
115#define TransferReady				(1<<0)
116#define CountExpired				(1<<1)
117#define Waited				(1<<5)
118#define PrimaryTC				(1<<6)
119#define SecondaryTC				(1<<7)
120  //#define SerialRose
121  //#define ReqRose
122  //#define Paused
123
124#define Group_1_First_Clear		6	/* W */
125#define Group_2_First_Clear		7	/* W */
126#define ClearWaited				(1<<3)
127#define ClearPrimaryTC			(1<<4)
128#define ClearSecondaryTC			(1<<5)
129#define DMAReset				(1<<6)
130#define FIFOReset				(1<<7)
131#define ClearAll				0xf8
132
133#define Group_1_FIFO			8	/* W */
134#define Group_2_FIFO			12	/* W */
135
136#define Transfer_Count			20
137#define Chip_ID_D			24
138#define Chip_ID_I			25
139#define Chip_ID_O			26
140#define Chip_Version			27
141#define Port_IO(x)			(28+(x))
142#define Port_Pin_Directions(x)		(32+(x))
143#define Port_Pin_Mask(x)		(36+(x))
144#define Port_Pin_Polarities(x)		(40+(x))
145
146#define Master_Clock_Routing		45
147#define RTSIClocking(x)			(((x)&3)<<4)
148
149#define Group_1_Second_Clear		46	/* W */
150#define Group_2_Second_Clear		47	/* W */
151#define ClearExpired				(1<<0)
152
153#define Port_Pattern(x)			(48+(x))
154
155#define Data_Path			64
156#define FIFOEnableA		(1<<0)
157#define FIFOEnableB		(1<<1)
158#define FIFOEnableC		(1<<2)
159#define FIFOEnableD		(1<<3)
160#define Funneling(x)		(((x)&3)<<4)
161#define GroupDirection	(1<<7)
162
163#define Protocol_Register_1		65
164#define OpMode				Protocol_Register_1
165#define RunMode(x)		((x)&7)
166#define Numbered		(1<<3)
167
168#define Protocol_Register_2		66
169#define ClockReg			Protocol_Register_2
170#define ClockLine(x)		(((x)&3)<<5)
171#define InvertStopTrig	(1<<7)
172#define DataLatching(x)       (((x)&3)<<5)
173
174#define Protocol_Register_3		67
175#define Sequence			Protocol_Register_3
176
177#define Protocol_Register_14		68	/* 16 bit */
178#define ClockSpeed			Protocol_Register_14
179
180#define Protocol_Register_4		70
181#define ReqReg				Protocol_Register_4
182#define ReqConditioning(x)	(((x)&7)<<3)
183
184#define Protocol_Register_5		71
185#define BlockMode			Protocol_Register_5
186
187#define FIFO_Control			72
188#define ReadyLevel(x)		((x)&7)
189
190#define Protocol_Register_6		73
191#define LinePolarities			Protocol_Register_6
192#define InvertAck		(1<<0)
193#define InvertReq		(1<<1)
194#define InvertClock		(1<<2)
195#define InvertSerial		(1<<3)
196#define OpenAck		(1<<4)
197#define OpenClock		(1<<5)
198
199#define Protocol_Register_7		74
200#define AckSer				Protocol_Register_7
201#define AckLine(x)		(((x)&3)<<2)
202#define ExchangePins		(1<<7)
203
204#define Interrupt_Control		75
205  /* bits same as flags */
206
207#define DMA_Line_Control_Group1		76
208#define DMA_Line_Control_Group2		108
209// channel zero is none
210static inline unsigned primary_DMAChannel_bits(unsigned channel)
211{
212	return channel & 0x3;
213}
214static inline unsigned secondary_DMAChannel_bits(unsigned channel)
215{
216	return (channel << 2) & 0xc;
217}
218
219#define Transfer_Size_Control		77
220#define TransferWidth(x)	((x)&3)
221#define TransferLength(x)	(((x)&3)<<3)
222#define RequireRLevel		(1<<5)
223
224#define Protocol_Register_15		79
225#define DAQOptions			Protocol_Register_15
226#define StartSource(x)			((x)&0x3)
227#define InvertStart				(1<<2)
228#define StopSource(x)				(((x)&0x3)<<3)
229#define ReqStart				(1<<6)
230#define PreStart				(1<<7)
231
232#define Pattern_Detection		81
233#define DetectionMethod			(1<<0)
234#define InvertMatch				(1<<1)
235#define IE_Pattern_Detection			(1<<2)
236
237#define Protocol_Register_9		82
238#define ReqDelay			Protocol_Register_9
239
240#define Protocol_Register_10		83
241#define ReqNotDelay			Protocol_Register_10
242
243#define Protocol_Register_11		84
244#define AckDelay			Protocol_Register_11
245
246#define Protocol_Register_12		85
247#define AckNotDelay			Protocol_Register_12
248
249#define Protocol_Register_13		86
250#define Data1Delay			Protocol_Register_13
251
252#define Protocol_Register_8		88	/* 32 bit */
253#define StartDelay			Protocol_Register_8
254
255enum pci_6534_firmware_registers {	/* 16 bit */
256	Firmware_Control_Register = 0x100,
257	Firmware_Status_Register = 0x104,
258	Firmware_Data_Register = 0x108,
259	Firmware_Mask_Register = 0x10c,
260	Firmware_Debug_Register = 0x110,
261};
262/* main fpga registers (32 bit)*/
263enum pci_6534_fpga_registers {
264	FPGA_Control1_Register = 0x200,
265	FPGA_Control2_Register = 0x204,
266	FPGA_Irq_Mask_Register = 0x208,
267	FPGA_Status_Register = 0x20c,
268	FPGA_Signature_Register = 0x210,
269	FPGA_SCALS_Counter_Register = 0x280,	/*write-clear */
270	FPGA_SCAMS_Counter_Register = 0x284,	/*write-clear */
271	FPGA_SCBLS_Counter_Register = 0x288,	/*write-clear */
272	FPGA_SCBMS_Counter_Register = 0x28c,	/*write-clear */
273	FPGA_Temp_Control_Register = 0x2a0,
274	FPGA_DAR_Register = 0x2a8,
275	FPGA_ELC_Read_Register = 0x2b8,
276	FPGA_ELC_Write_Register = 0x2bc,
277};
278enum FPGA_Control_Bits {
279	FPGA_Enable_Bit = 0x8000,
280};
281
282#define TIMER_BASE 50		/* nanoseconds */
283
284#ifdef USE_DMA
285#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
286#else
287#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
288#endif
289
290static int nidio_attach(struct comedi_device * dev, comedi_devconfig * it);
291static int nidio_detach(struct comedi_device * dev);
292static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
293
294static struct comedi_driver driver_pcidio = {
295      driver_name:"ni_pcidio",
296      module:THIS_MODULE,
297      attach:nidio_attach,
298      detach:nidio_detach,
299};
300
301typedef struct {
302	int dev_id;
303	const char *name;
304	int n_8255;
305	unsigned int is_diodaq:1;
306	unsigned int uses_firmware:1;
307} nidio_board;
308static const nidio_board nidio_boards[] = {
309	{
310	      dev_id:	0x1150,
311	      name:	"pci-dio-32hs",
312	      n_8255:	0,
313	      is_diodaq:1,
314		},
315	{
316	      dev_id:	0x1320,
317	      name:	"pxi-6533",
318	      n_8255:	0,
319	      is_diodaq:1,
320		},
321	{
322	      dev_id:	0x12b0,
323	      name:	"pci-6534",
324	      n_8255:	0,
325	      is_diodaq:1,
326	      uses_firmware:1,
327		},
328	{
329	      dev_id:	0x0160,
330	      name:	"pci-dio-96",
331	      n_8255:	4,
332	      is_diodaq:0,
333		},
334	{
335	      dev_id:	0x1630,
336	      name:	"pci-dio-96b",
337	      n_8255:	4,
338	      is_diodaq:0,
339		},
340	{
341	      dev_id:	0x13c0,
342	      name:	"pxi-6508",
343	      n_8255:	4,
344	      is_diodaq:0,
345		},
346	{
347	      dev_id:	0x0400,
348	      name:	"pci-6503",
349	      n_8255:	1,
350	      is_diodaq:0,
351		},
352	{
353	      dev_id:	0x1250,
354	      name:	"pci-6503b",
355	      n_8255:	1,
356	      is_diodaq:0,
357		},
358	{
359	      dev_id:	0x17d0,
360	      name:	"pci-6503x",
361	      n_8255:	1,
362	      is_diodaq:0,
363		},
364	{
365	      dev_id:	0x1800,
366	      name:	"pxi-6503",
367	      n_8255:	1,
368	      is_diodaq:0,
369		},
370};
371
372#define n_nidio_boards (sizeof(nidio_boards)/sizeof(nidio_boards[0]))
373#define this_board ((const nidio_board *)dev->board_ptr)
374
375static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
376	{PCI_VENDOR_ID_NATINST, 0x1150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
377	{PCI_VENDOR_ID_NATINST, 0x1320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
378	{PCI_VENDOR_ID_NATINST, 0x12b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
379	{PCI_VENDOR_ID_NATINST, 0x0160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
380	{PCI_VENDOR_ID_NATINST, 0x1630, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
381	{PCI_VENDOR_ID_NATINST, 0x13c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
382	{PCI_VENDOR_ID_NATINST, 0x0400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
383	{PCI_VENDOR_ID_NATINST, 0x1250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
384	{PCI_VENDOR_ID_NATINST, 0x17d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
385	{PCI_VENDOR_ID_NATINST, 0x1800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
386	{0}
387};
388
389MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
390
391typedef struct {
392	struct mite_struct *mite;
393	int boardtype;
394	int dio;
395	unsigned short OpModeBits;
396	struct mite_channel *di_mite_chan;
397	struct mite_dma_descriptor_ring *di_mite_ring;
398	spinlock_t mite_channel_lock;
399} nidio96_private;
400#define devpriv ((nidio96_private *)dev->private)
401
402static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
403	struct comedi_cmd * cmd);
404static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
405static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
406	unsigned int trignum);
407static int nidio_find_device(struct comedi_device * dev, int bus, int slot);
408static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
409static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s);
410
411#ifdef DEBUG_FLAGS
412static void ni_pcidio_print_flags(unsigned int flags);
413static void ni_pcidio_print_status(unsigned int status);
414#else
415#define ni_pcidio_print_flags(x)
416#define ni_pcidio_print_status(x)
417#endif
418
419static int ni_pcidio_request_di_mite_channel(struct comedi_device * dev)
420{
421	unsigned long flags;
422
423	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
424	BUG_ON(devpriv->di_mite_chan);
425	devpriv->di_mite_chan =
426		mite_request_channel_in_range(devpriv->mite,
427		devpriv->di_mite_ring, 1, 2);
428	if (devpriv->di_mite_chan == NULL) {
429		comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
430			flags);
431		comedi_error(dev, "failed to reserve mite dma channel.");
432		return -EBUSY;
433	}
434	writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
435		secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
436		devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
437	mmiowb();
438	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
439	return 0;
440}
441
442static void ni_pcidio_release_di_mite_channel(struct comedi_device * dev)
443{
444	unsigned long flags;
445
446	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
447	if (devpriv->di_mite_chan) {
448		mite_dma_disarm(devpriv->di_mite_chan);
449		mite_dma_reset(devpriv->di_mite_chan);
450		mite_release_channel(devpriv->di_mite_chan);
451		devpriv->di_mite_chan = NULL;
452		writeb(primary_DMAChannel_bits(0) |
453			secondary_DMAChannel_bits(0),
454			devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
455		mmiowb();
456	}
457	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
458}
459
460static int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase)
461{
462	if (dir) {
463		writeb(data, (void *)(iobase + port));
464		return 0;
465	} else {
466		return readb((void *)(iobase + port));
467	}
468}
469
470void ni_pcidio_event(struct comedi_device * dev, struct comedi_subdevice * s)
471{
472	if (s->async->
473		events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
474	{
475		ni_pcidio_cancel(dev, s);
476	}
477	comedi_event(dev, s);
478}
479
480static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG)
481{
482	struct comedi_device *dev = d;
483	struct comedi_subdevice *s = dev->subdevices;
484	struct comedi_async *async = s->async;
485	struct mite_struct *mite = devpriv->mite;
486
487	//int i, j;
488	long int AuxData = 0;
489	short data1 = 0;
490	short data2 = 0;
491	int flags;
492	int status;
493	int work = 0;
494	unsigned int m_status = 0;
495	unsigned long irq_flags;
496
497	//interrupcions parasites
498	if (dev->attached == 0) {
499		// assume it's from another card
500		return IRQ_NONE;
501	}
502
503	status = readb(devpriv->mite->daq_io_addr +
504		Interrupt_And_Window_Status);
505	flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
506
507	DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
508		status, flags);
509	ni_pcidio_print_flags(flags);
510	ni_pcidio_print_status(status);
511
512	//printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf);
513	//printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096));
514
515	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
516	if (devpriv->di_mite_chan)
517		m_status = mite_get_status(devpriv->di_mite_chan);
518#ifdef MITE_DEBUG
519	mite_print_chsr(m_status);
520#endif
521	//printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN));
522	//mite_dump_regs(mite);
523	if (m_status & CHSR_INT) {
524		if (m_status & CHSR_LINKC) {
525			writel(CHOR_CLRLC,
526				mite->mite_io_addr +
527				MITE_CHOR(devpriv->di_mite_chan->channel));
528			mite_sync_input_dma(devpriv->di_mite_chan, s->async);
529			/* XXX need to byteswap */
530		}
531		if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
532				CHSR_DRQ1 | CHSR_MRDY)) {
533			DPRINTK("unknown mite interrupt, disabling IRQ\n");
534			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
535			disable_irq(dev->irq);
536		}
537	}
538	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
539
540	while (status & DataLeft) {
541		work++;
542		if (work > 20) {
543			DPRINTK("too much work in interrupt\n");
544			writeb(0x00,
545				devpriv->mite->daq_io_addr +
546				Master_DMA_And_Interrupt_Control);
547			break;
548		}
549
550		flags &= IntEn;
551
552		if (flags & TransferReady) {
553			//DPRINTK("TransferReady\n");
554			while (flags & TransferReady) {
555				work++;
556				if (work > 100) {
557					DPRINTK("too much work in interrupt\n");
558					writeb(0x00,
559						devpriv->mite->daq_io_addr +
560						Master_DMA_And_Interrupt_Control);
561					goto out;
562				}
563				AuxData =
564					readl(devpriv->mite->daq_io_addr +
565					Group_1_FIFO);
566				data1 = AuxData & 0xffff;
567				data2 = (AuxData & 0xffff0000) >> 16;
568				comedi_buf_put(async, data1);
569				comedi_buf_put(async, data2);
570				//DPRINTK("read:%d, %d\n",data1,data2);
571				flags = readb(devpriv->mite->daq_io_addr +
572					Group_1_Flags);
573			}
574			//DPRINTK("buf_int_count: %d\n",async->buf_int_count);
575			//DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status);
576			//ni_pcidio_print_flags(flags);
577			//ni_pcidio_print_status(status);
578			async->events |= COMEDI_CB_BLOCK;
579		}
580
581		if (flags & CountExpired) {
582			DPRINTK("CountExpired\n");
583			writeb(ClearExpired,
584				devpriv->mite->daq_io_addr +
585				Group_1_Second_Clear);
586			async->events |= COMEDI_CB_EOA;
587
588			writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
589			break;
590		} else if (flags & Waited) {
591			DPRINTK("Waited\n");
592			writeb(ClearWaited,
593				devpriv->mite->daq_io_addr +
594				Group_1_First_Clear);
595			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
596			break;
597		} else if (flags & PrimaryTC) {
598			DPRINTK("PrimaryTC\n");
599			writeb(ClearPrimaryTC,
600				devpriv->mite->daq_io_addr +
601				Group_1_First_Clear);
602			async->events |= COMEDI_CB_EOA;
603		} else if (flags & SecondaryTC) {
604			DPRINTK("SecondaryTC\n");
605			writeb(ClearSecondaryTC,
606				devpriv->mite->daq_io_addr +
607				Group_1_First_Clear);
608			async->events |= COMEDI_CB_EOA;
609		}
610#if 0
611		else {
612			printk("ni_pcidio: unknown interrupt\n");
613			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
614			writeb(0x00,
615				devpriv->mite->daq_io_addr +
616				Master_DMA_And_Interrupt_Control);
617		}
618#endif
619		flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
620		status = readb(devpriv->mite->daq_io_addr +
621			Interrupt_And_Window_Status);
622		//DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n",
623		//      IntEn,flags,status);
624		//ni_pcidio_print_flags(flags);
625		//ni_pcidio_print_status(status);
626	}
627
628      out:
629	ni_pcidio_event(dev, s);
630#if 0
631	if (!tag) {
632		writeb(0x03,
633			devpriv->mite->daq_io_addr +
634			Master_DMA_And_Interrupt_Control);
635	}
636#endif
637	return IRQ_HANDLED;
638}
639
640#ifdef DEBUG_FLAGS
641static const char *const flags_strings[] = {
642	"TransferReady", "CountExpired", "2", "3",
643	"4", "Waited", "PrimaryTC", "SecondaryTC",
644};
645static void ni_pcidio_print_flags(unsigned int flags)
646{
647	int i;
648
649	printk("group_1_flags:");
650	for (i = 7; i >= 0; i--) {
651		if (flags & (1 << i)) {
652			printk(" %s", flags_strings[i]);
653		}
654	}
655	printk("\n");
656}
657static char *status_strings[] = {
658	"DataLeft1", "Reserved1", "Req1", "StopTrig1",
659	"DataLeft2", "Reserved2", "Req2", "StopTrig2",
660};
661static void ni_pcidio_print_status(unsigned int flags)
662{
663	int i;
664
665	printk("group_status:");
666	for (i = 7; i >= 0; i--) {
667		if (flags & (1 << i)) {
668			printk(" %s", status_strings[i]);
669		}
670	}
671	printk("\n");
672}
673#endif
674
675#ifdef unused
676static void debug_int(struct comedi_device * dev)
677{
678	int a, b;
679	static int n_int = 0;
680	struct timeval tv;
681
682	do_gettimeofday(&tv);
683	a = readb(devpriv->mite->daq_io_addr + Group_Status);
684	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
685
686	if (n_int < 10) {
687		DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
688			(int)tv.tv_usec);
689	}
690
691	while (b & 1) {
692		writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
693		b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
694	}
695
696	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
697
698	if (n_int < 10) {
699		DPRINTK("new status 0x%02x\n", b);
700		n_int++;
701	}
702}
703#endif
704
705static int ni_pcidio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
706	comedi_insn * insn, unsigned int * data)
707{
708	if (insn->n != 1)
709		return -EINVAL;
710	switch (data[0]) {
711	case INSN_CONFIG_DIO_OUTPUT:
712		s->io_bits |= 1 << CR_CHAN(insn->chanspec);
713		break;
714	case INSN_CONFIG_DIO_INPUT:
715		s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
716		break;
717	case INSN_CONFIG_DIO_QUERY:
718		data[1] =
719			(s->io_bits & (1 << CR_CHAN(insn->
720					chanspec))) ? COMEDI_OUTPUT :
721			COMEDI_INPUT;
722		return insn->n;
723		break;
724	default:
725		return -EINVAL;
726	}
727	writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
728
729	return 1;
730}
731
732static int ni_pcidio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
733	comedi_insn * insn, unsigned int * data)
734{
735	if (insn->n != 2)
736		return -EINVAL;
737	if (data[0]) {
738		s->state &= ~data[0];
739		s->state |= (data[0] & data[1]);
740		writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
741	}
742	data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
743
744	return 2;
745}
746
747static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
748	struct comedi_cmd * cmd)
749{
750	int err = 0;
751	int tmp;
752
753	/* step 1: make sure trigger sources are trivially valid */
754
755	tmp = cmd->start_src;
756	cmd->start_src &= TRIG_NOW | TRIG_INT;
757	if (!cmd->start_src || tmp != cmd->start_src)
758		err++;
759
760	tmp = cmd->scan_begin_src;
761	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
762	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
763		err++;
764
765	tmp = cmd->convert_src;
766	cmd->convert_src &= TRIG_NOW;
767	if (!cmd->convert_src || tmp != cmd->convert_src)
768		err++;
769
770	tmp = cmd->scan_end_src;
771	cmd->scan_end_src &= TRIG_COUNT;
772	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
773		err++;
774
775	tmp = cmd->stop_src;
776	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
777	if (!cmd->stop_src || tmp != cmd->stop_src)
778		err++;
779
780	if (err)
781		return 1;
782
783	/* step 2: make sure trigger sources are unique and mutually compatible */
784
785	/* note that mutual compatiblity is not an issue here */
786	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
787		err++;
788	if (cmd->scan_begin_src != TRIG_TIMER &&
789		cmd->scan_begin_src != TRIG_EXT)
790		err++;
791
792	if (err)
793		return 2;
794
795	/* step 3: make sure arguments are trivially compatible */
796
797	if (cmd->start_arg != 0) {
798		/* same for both TRIG_INT and TRIG_NOW */
799		cmd->start_arg = 0;
800		err++;
801	}
802#define MAX_SPEED	(TIMER_BASE)	/* in nanoseconds */
803
804	if (cmd->scan_begin_src == TRIG_TIMER) {
805		if (cmd->scan_begin_arg < MAX_SPEED) {
806			cmd->scan_begin_arg = MAX_SPEED;
807			err++;
808		}
809		/* no minumum speed */
810	} else {
811		/* TRIG_EXT */
812		/* should be level/edge, hi/lo specification here */
813		if (cmd->scan_begin_arg != 0) {
814			cmd->scan_begin_arg = 0;
815			err++;
816		}
817	}
818	if (cmd->convert_arg != 0) {
819		cmd->convert_arg = 0;
820		err++;
821	}
822
823	if (cmd->scan_end_arg != cmd->chanlist_len) {
824		cmd->scan_end_arg = cmd->chanlist_len;
825		err++;
826	}
827	if (cmd->stop_src == TRIG_COUNT) {
828		/* no limit */
829	} else {
830		/* TRIG_NONE */
831		if (cmd->stop_arg != 0) {
832			cmd->stop_arg = 0;
833			err++;
834		}
835	}
836
837	if (err)
838		return 3;
839
840	/* step 4: fix up any arguments */
841
842	if (cmd->scan_begin_src == TRIG_TIMER) {
843		tmp = cmd->scan_begin_arg;
844		ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
845			cmd->flags & TRIG_ROUND_MASK);
846		if (tmp != cmd->scan_begin_arg)
847			err++;
848	}
849
850	if (err)
851		return 4;
852
853	return 0;
854}
855
856static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
857{
858	int divider, base;
859
860	base = TIMER_BASE;
861
862	switch (round_mode) {
863	case TRIG_ROUND_NEAREST:
864	default:
865		divider = (*nanosec + base / 2) / base;
866		break;
867	case TRIG_ROUND_DOWN:
868		divider = (*nanosec) / base;
869		break;
870	case TRIG_ROUND_UP:
871		divider = (*nanosec + base - 1) / base;
872		break;
873	}
874
875	*nanosec = base * divider;
876	return divider;
877}
878
879static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
880{
881	struct comedi_cmd *cmd = &s->async->cmd;
882
883	/* XXX configure ports for input */
884	writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
885
886	if (1) {
887		/* enable fifos A B C D */
888		writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
889
890		/* set transfer width a 32 bits */
891		writeb(TransferWidth(0) | TransferLength(0),
892			devpriv->mite->daq_io_addr + Transfer_Size_Control);
893	} else {
894		writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
895		writeb(TransferWidth(3) | TransferLength(0),
896			devpriv->mite->daq_io_addr + Transfer_Size_Control);
897	}
898
899	/* protocol configuration */
900	if (cmd->scan_begin_src == TRIG_TIMER) {
901		/* page 4-5, "input with internal REQs" */
902		writeb(0, devpriv->mite->daq_io_addr + OpMode);
903		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
904		writeb(1, devpriv->mite->daq_io_addr + Sequence);
905		writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
906		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
907		writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
908		writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
909		writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
910				TRIG_ROUND_NEAREST),
911			devpriv->mite->daq_io_addr + StartDelay);
912		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
913		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
914		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
915		writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
916		writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
917		/* manual, page 4-5: ClockSpeed comment is incorrectly listed
918		 * on DAQOptions */
919		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
920		writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
921	} else {
922		/* TRIG_EXT */
923		/* page 4-5, "input with external REQs" */
924		writeb(0, devpriv->mite->daq_io_addr + OpMode);
925		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
926		writeb(0, devpriv->mite->daq_io_addr + Sequence);
927		writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
928		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
929		writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
930		writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
931		writel(1, devpriv->mite->daq_io_addr + StartDelay);
932		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
933		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
934		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
935		writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
936		writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
937		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
938		writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
939	}
940
941	if (cmd->stop_src == TRIG_COUNT) {
942		writel(cmd->stop_arg,
943			devpriv->mite->daq_io_addr + Transfer_Count);
944	} else {
945		/* XXX */
946	}
947
948#ifdef USE_DMA
949	writeb(ClearPrimaryTC | ClearSecondaryTC,
950		devpriv->mite->daq_io_addr + Group_1_First_Clear);
951
952	{
953		int retval = setup_mite_dma(dev, s);
954		if (retval)
955			return retval;
956	}
957#else
958	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
959#endif
960	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
961
962	/* clear and enable interrupts */
963	writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
964	//writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear);
965
966	writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
967	writeb(0x03,
968		devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
969
970	if (cmd->stop_src == TRIG_NONE) {
971		devpriv->OpModeBits = DataLatching(0) | RunMode(7);
972	} else {		// TRIG_TIMER
973		devpriv->OpModeBits = Numbered | RunMode(7);
974	}
975	if (cmd->start_src == TRIG_NOW) {
976		/* start */
977		writeb(devpriv->OpModeBits,
978			devpriv->mite->daq_io_addr + OpMode);
979		s->async->inttrig = NULL;
980	} else {
981		/* TRIG_INT */
982		s->async->inttrig = ni_pcidio_inttrig;
983	}
984
985	DPRINTK("ni_pcidio: command started\n");
986	return 0;
987}
988
989static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s)
990{
991	int retval;
992
993	retval = ni_pcidio_request_di_mite_channel(dev);
994	if (retval)
995		return retval;
996
997	devpriv->di_mite_chan->dir = COMEDI_INPUT;
998
999	mite_prep_dma(devpriv->di_mite_chan, 32, 32);
1000
1001	mite_dma_arm(devpriv->di_mite_chan);
1002	return 0;
1003}
1004
1005static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
1006	unsigned int trignum)
1007{
1008	if (trignum != 0)
1009		return -EINVAL;
1010
1011	writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
1012	s->async->inttrig = NULL;
1013
1014	return 1;
1015}
1016
1017static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
1018{
1019	writeb(0x00,
1020		devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
1021	ni_pcidio_release_di_mite_channel(dev);
1022
1023	return 0;
1024}
1025
1026static int ni_pcidio_change(struct comedi_device * dev, struct comedi_subdevice * s,
1027	unsigned long new_size)
1028{
1029	int ret;
1030
1031	ret = mite_buf_change(devpriv->di_mite_ring, s->async);
1032	if (ret < 0)
1033		return ret;
1034
1035	memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
1036
1037	return 0;
1038}
1039
1040static int pci_6534_load_fpga(struct comedi_device * dev, int fpga_index, u8 * data,
1041	int data_len)
1042{
1043	static const int timeout = 1000;
1044	int i, j;
1045	writew(0x80 | fpga_index,
1046		devpriv->mite->daq_io_addr + Firmware_Control_Register);
1047	writew(0xc0 | fpga_index,
1048		devpriv->mite->daq_io_addr + Firmware_Control_Register);
1049	for (i = 0;
1050		(readw(devpriv->mite->daq_io_addr +
1051				Firmware_Status_Register) & 0x2) == 0
1052		&& i < timeout; ++i) {
1053		udelay(1);
1054	}
1055	if (i == timeout) {
1056		printk("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n", fpga_index);
1057		return -EIO;
1058	}
1059	writew(0x80 | fpga_index,
1060		devpriv->mite->daq_io_addr + Firmware_Control_Register);
1061	for (i = 0;
1062		readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
1063		0x3 && i < timeout; ++i) {
1064		udelay(1);
1065	}
1066	if (i == timeout) {
1067		printk("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n", fpga_index);
1068		return -EIO;
1069	}
1070	for (j = 0; j + 1 < data_len;) {
1071		unsigned int value = data[j++];
1072		value |= data[j++] << 8;
1073		writew(value,
1074			devpriv->mite->daq_io_addr + Firmware_Data_Register);
1075		for (i = 0;
1076			(readw(devpriv->mite->daq_io_addr +
1077					Firmware_Status_Register) & 0x2) == 0
1078			&& i < timeout; ++i) {
1079			udelay(1);
1080		}
1081		if (i == timeout) {
1082			printk("ni_pcidio: failed to load word into fpga %i\n",
1083				fpga_index);
1084			return -EIO;
1085		}
1086		if (need_resched())
1087			schedule();
1088	}
1089	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1090	return 0;
1091}
1092
1093static int pci_6534_reset_fpga(struct comedi_device * dev, int fpga_index)
1094{
1095	return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
1096}
1097
1098static int pci_6534_reset_fpgas(struct comedi_device * dev)
1099{
1100	int ret;
1101	int i;
1102	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1103	for (i = 0; i < 3; ++i) {
1104		ret = pci_6534_reset_fpga(dev, i);
1105		if (ret < 0)
1106			break;
1107	}
1108	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
1109	return ret;
1110}
1111
1112static void pci_6534_init_main_fpga(struct comedi_device * dev)
1113{
1114	writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
1115	writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
1116	writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
1117	writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
1118	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
1119	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
1120}
1121
1122static int pci_6534_upload_firmware(struct comedi_device * dev, int options[])
1123{
1124	int ret;
1125	void *main_fpga_data, *scarab_a_data, *scarab_b_data;
1126	int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len;
1127
1128	if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0)
1129		return 0;
1130	ret = pci_6534_reset_fpgas(dev);
1131	if (ret < 0)
1132		return ret;
1133	main_fpga_data = comedi_aux_data(options, 0);
1134	main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
1135	ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len);
1136	if (ret < 0)
1137		return ret;
1138	pci_6534_init_main_fpga(dev);
1139	scarab_a_data = comedi_aux_data(options, 1);
1140	scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
1141	ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len);
1142	if (ret < 0)
1143		return ret;
1144	scarab_b_data = comedi_aux_data(options, 2);
1145	scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
1146	ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len);
1147	if (ret < 0)
1148		return ret;
1149	return 0;
1150}
1151
1152static int nidio_attach(struct comedi_device * dev, comedi_devconfig * it)
1153{
1154	struct comedi_subdevice *s;
1155	int i;
1156	int ret;
1157	int n_subdevices;
1158	unsigned int irq;
1159
1160	printk("comedi%d: nidio:", dev->minor);
1161
1162	if ((ret = alloc_private(dev, sizeof(nidio96_private))) < 0)
1163		return ret;
1164	spin_lock_init(&devpriv->mite_channel_lock);
1165
1166	ret = nidio_find_device(dev, it->options[0], it->options[1]);
1167	if (ret < 0)
1168		return ret;
1169
1170	ret = mite_setup(devpriv->mite);
1171	if (ret < 0) {
1172		printk("error setting up mite\n");
1173		return ret;
1174	}
1175	comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
1176	devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
1177	if (devpriv->di_mite_ring == NULL)
1178		return -ENOMEM;
1179
1180	dev->board_name = this_board->name;
1181	irq = mite_irq(devpriv->mite);
1182	printk(" %s", dev->board_name);
1183	if (this_board->uses_firmware) {
1184		ret = pci_6534_upload_firmware(dev, it->options);
1185		if (ret < 0)
1186			return ret;
1187	}
1188	if (!this_board->is_diodaq) {
1189		n_subdevices = this_board->n_8255;
1190	} else {
1191		n_subdevices = 1;
1192	}
1193	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
1194		return ret;
1195
1196	if (!this_board->is_diodaq) {
1197		for (i = 0; i < this_board->n_8255; i++) {
1198			subdev_8255_init(dev, dev->subdevices + i,
1199				nidio96_8255_cb,
1200				(unsigned long)(devpriv->mite->daq_io_addr +
1201					NIDIO_8255_BASE(i)));
1202		}
1203	} else {
1204
1205		printk(" rev=%d",
1206			readb(devpriv->mite->daq_io_addr + Chip_Version));
1207
1208		s = dev->subdevices + 0;
1209
1210		dev->read_subdev = s;
1211		s->type = COMEDI_SUBD_DIO;
1212		s->subdev_flags =
1213			SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
1214			SDF_CMD_READ;
1215		s->n_chan = 32;
1216		s->range_table = &range_digital;
1217		s->maxdata = 1;
1218		s->insn_config = &ni_pcidio_insn_config;
1219		s->insn_bits = &ni_pcidio_insn_bits;
1220		s->do_cmd = &ni_pcidio_cmd;
1221		s->do_cmdtest = &ni_pcidio_cmdtest;
1222		s->cancel = &ni_pcidio_cancel;
1223		s->len_chanlist = 32;	/* XXX */
1224		s->buf_change = &ni_pcidio_change;
1225		s->async_dma_dir = DMA_BIDIRECTIONAL;
1226
1227		writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
1228		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
1229		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));
1230
1231		/* disable interrupts on board */
1232		writeb(0x00,
1233			devpriv->mite->daq_io_addr +
1234			Master_DMA_And_Interrupt_Control);
1235
1236		ret = comedi_request_irq(irq, nidio_interrupt, IRQF_SHARED,
1237			"ni_pcidio", dev);
1238		if (ret < 0) {
1239			printk(" irq not available");
1240		}
1241		dev->irq = irq;
1242	}
1243
1244	printk("\n");
1245
1246	return 0;
1247}
1248
1249static int nidio_detach(struct comedi_device * dev)
1250{
1251	int i;
1252
1253	if (this_board && !this_board->is_diodaq) {
1254		for (i = 0; i < this_board->n_8255; i++) {
1255			subdev_8255_cleanup(dev, dev->subdevices + i);
1256		}
1257	}
1258
1259	if (dev->irq)
1260		comedi_free_irq(dev->irq, dev);
1261
1262	if (devpriv) {
1263		if (devpriv->di_mite_ring) {
1264			mite_free_ring(devpriv->di_mite_ring);
1265			devpriv->di_mite_ring = NULL;
1266		}
1267		if (devpriv->mite)
1268			mite_unsetup(devpriv->mite);
1269	}
1270	return 0;
1271}
1272
1273static int nidio_find_device(struct comedi_device * dev, int bus, int slot)
1274{
1275	struct mite_struct *mite;
1276	int i;
1277
1278	for (mite = mite_devices; mite; mite = mite->next) {
1279		if (mite->used)
1280			continue;
1281		if (bus || slot) {
1282			if (bus != mite->pcidev->bus->number ||
1283				slot != PCI_SLOT(mite->pcidev->devfn))
1284				continue;
1285		}
1286		for (i = 0; i < n_nidio_boards; i++) {
1287			if (mite_device_id(mite) == nidio_boards[i].dev_id) {
1288				dev->board_ptr = nidio_boards + i;
1289				devpriv->mite = mite;
1290
1291				return 0;
1292			}
1293		}
1294	}
1295	printk("no device found\n");
1296	mite_list_devices();
1297	return -EIO;
1298}
1299
1300COMEDI_PCI_INITCLEANUP(driver_pcidio, ni_pcidio_pci_table);
1301