ni_pcidio.c revision 70265d24e3404fe798b6edd55a02016b1edb49d7
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, struct 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
301struct nidio_board {
302
303	int dev_id;
304	const char *name;
305	int n_8255;
306	unsigned int is_diodaq:1;
307	unsigned int uses_firmware:1;
308};
309
310static const struct nidio_board nidio_boards[] = {
311	{
312	      dev_id:	0x1150,
313	      name:	"pci-dio-32hs",
314	      n_8255:	0,
315	      is_diodaq:1,
316		},
317	{
318	      dev_id:	0x1320,
319	      name:	"pxi-6533",
320	      n_8255:	0,
321	      is_diodaq:1,
322		},
323	{
324	      dev_id:	0x12b0,
325	      name:	"pci-6534",
326	      n_8255:	0,
327	      is_diodaq:1,
328	      uses_firmware:1,
329		},
330	{
331	      dev_id:	0x0160,
332	      name:	"pci-dio-96",
333	      n_8255:	4,
334	      is_diodaq:0,
335		},
336	{
337	      dev_id:	0x1630,
338	      name:	"pci-dio-96b",
339	      n_8255:	4,
340	      is_diodaq:0,
341		},
342	{
343	      dev_id:	0x13c0,
344	      name:	"pxi-6508",
345	      n_8255:	4,
346	      is_diodaq:0,
347		},
348	{
349	      dev_id:	0x0400,
350	      name:	"pci-6503",
351	      n_8255:	1,
352	      is_diodaq:0,
353		},
354	{
355	      dev_id:	0x1250,
356	      name:	"pci-6503b",
357	      n_8255:	1,
358	      is_diodaq:0,
359		},
360	{
361	      dev_id:	0x17d0,
362	      name:	"pci-6503x",
363	      n_8255:	1,
364	      is_diodaq:0,
365		},
366	{
367	      dev_id:	0x1800,
368	      name:	"pxi-6503",
369	      n_8255:	1,
370	      is_diodaq:0,
371		},
372};
373
374#define n_nidio_boards (sizeof(nidio_boards)/sizeof(nidio_boards[0]))
375#define this_board ((const struct nidio_board *)dev->board_ptr)
376
377static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
378	{PCI_VENDOR_ID_NATINST, 0x1150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
379	{PCI_VENDOR_ID_NATINST, 0x1320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
380	{PCI_VENDOR_ID_NATINST, 0x12b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
381	{PCI_VENDOR_ID_NATINST, 0x0160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
382	{PCI_VENDOR_ID_NATINST, 0x1630, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
383	{PCI_VENDOR_ID_NATINST, 0x13c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
384	{PCI_VENDOR_ID_NATINST, 0x0400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
385	{PCI_VENDOR_ID_NATINST, 0x1250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
386	{PCI_VENDOR_ID_NATINST, 0x17d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
387	{PCI_VENDOR_ID_NATINST, 0x1800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
388	{0}
389};
390
391MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
392
393struct nidio96_private {
394	struct mite_struct *mite;
395	int boardtype;
396	int dio;
397	unsigned short OpModeBits;
398	struct mite_channel *di_mite_chan;
399	struct mite_dma_descriptor_ring *di_mite_ring;
400	spinlock_t mite_channel_lock;
401};
402#define devpriv ((struct nidio96_private *)dev->private)
403
404static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
405	struct comedi_cmd * cmd);
406static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
407static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
408	unsigned int trignum);
409static int nidio_find_device(struct comedi_device * dev, int bus, int slot);
410static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
411static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s);
412
413#ifdef DEBUG_FLAGS
414static void ni_pcidio_print_flags(unsigned int flags);
415static void ni_pcidio_print_status(unsigned int status);
416#else
417#define ni_pcidio_print_flags(x)
418#define ni_pcidio_print_status(x)
419#endif
420
421static int ni_pcidio_request_di_mite_channel(struct comedi_device * dev)
422{
423	unsigned long flags;
424
425	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
426	BUG_ON(devpriv->di_mite_chan);
427	devpriv->di_mite_chan =
428		mite_request_channel_in_range(devpriv->mite,
429		devpriv->di_mite_ring, 1, 2);
430	if (devpriv->di_mite_chan == NULL) {
431		comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
432			flags);
433		comedi_error(dev, "failed to reserve mite dma channel.");
434		return -EBUSY;
435	}
436	writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
437		secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
438		devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
439	mmiowb();
440	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
441	return 0;
442}
443
444static void ni_pcidio_release_di_mite_channel(struct comedi_device * dev)
445{
446	unsigned long flags;
447
448	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
449	if (devpriv->di_mite_chan) {
450		mite_dma_disarm(devpriv->di_mite_chan);
451		mite_dma_reset(devpriv->di_mite_chan);
452		mite_release_channel(devpriv->di_mite_chan);
453		devpriv->di_mite_chan = NULL;
454		writeb(primary_DMAChannel_bits(0) |
455			secondary_DMAChannel_bits(0),
456			devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
457		mmiowb();
458	}
459	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
460}
461
462static int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase)
463{
464	if (dir) {
465		writeb(data, (void *)(iobase + port));
466		return 0;
467	} else {
468		return readb((void *)(iobase + port));
469	}
470}
471
472void ni_pcidio_event(struct comedi_device * dev, struct comedi_subdevice * s)
473{
474	if (s->async->
475		events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
476	{
477		ni_pcidio_cancel(dev, s);
478	}
479	comedi_event(dev, s);
480}
481
482static irqreturn_t nidio_interrupt(int irq, void *d)
483{
484	struct comedi_device *dev = d;
485	struct comedi_subdevice *s = dev->subdevices;
486	struct comedi_async *async = s->async;
487	struct mite_struct *mite = devpriv->mite;
488
489	//int i, j;
490	long int AuxData = 0;
491	short data1 = 0;
492	short data2 = 0;
493	int flags;
494	int status;
495	int work = 0;
496	unsigned int m_status = 0;
497	unsigned long irq_flags;
498
499	//interrupcions parasites
500	if (dev->attached == 0) {
501		// assume it's from another card
502		return IRQ_NONE;
503	}
504
505	status = readb(devpriv->mite->daq_io_addr +
506		Interrupt_And_Window_Status);
507	flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
508
509	DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
510		status, flags);
511	ni_pcidio_print_flags(flags);
512	ni_pcidio_print_status(status);
513
514	//printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf);
515	//printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096));
516
517	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
518	if (devpriv->di_mite_chan)
519		m_status = mite_get_status(devpriv->di_mite_chan);
520#ifdef MITE_DEBUG
521	mite_print_chsr(m_status);
522#endif
523	//printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN));
524	//mite_dump_regs(mite);
525	if (m_status & CHSR_INT) {
526		if (m_status & CHSR_LINKC) {
527			writel(CHOR_CLRLC,
528				mite->mite_io_addr +
529				MITE_CHOR(devpriv->di_mite_chan->channel));
530			mite_sync_input_dma(devpriv->di_mite_chan, s->async);
531			/* XXX need to byteswap */
532		}
533		if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
534				CHSR_DRQ1 | CHSR_MRDY)) {
535			DPRINTK("unknown mite interrupt, disabling IRQ\n");
536			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
537			disable_irq(dev->irq);
538		}
539	}
540	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
541
542	while (status & DataLeft) {
543		work++;
544		if (work > 20) {
545			DPRINTK("too much work in interrupt\n");
546			writeb(0x00,
547				devpriv->mite->daq_io_addr +
548				Master_DMA_And_Interrupt_Control);
549			break;
550		}
551
552		flags &= IntEn;
553
554		if (flags & TransferReady) {
555			//DPRINTK("TransferReady\n");
556			while (flags & TransferReady) {
557				work++;
558				if (work > 100) {
559					DPRINTK("too much work in interrupt\n");
560					writeb(0x00,
561						devpriv->mite->daq_io_addr +
562						Master_DMA_And_Interrupt_Control);
563					goto out;
564				}
565				AuxData =
566					readl(devpriv->mite->daq_io_addr +
567					Group_1_FIFO);
568				data1 = AuxData & 0xffff;
569				data2 = (AuxData & 0xffff0000) >> 16;
570				comedi_buf_put(async, data1);
571				comedi_buf_put(async, data2);
572				//DPRINTK("read:%d, %d\n",data1,data2);
573				flags = readb(devpriv->mite->daq_io_addr +
574					Group_1_Flags);
575			}
576			//DPRINTK("buf_int_count: %d\n",async->buf_int_count);
577			//DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status);
578			//ni_pcidio_print_flags(flags);
579			//ni_pcidio_print_status(status);
580			async->events |= COMEDI_CB_BLOCK;
581		}
582
583		if (flags & CountExpired) {
584			DPRINTK("CountExpired\n");
585			writeb(ClearExpired,
586				devpriv->mite->daq_io_addr +
587				Group_1_Second_Clear);
588			async->events |= COMEDI_CB_EOA;
589
590			writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
591			break;
592		} else if (flags & Waited) {
593			DPRINTK("Waited\n");
594			writeb(ClearWaited,
595				devpriv->mite->daq_io_addr +
596				Group_1_First_Clear);
597			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
598			break;
599		} else if (flags & PrimaryTC) {
600			DPRINTK("PrimaryTC\n");
601			writeb(ClearPrimaryTC,
602				devpriv->mite->daq_io_addr +
603				Group_1_First_Clear);
604			async->events |= COMEDI_CB_EOA;
605		} else if (flags & SecondaryTC) {
606			DPRINTK("SecondaryTC\n");
607			writeb(ClearSecondaryTC,
608				devpriv->mite->daq_io_addr +
609				Group_1_First_Clear);
610			async->events |= COMEDI_CB_EOA;
611		}
612#if 0
613		else {
614			printk("ni_pcidio: unknown interrupt\n");
615			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
616			writeb(0x00,
617				devpriv->mite->daq_io_addr +
618				Master_DMA_And_Interrupt_Control);
619		}
620#endif
621		flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
622		status = readb(devpriv->mite->daq_io_addr +
623			Interrupt_And_Window_Status);
624		//DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n",
625		//      IntEn,flags,status);
626		//ni_pcidio_print_flags(flags);
627		//ni_pcidio_print_status(status);
628	}
629
630      out:
631	ni_pcidio_event(dev, s);
632#if 0
633	if (!tag) {
634		writeb(0x03,
635			devpriv->mite->daq_io_addr +
636			Master_DMA_And_Interrupt_Control);
637	}
638#endif
639	return IRQ_HANDLED;
640}
641
642#ifdef DEBUG_FLAGS
643static const char *const flags_strings[] = {
644	"TransferReady", "CountExpired", "2", "3",
645	"4", "Waited", "PrimaryTC", "SecondaryTC",
646};
647static void ni_pcidio_print_flags(unsigned int flags)
648{
649	int i;
650
651	printk("group_1_flags:");
652	for (i = 7; i >= 0; i--) {
653		if (flags & (1 << i)) {
654			printk(" %s", flags_strings[i]);
655		}
656	}
657	printk("\n");
658}
659static char *status_strings[] = {
660	"DataLeft1", "Reserved1", "Req1", "StopTrig1",
661	"DataLeft2", "Reserved2", "Req2", "StopTrig2",
662};
663static void ni_pcidio_print_status(unsigned int flags)
664{
665	int i;
666
667	printk("group_status:");
668	for (i = 7; i >= 0; i--) {
669		if (flags & (1 << i)) {
670			printk(" %s", status_strings[i]);
671		}
672	}
673	printk("\n");
674}
675#endif
676
677#ifdef unused
678static void debug_int(struct comedi_device * dev)
679{
680	int a, b;
681	static int n_int = 0;
682	struct timeval tv;
683
684	do_gettimeofday(&tv);
685	a = readb(devpriv->mite->daq_io_addr + Group_Status);
686	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
687
688	if (n_int < 10) {
689		DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
690			(int)tv.tv_usec);
691	}
692
693	while (b & 1) {
694		writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
695		b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
696	}
697
698	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
699
700	if (n_int < 10) {
701		DPRINTK("new status 0x%02x\n", b);
702		n_int++;
703	}
704}
705#endif
706
707static int ni_pcidio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
708	struct comedi_insn * insn, unsigned int * data)
709{
710	if (insn->n != 1)
711		return -EINVAL;
712	switch (data[0]) {
713	case INSN_CONFIG_DIO_OUTPUT:
714		s->io_bits |= 1 << CR_CHAN(insn->chanspec);
715		break;
716	case INSN_CONFIG_DIO_INPUT:
717		s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
718		break;
719	case INSN_CONFIG_DIO_QUERY:
720		data[1] =
721			(s->io_bits & (1 << CR_CHAN(insn->
722					chanspec))) ? COMEDI_OUTPUT :
723			COMEDI_INPUT;
724		return insn->n;
725		break;
726	default:
727		return -EINVAL;
728	}
729	writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
730
731	return 1;
732}
733
734static int ni_pcidio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
735	struct comedi_insn * insn, unsigned int * data)
736{
737	if (insn->n != 2)
738		return -EINVAL;
739	if (data[0]) {
740		s->state &= ~data[0];
741		s->state |= (data[0] & data[1]);
742		writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
743	}
744	data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
745
746	return 2;
747}
748
749static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
750	struct comedi_cmd * cmd)
751{
752	int err = 0;
753	int tmp;
754
755	/* step 1: make sure trigger sources are trivially valid */
756
757	tmp = cmd->start_src;
758	cmd->start_src &= TRIG_NOW | TRIG_INT;
759	if (!cmd->start_src || tmp != cmd->start_src)
760		err++;
761
762	tmp = cmd->scan_begin_src;
763	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
764	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
765		err++;
766
767	tmp = cmd->convert_src;
768	cmd->convert_src &= TRIG_NOW;
769	if (!cmd->convert_src || tmp != cmd->convert_src)
770		err++;
771
772	tmp = cmd->scan_end_src;
773	cmd->scan_end_src &= TRIG_COUNT;
774	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
775		err++;
776
777	tmp = cmd->stop_src;
778	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
779	if (!cmd->stop_src || tmp != cmd->stop_src)
780		err++;
781
782	if (err)
783		return 1;
784
785	/* step 2: make sure trigger sources are unique and mutually compatible */
786
787	/* note that mutual compatiblity is not an issue here */
788	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
789		err++;
790	if (cmd->scan_begin_src != TRIG_TIMER &&
791		cmd->scan_begin_src != TRIG_EXT)
792		err++;
793
794	if (err)
795		return 2;
796
797	/* step 3: make sure arguments are trivially compatible */
798
799	if (cmd->start_arg != 0) {
800		/* same for both TRIG_INT and TRIG_NOW */
801		cmd->start_arg = 0;
802		err++;
803	}
804#define MAX_SPEED	(TIMER_BASE)	/* in nanoseconds */
805
806	if (cmd->scan_begin_src == TRIG_TIMER) {
807		if (cmd->scan_begin_arg < MAX_SPEED) {
808			cmd->scan_begin_arg = MAX_SPEED;
809			err++;
810		}
811		/* no minumum speed */
812	} else {
813		/* TRIG_EXT */
814		/* should be level/edge, hi/lo specification here */
815		if (cmd->scan_begin_arg != 0) {
816			cmd->scan_begin_arg = 0;
817			err++;
818		}
819	}
820	if (cmd->convert_arg != 0) {
821		cmd->convert_arg = 0;
822		err++;
823	}
824
825	if (cmd->scan_end_arg != cmd->chanlist_len) {
826		cmd->scan_end_arg = cmd->chanlist_len;
827		err++;
828	}
829	if (cmd->stop_src == TRIG_COUNT) {
830		/* no limit */
831	} else {
832		/* TRIG_NONE */
833		if (cmd->stop_arg != 0) {
834			cmd->stop_arg = 0;
835			err++;
836		}
837	}
838
839	if (err)
840		return 3;
841
842	/* step 4: fix up any arguments */
843
844	if (cmd->scan_begin_src == TRIG_TIMER) {
845		tmp = cmd->scan_begin_arg;
846		ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
847			cmd->flags & TRIG_ROUND_MASK);
848		if (tmp != cmd->scan_begin_arg)
849			err++;
850	}
851
852	if (err)
853		return 4;
854
855	return 0;
856}
857
858static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
859{
860	int divider, base;
861
862	base = TIMER_BASE;
863
864	switch (round_mode) {
865	case TRIG_ROUND_NEAREST:
866	default:
867		divider = (*nanosec + base / 2) / base;
868		break;
869	case TRIG_ROUND_DOWN:
870		divider = (*nanosec) / base;
871		break;
872	case TRIG_ROUND_UP:
873		divider = (*nanosec + base - 1) / base;
874		break;
875	}
876
877	*nanosec = base * divider;
878	return divider;
879}
880
881static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
882{
883	struct comedi_cmd *cmd = &s->async->cmd;
884
885	/* XXX configure ports for input */
886	writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
887
888	if (1) {
889		/* enable fifos A B C D */
890		writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
891
892		/* set transfer width a 32 bits */
893		writeb(TransferWidth(0) | TransferLength(0),
894			devpriv->mite->daq_io_addr + Transfer_Size_Control);
895	} else {
896		writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
897		writeb(TransferWidth(3) | TransferLength(0),
898			devpriv->mite->daq_io_addr + Transfer_Size_Control);
899	}
900
901	/* protocol configuration */
902	if (cmd->scan_begin_src == TRIG_TIMER) {
903		/* page 4-5, "input with internal REQs" */
904		writeb(0, devpriv->mite->daq_io_addr + OpMode);
905		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
906		writeb(1, devpriv->mite->daq_io_addr + Sequence);
907		writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
908		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
909		writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
910		writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
911		writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
912				TRIG_ROUND_NEAREST),
913			devpriv->mite->daq_io_addr + StartDelay);
914		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
915		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
916		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
917		writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
918		writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
919		/* manual, page 4-5: ClockSpeed comment is incorrectly listed
920		 * on DAQOptions */
921		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
922		writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
923	} else {
924		/* TRIG_EXT */
925		/* page 4-5, "input with external REQs" */
926		writeb(0, devpriv->mite->daq_io_addr + OpMode);
927		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
928		writeb(0, devpriv->mite->daq_io_addr + Sequence);
929		writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
930		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
931		writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
932		writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
933		writel(1, devpriv->mite->daq_io_addr + StartDelay);
934		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
935		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
936		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
937		writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
938		writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
939		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
940		writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
941	}
942
943	if (cmd->stop_src == TRIG_COUNT) {
944		writel(cmd->stop_arg,
945			devpriv->mite->daq_io_addr + Transfer_Count);
946	} else {
947		/* XXX */
948	}
949
950#ifdef USE_DMA
951	writeb(ClearPrimaryTC | ClearSecondaryTC,
952		devpriv->mite->daq_io_addr + Group_1_First_Clear);
953
954	{
955		int retval = setup_mite_dma(dev, s);
956		if (retval)
957			return retval;
958	}
959#else
960	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
961#endif
962	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
963
964	/* clear and enable interrupts */
965	writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
966	//writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear);
967
968	writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
969	writeb(0x03,
970		devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
971
972	if (cmd->stop_src == TRIG_NONE) {
973		devpriv->OpModeBits = DataLatching(0) | RunMode(7);
974	} else {		// TRIG_TIMER
975		devpriv->OpModeBits = Numbered | RunMode(7);
976	}
977	if (cmd->start_src == TRIG_NOW) {
978		/* start */
979		writeb(devpriv->OpModeBits,
980			devpriv->mite->daq_io_addr + OpMode);
981		s->async->inttrig = NULL;
982	} else {
983		/* TRIG_INT */
984		s->async->inttrig = ni_pcidio_inttrig;
985	}
986
987	DPRINTK("ni_pcidio: command started\n");
988	return 0;
989}
990
991static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s)
992{
993	int retval;
994
995	retval = ni_pcidio_request_di_mite_channel(dev);
996	if (retval)
997		return retval;
998
999	devpriv->di_mite_chan->dir = COMEDI_INPUT;
1000
1001	mite_prep_dma(devpriv->di_mite_chan, 32, 32);
1002
1003	mite_dma_arm(devpriv->di_mite_chan);
1004	return 0;
1005}
1006
1007static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
1008	unsigned int trignum)
1009{
1010	if (trignum != 0)
1011		return -EINVAL;
1012
1013	writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
1014	s->async->inttrig = NULL;
1015
1016	return 1;
1017}
1018
1019static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
1020{
1021	writeb(0x00,
1022		devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
1023	ni_pcidio_release_di_mite_channel(dev);
1024
1025	return 0;
1026}
1027
1028static int ni_pcidio_change(struct comedi_device * dev, struct comedi_subdevice * s,
1029	unsigned long new_size)
1030{
1031	int ret;
1032
1033	ret = mite_buf_change(devpriv->di_mite_ring, s->async);
1034	if (ret < 0)
1035		return ret;
1036
1037	memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
1038
1039	return 0;
1040}
1041
1042static int pci_6534_load_fpga(struct comedi_device * dev, int fpga_index, u8 * data,
1043	int data_len)
1044{
1045	static const int timeout = 1000;
1046	int i, j;
1047	writew(0x80 | fpga_index,
1048		devpriv->mite->daq_io_addr + Firmware_Control_Register);
1049	writew(0xc0 | fpga_index,
1050		devpriv->mite->daq_io_addr + Firmware_Control_Register);
1051	for (i = 0;
1052		(readw(devpriv->mite->daq_io_addr +
1053				Firmware_Status_Register) & 0x2) == 0
1054		&& i < timeout; ++i) {
1055		udelay(1);
1056	}
1057	if (i == timeout) {
1058		printk("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n", fpga_index);
1059		return -EIO;
1060	}
1061	writew(0x80 | fpga_index,
1062		devpriv->mite->daq_io_addr + Firmware_Control_Register);
1063	for (i = 0;
1064		readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
1065		0x3 && i < timeout; ++i) {
1066		udelay(1);
1067	}
1068	if (i == timeout) {
1069		printk("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n", fpga_index);
1070		return -EIO;
1071	}
1072	for (j = 0; j + 1 < data_len;) {
1073		unsigned int value = data[j++];
1074		value |= data[j++] << 8;
1075		writew(value,
1076			devpriv->mite->daq_io_addr + Firmware_Data_Register);
1077		for (i = 0;
1078			(readw(devpriv->mite->daq_io_addr +
1079					Firmware_Status_Register) & 0x2) == 0
1080			&& i < timeout; ++i) {
1081			udelay(1);
1082		}
1083		if (i == timeout) {
1084			printk("ni_pcidio: failed to load word into fpga %i\n",
1085				fpga_index);
1086			return -EIO;
1087		}
1088		if (need_resched())
1089			schedule();
1090	}
1091	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1092	return 0;
1093}
1094
1095static int pci_6534_reset_fpga(struct comedi_device * dev, int fpga_index)
1096{
1097	return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
1098}
1099
1100static int pci_6534_reset_fpgas(struct comedi_device * dev)
1101{
1102	int ret;
1103	int i;
1104	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1105	for (i = 0; i < 3; ++i) {
1106		ret = pci_6534_reset_fpga(dev, i);
1107		if (ret < 0)
1108			break;
1109	}
1110	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
1111	return ret;
1112}
1113
1114static void pci_6534_init_main_fpga(struct comedi_device * dev)
1115{
1116	writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
1117	writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
1118	writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
1119	writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
1120	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
1121	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
1122}
1123
1124static int pci_6534_upload_firmware(struct comedi_device * dev, int options[])
1125{
1126	int ret;
1127	void *main_fpga_data, *scarab_a_data, *scarab_b_data;
1128	int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len;
1129
1130	if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0)
1131		return 0;
1132	ret = pci_6534_reset_fpgas(dev);
1133	if (ret < 0)
1134		return ret;
1135	main_fpga_data = comedi_aux_data(options, 0);
1136	main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
1137	ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len);
1138	if (ret < 0)
1139		return ret;
1140	pci_6534_init_main_fpga(dev);
1141	scarab_a_data = comedi_aux_data(options, 1);
1142	scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
1143	ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len);
1144	if (ret < 0)
1145		return ret;
1146	scarab_b_data = comedi_aux_data(options, 2);
1147	scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
1148	ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len);
1149	if (ret < 0)
1150		return ret;
1151	return 0;
1152}
1153
1154static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
1155{
1156	struct comedi_subdevice *s;
1157	int i;
1158	int ret;
1159	int n_subdevices;
1160	unsigned int irq;
1161
1162	printk("comedi%d: nidio:", dev->minor);
1163
1164	if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0)
1165		return ret;
1166	spin_lock_init(&devpriv->mite_channel_lock);
1167
1168	ret = nidio_find_device(dev, it->options[0], it->options[1]);
1169	if (ret < 0)
1170		return ret;
1171
1172	ret = mite_setup(devpriv->mite);
1173	if (ret < 0) {
1174		printk("error setting up mite\n");
1175		return ret;
1176	}
1177	comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
1178	devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
1179	if (devpriv->di_mite_ring == NULL)
1180		return -ENOMEM;
1181
1182	dev->board_name = this_board->name;
1183	irq = mite_irq(devpriv->mite);
1184	printk(" %s", dev->board_name);
1185	if (this_board->uses_firmware) {
1186		ret = pci_6534_upload_firmware(dev, it->options);
1187		if (ret < 0)
1188			return ret;
1189	}
1190	if (!this_board->is_diodaq) {
1191		n_subdevices = this_board->n_8255;
1192	} else {
1193		n_subdevices = 1;
1194	}
1195	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
1196		return ret;
1197
1198	if (!this_board->is_diodaq) {
1199		for (i = 0; i < this_board->n_8255; i++) {
1200			subdev_8255_init(dev, dev->subdevices + i,
1201				nidio96_8255_cb,
1202				(unsigned long)(devpriv->mite->daq_io_addr +
1203					NIDIO_8255_BASE(i)));
1204		}
1205	} else {
1206
1207		printk(" rev=%d",
1208			readb(devpriv->mite->daq_io_addr + Chip_Version));
1209
1210		s = dev->subdevices + 0;
1211
1212		dev->read_subdev = s;
1213		s->type = COMEDI_SUBD_DIO;
1214		s->subdev_flags =
1215			SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
1216			SDF_CMD_READ;
1217		s->n_chan = 32;
1218		s->range_table = &range_digital;
1219		s->maxdata = 1;
1220		s->insn_config = &ni_pcidio_insn_config;
1221		s->insn_bits = &ni_pcidio_insn_bits;
1222		s->do_cmd = &ni_pcidio_cmd;
1223		s->do_cmdtest = &ni_pcidio_cmdtest;
1224		s->cancel = &ni_pcidio_cancel;
1225		s->len_chanlist = 32;	/* XXX */
1226		s->buf_change = &ni_pcidio_change;
1227		s->async_dma_dir = DMA_BIDIRECTIONAL;
1228
1229		writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
1230		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
1231		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));
1232
1233		/* disable interrupts on board */
1234		writeb(0x00,
1235			devpriv->mite->daq_io_addr +
1236			Master_DMA_And_Interrupt_Control);
1237
1238		ret = comedi_request_irq(irq, nidio_interrupt, IRQF_SHARED,
1239			"ni_pcidio", dev);
1240		if (ret < 0) {
1241			printk(" irq not available");
1242		}
1243		dev->irq = irq;
1244	}
1245
1246	printk("\n");
1247
1248	return 0;
1249}
1250
1251static int nidio_detach(struct comedi_device * dev)
1252{
1253	int i;
1254
1255	if (this_board && !this_board->is_diodaq) {
1256		for (i = 0; i < this_board->n_8255; i++) {
1257			subdev_8255_cleanup(dev, dev->subdevices + i);
1258		}
1259	}
1260
1261	if (dev->irq)
1262		comedi_free_irq(dev->irq, dev);
1263
1264	if (devpriv) {
1265		if (devpriv->di_mite_ring) {
1266			mite_free_ring(devpriv->di_mite_ring);
1267			devpriv->di_mite_ring = NULL;
1268		}
1269		if (devpriv->mite)
1270			mite_unsetup(devpriv->mite);
1271	}
1272	return 0;
1273}
1274
1275static int nidio_find_device(struct comedi_device * dev, int bus, int slot)
1276{
1277	struct mite_struct *mite;
1278	int i;
1279
1280	for (mite = mite_devices; mite; mite = mite->next) {
1281		if (mite->used)
1282			continue;
1283		if (bus || slot) {
1284			if (bus != mite->pcidev->bus->number ||
1285				slot != PCI_SLOT(mite->pcidev->devfn))
1286				continue;
1287		}
1288		for (i = 0; i < n_nidio_boards; i++) {
1289			if (mite_device_id(mite) == nidio_boards[i].dev_id) {
1290				dev->board_ptr = nidio_boards + i;
1291				devpriv->mite = mite;
1292
1293				return 0;
1294			}
1295		}
1296	}
1297	printk("no device found\n");
1298	mite_list_devices();
1299	return -EIO;
1300}
1301
1302COMEDI_PCI_INITCLEANUP(driver_pcidio, ni_pcidio_pci_table);
1303