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