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