changed a bunch of #include <blah.h> to #include "blah.h" so that make dep
authorFrank Mori Hess <fmhess@speakeasy.net>
Thu, 21 Jun 2001 20:59:50 +0000 (20:59 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Thu, 21 Jun 2001 20:59:50 +0000 (20:59 +0000)
catches the dependencies

17 files changed:
comedi/drivers/adl_pci9118.c
comedi/drivers/adv_pci1710.c
comedi/drivers/daqboard2000.c
comedi/drivers/das08.c
comedi/drivers/das16.c
comedi/drivers/das16m1.c
comedi/drivers/ni_atmio.c
comedi/drivers/ni_atmio16d.c
comedi/drivers/ni_mio_common.c
comedi/drivers/ni_mio_cs.c
comedi/drivers/ni_pcidio.c
comedi/drivers/ni_pcimio.c
comedi/drivers/pcl711.c
comedi/drivers/pcl724.c
comedi/drivers/pcl812.c
comedi/drivers/pcl818.c
comedi/drivers/rti800.c

index 3d956282692ea6aac09d29865c4949df611b5605..691f68d501b2d7134cce6dc2761d59739264aff7 100644 (file)
@@ -30,8 +30,8 @@
 #include <linux/pci.h>
 #include <asm/io.h>
 #include <linux/comedidev.h>
-#include <amcc_s5933.h>
-#include <8253.h>
+#include "amcc_s5933.h"
+#include "8253.h"
 
 #define PCL9118_PARANOIDCHECK          /* if defined, then is used code which control correct channel number on every 12 bit sample */
 
index d356436518c7517a8d35c7818e8516859f51d272..7f21ab8cc3ed49bba6174cdedbe69102acafdb29 100644 (file)
@@ -31,8 +31,8 @@
 #include <linux/pci.h>
 #include <asm/io.h>
 #include <linux/comedidev.h>
-#include <8253.h>
-#include <amcc_s5933.h>
+#include "8253.h"
+#include "amcc_s5933.h"
 
 
 #define ADVANTECH_VENDOR       0x13fe  /* Advantech PCI vendor ID */
index bef7ea3fe479e2900ad944a8b6de436382ce6c47..50cf8790cb05ae26e6732e253f5088710bac2b80 100644 (file)
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <linux/comedidev.h>
-#include <8255.h>
+#include "8255.h"
 #ifdef CONFIG_COMEDI_DAQBOARD2000_FPGA
-#include <daqboard2000_fpga.h>
+#include "daqboard2000_fpga.h"
 #endif
 
 #define DAQBOARD2000_SUBSYSTEM_IDS2    0x00021616 /* Daqboard/2000 - 2 Dacs */
index 8df4be6cc96b7fa6a3e3593c805fcc595f0ec892..14fa7ecf6ecaea062e1ef9fb77429039601ccbcb 100644 (file)
@@ -34,7 +34,7 @@ Support for pci-das08 card added by Frank M. Hess
 #include <asm/io.h>
 #include <linux/malloc.h>
 #include <linux/delay.h>
-#include <8255.h>
+#include "8255.h"
 #include <linux/pci.h>
 
 
index a508811996fdaed5486901dacea85af86c46ab45..aa606754c575eed6e8577cd28df136e9f9f8959e 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/io.h>
 #include <linux/malloc.h>
 #include <linux/delay.h>
-#include <8255.h>
+#include "8255.h"
 
 
 #define DAS16_SIZE 20
index 29de95bf8f9a22d2d98c5c80a3dcc8648146911f..221bc93217262e78eb624dcdc667f1c44d2cbfc4 100644 (file)
@@ -51,8 +51,8 @@ list has 2 or more channels in it, then two conditions must be satisfied:
 #include <asm/io.h>
 #include <linux/malloc.h>
 #include <linux/delay.h>
-#include <8255.h>
-#include <8253.h>
+#include "8255.h"
+#include "8253.h"
 
 #define DAS16M1_SIZE 16
 #define DAS16M1_SIZE2 8
index 473b12eb4ce4fad5d54b7e82776ae3a5aa1f4d97..ebfca54e3cfb5f33067867229f62d6702cfd2769 100644 (file)
@@ -69,8 +69,8 @@
 #include <linux/isapnp.h>
 #include <linux/pci.h>
 #endif
-#include <ni_stc.h>
-#include <8255.h>
+#include "ni_stc.h"
+#include "8255.h"
 
 #undef DEBUG
 
index 89d742f3fd34e11a5b8363de153c059a3e44576a..7720d4916ae9d9c8047885458b5a57a5562baac4 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/timer.h>
 #include <asm/io.h>
 #include <linux/comedidev.h>
-#include <8255.h>
+#include "8255.h"
 
 
 /* Configuration and Status Registers */
index 02e1d821944495bfa36ed845dadc65f72c185387..970439a0c4add79b025860b1e08d9e15561a04aa 100644 (file)
-
-/*
-    comedi/drivers/ni_mio_common.c
-    Hardware driver for DAQ-STC based boards
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/*
-       This file is meant to be included by another file, e.g.,
-       ni_atmio.c or ni_pcimio.c.
-
-       Interrupt support originally added by Truxton Fulton
-       <trux@truxton.com>
-
-       References (from ftp://ftp.natinst.com/support/manuals):
-       
-          340747b.pdf  AT-MIO E series Register Level Programmer Manual
-          341079b.pdf  PCI E Series RLPM
-          340934b.pdf  DAQ-STC reference manual
-
-       Other possibly relevant info:
-       
-          320517c.pdf  User manual (obsolete)
-          320517f.pdf  User manual (new)
-          320889a.pdf  delete
-          320906c.pdf  maximum signal ratings
-          321066a.pdf  about 16x
-          321791a.pdf  discontinuation of at-mio-16e-10 rev. c
-          321808a.pdf  about at-mio-16e-10 rev P
-          321837a.pdf  discontinuation of at-mio-16de-10 rev d
-          321838a.pdf  about at-mio-16de-10 rev N
-       
-       ISSUES:
-
-        - the interrupt routine needs to be cleaned up
-        - many printk's need to be changed to rt_printk()
-*/
-
-//#define DEBUG_INTERRUPT
-//#define TRY_BLOCK
-#define DEBUG_STATUS_A
-//#define DEBUG_STATUS_B
-
-#include <8255.h>
-
-#ifndef MDPRINTK
-#define MDPRINTK(format,args...)
-#endif
-
-/* reference: ground, common, differential, other */
-static int ni_modebits1[4]={ 0x3000, 0x2000, 0x1000, 0 };
-static int ni_modebits2[4]={ 0x3f, 0x3f, 0x37, 0x37 };
-
-static int ni_gainlkup[][16]={
-       { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
-       { 1, 2, 4, 7, 9, 10, 12, 15, 0,0,0,0,0,0,0,0 },
-       { 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 0,0 },
-       { 0, 1, 4, 7, 8, 9, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0 },
-       { 0, 1, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-};
-
-static comedi_lrange range_ni_E_ai={   16, {
-       RANGE( -10,     10      ),
-       RANGE( -5,      5       ),
-       RANGE( -2.5,    2.5     ),
-       RANGE( -1,      1       ),
-       RANGE( -0.5,    0.5     ),
-       RANGE( -0.25,   0.25    ),
-       RANGE( -0.1,    0.1     ),
-       RANGE( -0.05,   0.05    ),
-       RANGE( 0,       20      ),
-       RANGE( 0,       10      ),
-       RANGE( 0,       5       ),
-       RANGE( 0,       2       ),
-       RANGE( 0,       1       ),
-       RANGE( 0,       0.5     ),
-       RANGE( 0,       0.2     ),
-       RANGE( 0,       0.1     ),
-}};
-static comedi_lrange range_ni_E_ai_limited={   8, {
-       RANGE( -10,     10      ),
-       RANGE( -5,      5       ),
-       RANGE( -1,      1       ),
-       RANGE( -0.1,    0.1     ),
-       RANGE( 0,       10      ),
-       RANGE( 0,       5       ),
-       RANGE( 0,       1       ),
-       RANGE( 0,       0.1     ),
-}};
-static comedi_lrange range_ni_E_ai_limited14={ 14, {
-       RANGE( -10,     10      ),
-       RANGE( -5,      5       ),
-       RANGE( -2,      2       ),
-       RANGE( -1,      1       ),
-       RANGE( -0.5,    0.5     ),
-       RANGE( -0.2,    0.2     ),
-       RANGE( -0.1,    0.1     ),
-       RANGE( 0,       10      ),
-       RANGE( 0,       5       ),
-       RANGE( 0,       2       ),
-       RANGE( 0,       1       ),
-       RANGE( 0,       0.5     ),
-       RANGE( 0,       0.2     ),
-       RANGE( 0,       0.1     ),
-}};
-static comedi_lrange range_ni_E_ai_bipolar4={ 4, {
-       RANGE( -10,     10      ),
-       RANGE( -5,      5       ),
-       RANGE( -0.5,    0.5     ),
-       RANGE( -0.05,   0.05    ),
-}};
-#if 0
-static comedi_lrange range_ni_E_ao = { 2, {
-       RANGE( -10,     10      ),
-       RANGE( 0,       10      ),
-}};
-#endif
-static comedi_lrange range_ni_E_ao_ext = { 4, {
-       RANGE( -10,     10      ),
-       RANGE( 0,       10      ),
-       RANGE_ext( -1,  1       ),
-       RANGE_ext( 0,   1       ),
-}};
-
-static comedi_lrange *ni_range_lkup[]={
-       &range_ni_E_ai,
-       &range_ni_E_ai_limited,
-       &range_ni_E_ai_limited14,
-       &range_ni_E_ai_bipolar4,
-};
-
-
-
-static int ni_dio_insn_config(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-static int ni_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-
-static int ni_calib_insn_read(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-static int ni_calib_insn_write(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-
-static int ni_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-
-static void caldac_setup(comedi_device *dev,comedi_subdevice *s);
-static int ni_read_eeprom(comedi_device *dev,int addr);
-
-#ifdef DEBUG_STATUS_A
-static void ni_mio_print_status_a(int status);
-#else
-#define ni_mio_print_status_a(a)
-#endif
-#ifdef DEBUG_STATUS_B
-static void ni_mio_print_status_b(int status);
-#else
-#define ni_mio_print_status_b(a)
-#endif
-
-static int ni_ai_reset(comedi_device *dev,comedi_subdevice *s);
-static void ni_handle_fifo_half_full(comedi_device *dev);
-static void ni_handle_fifo_dregs(comedi_device *dev);
-#ifdef TRY_BLOCK
-static void ni_handle_block(comedi_device *dev);
-#endif
-#ifdef PCIDMA
-static void ni_handle_block_dma(comedi_device *dev);
-#endif
-static int ni_ai_inttrig(comedi_device *dev,comedi_subdevice *s,
-       unsigned int trignum);
-
-static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s);
-
-static int ni_8255_callback(int dir,int port,int data,void *arg);
-
-static int ni_ns_to_timer(int *nanosec,int round_mode);
-
-//static int gpct_setup(comedi_device *dev,comedi_subdevice *s);
-static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-
-static void pfi_setup(comedi_device *dev);
-
-/*GPCT function def's*/
-int GPCT_G_Watch(comedi_device *dev, int chan);
-
-void GPCT_Reset(comedi_device *dev, int chan);
-void GPCT_Gen_Cont_Pulse(comedi_device *dev, int chan, unsigned int length);
-void GPCT_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length);
-void GPCT_Period_Meas(comedi_device *dev, int chan);
-void GPCT_Pulse_Width_Meas(comedi_device *dev, int chan);
-void GPCT_Event_Counting(comedi_device *dev,int chan);
-int GPCT_Set_Direction(comedi_device *dev,int chan,int direction);
-int GPCT_Set_Gate(comedi_device *dev,int chan ,int gate);
-int GPCT_Set_Source(comedi_device *dev,int chan ,int source);
-
-static int ni_gpct_insn_write(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data);
-
-#undef DEBUG
-
-#define AIMODE_NONE            0
-#define AIMODE_HALF_FULL       1
-#define AIMODE_SCAN            2
-#define AIMODE_SAMPLE          3
-
-static void handle_a_interrupt(comedi_device *dev,unsigned short status);
-static void handle_b_interrupt(comedi_device *dev,unsigned short status);
-#ifdef PCIDMA
-/*status must be long because the CHSR is 32 bits and the high bits
-are important to us */
-static void mite_handle_interrupt(comedi_device *dev,unsigned long status);
-void ni_munge(comedi_device *dev,comedi_subdevice *s,sampl_t *start, sampl_t *stop);
-#endif
-
-/* ni_set_bits( ) allows different parts of the ni_mio_common driver to 
-* share registers (such as Interrupt_A_Register) without interfering with
-* each other.  Use comedi_spin_lock_irqsave() and comedi_spin_unlock_irqrestore()
-* if you use this to modify the interrupt enable registers...which are sometimes
-* changed in ISRs
-*
-* NOTE: the switch/case statements are optimized out for a constant argument
-* so this is actually quite fast---  If you must wrap another function around this
-* make it inline to avoid a large speed penalty.
-*
-* value should only be 1 or 0.
-*/
-void inline ni_set_bits(comedi_device *dev, int reg, int bits, int value) {
-       
-       switch (reg){
-               case Interrupt_A_Enable_Register:
-                       if(value)
-                               devpriv->int_a_enable_reg |= bits;
-                       else
-                               devpriv->int_a_enable_reg &= ~bits;
-                       win_out(devpriv->int_a_enable_reg,Interrupt_A_Enable_Register);
-                       break;
-               case Interrupt_B_Enable_Register:
-                       if(value)
-                               devpriv->int_b_enable_reg |= bits;
-                       else
-                               devpriv->int_b_enable_reg &= ~bits;
-                       win_out(devpriv->int_b_enable_reg,Interrupt_B_Enable_Register);
-                       break;
-               case IO_Bidirection_Pin_Register:
-                       if(value)
-                               devpriv->io_bidirection_pin_reg |= bits;
-                       else
-                               devpriv->io_bidirection_pin_reg &= ~bits;
-                       win_out(devpriv->io_bidirection_pin_reg,IO_Bidirection_Pin_Register);
-                       break;
-               default:
-                       printk("Warning ni_set_bits() called with invalid arguments\n");
-                       printk("reg is %d\n",reg);
-                       break;
-       }
-}
-
-
-static
-void ni_E_interrupt(int irq,void *d,struct pt_regs * regs)
-{
-       comedi_device *dev=d;
-       unsigned short a_status;
-       unsigned short b_status;
-       int wsave;
-#ifdef PCIDMA
-       /* m_status must be long because the CHSR is a 32 bit register and we are
-       interested in several high bits */
-       unsigned long m_status;
-#endif
-
-       MDPRINTK("ni_E_Interrupt\n");
-/*
-    If you want to use windowed registers in an interrupt, it is
-    important that you restore the window address register.  If
-    you change certain modes, e.g., AI_Configuration_Start/End,
-    you need to set up software flags for non-interrupt routines.
-*/
-       wsave=win_save();
-       
-       a_status=ni_readw(AI_Status_1);
-       b_status=ni_readw(AO_Status_1);
-#ifdef PCIDMA
-       m_status=readl(devpriv->mite->mite_io_addr+MITE_CHSR+CHAN_OFFSET(0));
-#endif
-#ifdef DEBUG_INTERRUPT
-       rt_printk("ni_mio_common: interrupt: a_status=%04x b_status=%04x\n",
-               a_status,b_status);
-       ni_mio_print_status_a(a_status);
-       ni_mio_print_status_b(b_status);
-#endif
-#ifdef PCIDMA
-       //rt_printk("mite status=0x%08lx\n",m_status);
-       if(m_status&CHSR_INT)mite_handle_interrupt(dev,m_status);
-#endif
-       if(a_status&Interrupt_A_St)handle_a_interrupt(dev,a_status);
-       if(b_status&Interrupt_B_St)handle_b_interrupt(dev,b_status);
-       
-       win_restore(wsave);
-       MDPRINTK("exit ni_E_Interrupt\n");
-}
-
-#ifdef PCIDMA
-static void mite_handle_interrupt(comedi_device *dev,unsigned long m_status)
-{
-       comedi_subdevice *s=dev->subdevices+0;
-       
-       comedi_event(dev,s,COMEDI_CB_BLOCK);
-
-       MDPRINTK("mite_handle_interrupt\n");
-       writel(CHOR_CLRLC, devpriv->mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(0));
-#if 0
-       //Don't munge the data, just update the user's status variables
-       s->async->buf_int_count=mite_bytes_transferred(devpriv->mite, 0);
-       s->async->buf_int_ptr= s->async->buf_int_count % s->async->prealloc_bufsz;     
-#else
-       //Munge the ADC data to change its format from twos complement to unsigned int
-       //This is slow but makes it more compatible with other cards
-       { 
-       unsigned int raw_ptr;
-       s->async->buf_int_count = mite_bytes_transferred(devpriv->mite, 0);
-       raw_ptr = s->async->buf_int_count % s->async->prealloc_bufsz;
-       if(s->async->buf_int_ptr > raw_ptr) {
-               ni_munge(dev,s,s->async->buf_int_ptr+s->async->prealloc_buf, 
-                       s->async->prealloc_buf+s->async->prealloc_bufsz);
-               s->async->buf_int_ptr = 0;
-       }
-       ni_munge(dev,s,s->async->buf_int_ptr+s->async->prealloc_buf, 
-               raw_ptr+s->async->prealloc_buf);
-       s->async->buf_int_ptr = raw_ptr;
-       }
-#endif
-       MDPRINTK("CHSR is 0x%08lx, count is %d\n",m_status,s->async->buf_int_count);
-       if(m_status&CHSR_DONE){
-               writel(CHOR_CLRDONE, devpriv->mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(0));
-               //printk("buf_int_count is %d, buf_int_ptr is %d\n",
-               //              s->async->buf_int_count,s->async->buf_int_ptr);
-               ni_handle_block_dma(dev);
-       }       
-       MDPRINTK("exit mite_handle_interrupt\n");
-       return; 
-}      
-
-#endif //PCIDMA
-
-static void handle_a_interrupt(comedi_device *dev,unsigned short status)
-{
-       comedi_subdevice *s=dev->subdevices+0;
-       unsigned short ack=0;
-
-       s->async->events = 0;
-
-       /* uncommon interrupt events */
-       if(status&(AI_Overrun_St|AI_Overflow_St|AI_SC_TC_Error_St|AI_SC_TC_St|AI_START1_St)){
-               if(status==0xffff){
-                       rt_printk("ni_mio_common: a_status=0xffff.  Card removed?\n");
-                       /* we probably aren't even running a command now,
-                        * so it's a good idea to be careful. */
-                       if(s->subdev_flags&SDF_RUNNING)comedi_done(dev,s);
-                       return;
-               }
-               if(status&(AI_Overrun_St|AI_Overflow_St|AI_SC_TC_Error_St)){
-                       rt_printk("ni_mio_common: ai error a_status=%04x\n",
-                               status);
-                       ni_mio_print_status_a(status);
-                       
-                       //TIM 5/11/01
-                       win_out(AI_Error_Interrupt_Ack, Interrupt_A_Ack_Register);
-                       
-                       #ifndef PCIDMA
-                       ni_handle_fifo_dregs(dev);
+\r
+/*\r
+    comedi/drivers/ni_mio_common.c\r
+    Hardware driver for DAQ-STC based boards\r
+\r
+    COMEDI - Linux Control and Measurement Device Interface\r
+    Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+\r
+*/\r
+\r
+/*\r
+       This file is meant to be included by another file, e.g.,\r
+       ni_atmio.c or ni_pcimio.c.\r
+\r
+       Interrupt support originally added by Truxton Fulton\r
+       <trux@truxton.com>\r
+\r
+       References (from ftp://ftp.natinst.com/support/manuals):\r
+       \r
+          340747b.pdf  AT-MIO E series Register Level Programmer Manual\r
+          341079b.pdf  PCI E Series RLPM\r
+          340934b.pdf  DAQ-STC reference manual\r
+\r
+       Other possibly relevant info:\r
+       \r
+          320517c.pdf  User manual (obsolete)\r
+          320517f.pdf  User manual (new)\r
+          320889a.pdf  delete\r
+          320906c.pdf  maximum signal ratings\r
+          321066a.pdf  about 16x\r
+          321791a.pdf  discontinuation of at-mio-16e-10 rev. c\r
+          321808a.pdf  about at-mio-16e-10 rev P\r
+          321837a.pdf  discontinuation of at-mio-16de-10 rev d\r
+          321838a.pdf  about at-mio-16de-10 rev N\r
+       \r
+       ISSUES:\r
+\r
+        - the interrupt routine needs to be cleaned up\r
+        - many printk's need to be changed to rt_printk()\r
+*/\r
+\r
+//#define DEBUG_INTERRUPT\r
+//#define TRY_BLOCK\r
+#define DEBUG_STATUS_A\r
+//#define DEBUG_STATUS_B\r
+\r
+#include "8255.h"\r
+\r
+#ifndef MDPRINTK\r
+#define MDPRINTK(format,args...)\r
+#endif\r
+\r
+/* reference: ground, common, differential, other */\r
+static int ni_modebits1[4]={ 0x3000, 0x2000, 0x1000, 0 };\r
+static int ni_modebits2[4]={ 0x3f, 0x3f, 0x37, 0x37 };\r
+\r
+static int ni_gainlkup[][16]={\r
+       { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },\r
+       { 1, 2, 4, 7, 9, 10, 12, 15, 0,0,0,0,0,0,0,0 },\r
+       { 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 0,0 },\r
+       { 0, 1, 4, 7, 8, 9, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0 },\r
+       { 0, 1, 4, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }\r
+};\r
+\r
+static comedi_lrange range_ni_E_ai={   16, {\r
+       RANGE( -10,     10      ),\r
+       RANGE( -5,      5       ),\r
+       RANGE( -2.5,    2.5     ),\r
+       RANGE( -1,      1       ),\r
+       RANGE( -0.5,    0.5     ),\r
+       RANGE( -0.25,   0.25    ),\r
+       RANGE( -0.1,    0.1     ),\r
+       RANGE( -0.05,   0.05    ),\r
+       RANGE( 0,       20      ),\r
+       RANGE( 0,       10      ),\r
+       RANGE( 0,       5       ),\r
+       RANGE( 0,       2       ),\r
+       RANGE( 0,       1       ),\r
+       RANGE( 0,       0.5     ),\r
+       RANGE( 0,       0.2     ),\r
+       RANGE( 0,       0.1     ),\r
+}};\r
+static comedi_lrange range_ni_E_ai_limited={   8, {\r
+       RANGE( -10,     10      ),\r
+       RANGE( -5,      5       ),\r
+       RANGE( -1,      1       ),\r
+       RANGE( -0.1,    0.1     ),\r
+       RANGE( 0,       10      ),\r
+       RANGE( 0,       5       ),\r
+       RANGE( 0,       1       ),\r
+       RANGE( 0,       0.1     ),\r
+}};\r
+static comedi_lrange range_ni_E_ai_limited14={ 14, {\r
+       RANGE( -10,     10      ),\r
+       RANGE( -5,      5       ),\r
+       RANGE( -2,      2       ),\r
+       RANGE( -1,      1       ),\r
+       RANGE( -0.5,    0.5     ),\r
+       RANGE( -0.2,    0.2     ),\r
+       RANGE( -0.1,    0.1     ),\r
+       RANGE( 0,       10      ),\r
+       RANGE( 0,       5       ),\r
+       RANGE( 0,       2       ),\r
+       RANGE( 0,       1       ),\r
+       RANGE( 0,       0.5     ),\r
+       RANGE( 0,       0.2     ),\r
+       RANGE( 0,       0.1     ),\r
+}};\r
+static comedi_lrange range_ni_E_ai_bipolar4={ 4, {\r
+       RANGE( -10,     10      ),\r
+       RANGE( -5,      5       ),\r
+       RANGE( -0.5,    0.5     ),\r
+       RANGE( -0.05,   0.05    ),\r
+}};\r
+#if 0\r
+static comedi_lrange range_ni_E_ao = { 2, {\r
+       RANGE( -10,     10      ),\r
+       RANGE( 0,       10      ),\r
+}};\r
+#endif\r
+static comedi_lrange range_ni_E_ao_ext = { 4, {\r
+       RANGE( -10,     10      ),\r
+       RANGE( 0,       10      ),\r
+       RANGE_ext( -1,  1       ),\r
+       RANGE_ext( 0,   1       ),\r
+}};\r
+\r
+static comedi_lrange *ni_range_lkup[]={\r
+       &range_ni_E_ai,\r
+       &range_ni_E_ai_limited,\r
+       &range_ni_E_ai_limited14,\r
+       &range_ni_E_ai_bipolar4,\r
+};\r
+\r
+\r
+\r
+static int ni_dio_insn_config(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+static int ni_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+\r
+static int ni_calib_insn_read(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+static int ni_calib_insn_write(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+\r
+static int ni_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+\r
+static void caldac_setup(comedi_device *dev,comedi_subdevice *s);\r
+static int ni_read_eeprom(comedi_device *dev,int addr);\r
+\r
+#ifdef DEBUG_STATUS_A\r
+static void ni_mio_print_status_a(int status);\r
+#else\r
+#define ni_mio_print_status_a(a)\r
+#endif\r
+#ifdef DEBUG_STATUS_B\r
+static void ni_mio_print_status_b(int status);\r
+#else\r
+#define ni_mio_print_status_b(a)\r
+#endif\r
+\r
+static int ni_ai_reset(comedi_device *dev,comedi_subdevice *s);\r
+static void ni_handle_fifo_half_full(comedi_device *dev);\r
+static void ni_handle_fifo_dregs(comedi_device *dev);\r
+#ifdef TRY_BLOCK\r
+static void ni_handle_block(comedi_device *dev);\r
+#endif\r
+#ifdef PCIDMA\r
+static void ni_handle_block_dma(comedi_device *dev);\r
+#endif\r
+static int ni_ai_inttrig(comedi_device *dev,comedi_subdevice *s,\r
+       unsigned int trignum);\r
+\r
+static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s);\r
+\r
+static int ni_8255_callback(int dir,int port,int data,void *arg);\r
+\r
+static int ni_ns_to_timer(int *nanosec,int round_mode);\r
+\r
+//static int gpct_setup(comedi_device *dev,comedi_subdevice *s);\r
+static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+\r
+static void pfi_setup(comedi_device *dev);\r
+\r
+/*GPCT function def's*/\r
+int GPCT_G_Watch(comedi_device *dev, int chan);\r
+\r
+void GPCT_Reset(comedi_device *dev, int chan);\r
+void GPCT_Gen_Cont_Pulse(comedi_device *dev, int chan, unsigned int length);\r
+void GPCT_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length);\r
+void GPCT_Period_Meas(comedi_device *dev, int chan);\r
+void GPCT_Pulse_Width_Meas(comedi_device *dev, int chan);\r
+void GPCT_Event_Counting(comedi_device *dev,int chan);\r
+int GPCT_Set_Direction(comedi_device *dev,int chan,int direction);\r
+int GPCT_Set_Gate(comedi_device *dev,int chan ,int gate);\r
+int GPCT_Set_Source(comedi_device *dev,int chan ,int source);\r
+\r
+static int ni_gpct_insn_write(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data);\r
+\r
+#undef DEBUG\r
+\r
+#define AIMODE_NONE            0\r
+#define AIMODE_HALF_FULL       1\r
+#define AIMODE_SCAN            2\r
+#define AIMODE_SAMPLE          3\r
+\r
+static void handle_a_interrupt(comedi_device *dev,unsigned short status);\r
+static void handle_b_interrupt(comedi_device *dev,unsigned short status);\r
+#ifdef PCIDMA\r
+/*status must be long because the CHSR is 32 bits and the high bits\r
+are important to us */\r
+static void mite_handle_interrupt(comedi_device *dev,unsigned long status);\r
+void ni_munge(comedi_device *dev,comedi_subdevice *s,sampl_t *start, sampl_t *stop);\r
+#endif\r
+\r
+/* ni_set_bits( ) allows different parts of the ni_mio_common driver to \r
+* share registers (such as Interrupt_A_Register) without interfering with\r
+* each other.  Use comedi_spin_lock_irqsave() and comedi_spin_unlock_irqrestore()\r
+* if you use this to modify the interrupt enable registers...which are sometimes\r
+* changed in ISRs\r
+*\r
+* NOTE: the switch/case statements are optimized out for a constant argument\r
+* so this is actually quite fast---  If you must wrap another function around this\r
+* make it inline to avoid a large speed penalty.\r
+*\r
+* value should only be 1 or 0.\r
+*/\r
+void inline ni_set_bits(comedi_device *dev, int reg, int bits, int value) {\r
+       \r
+       switch (reg){\r
+               case Interrupt_A_Enable_Register:\r
+                       if(value)\r
+                               devpriv->int_a_enable_reg |= bits;\r
+                       else\r
+                               devpriv->int_a_enable_reg &= ~bits;\r
+                       win_out(devpriv->int_a_enable_reg,Interrupt_A_Enable_Register);\r
+                       break;\r
+               case Interrupt_B_Enable_Register:\r
+                       if(value)\r
+                               devpriv->int_b_enable_reg |= bits;\r
+                       else\r
+                               devpriv->int_b_enable_reg &= ~bits;\r
+                       win_out(devpriv->int_b_enable_reg,Interrupt_B_Enable_Register);\r
+                       break;\r
+               case IO_Bidirection_Pin_Register:\r
+                       if(value)\r
+                               devpriv->io_bidirection_pin_reg |= bits;\r
+                       else\r
+                               devpriv->io_bidirection_pin_reg &= ~bits;\r
+                       win_out(devpriv->io_bidirection_pin_reg,IO_Bidirection_Pin_Register);\r
+                       break;\r
+               default:\r
+                       printk("Warning ni_set_bits() called with invalid arguments\n");\r
+                       printk("reg is %d\n",reg);\r
+                       break;\r
+       }\r
+}\r
+\r
+\r
+static\r
+void ni_E_interrupt(int irq,void *d,struct pt_regs * regs)\r
+{\r
+       comedi_device *dev=d;\r
+       unsigned short a_status;\r
+       unsigned short b_status;\r
+       int wsave;\r
+#ifdef PCIDMA\r
+       /* m_status must be long because the CHSR is a 32 bit register and we are\r
+       interested in several high bits */\r
+       unsigned long m_status;\r
+#endif\r
+\r
+       MDPRINTK("ni_E_Interrupt\n");\r
+/*\r
+    If you want to use windowed registers in an interrupt, it is\r
+    important that you restore the window address register.  If\r
+    you change certain modes, e.g., AI_Configuration_Start/End,\r
+    you need to set up software flags for non-interrupt routines.\r
+*/\r
+       wsave=win_save();\r
+       \r
+       a_status=ni_readw(AI_Status_1);\r
+       b_status=ni_readw(AO_Status_1);\r
+#ifdef PCIDMA\r
+       m_status=readl(devpriv->mite->mite_io_addr+MITE_CHSR+CHAN_OFFSET(0));\r
+#endif\r
+#ifdef DEBUG_INTERRUPT\r
+       rt_printk("ni_mio_common: interrupt: a_status=%04x b_status=%04x\n",\r
+               a_status,b_status);\r
+       ni_mio_print_status_a(a_status);\r
+       ni_mio_print_status_b(b_status);\r
+#endif\r
+#ifdef PCIDMA\r
+       //rt_printk("mite status=0x%08lx\n",m_status);\r
+       if(m_status&CHSR_INT)mite_handle_interrupt(dev,m_status);\r
+#endif\r
+       if(a_status&Interrupt_A_St)handle_a_interrupt(dev,a_status);\r
+       if(b_status&Interrupt_B_St)handle_b_interrupt(dev,b_status);\r
+       \r
+       win_restore(wsave);\r
+       MDPRINTK("exit ni_E_Interrupt\n");\r
+}\r
+\r
+#ifdef PCIDMA\r
+static void mite_handle_interrupt(comedi_device *dev,unsigned long m_status)\r
+{\r
+       comedi_subdevice *s=dev->subdevices+0;\r
+       \r
+       comedi_event(dev,s,COMEDI_CB_BLOCK);\r
+\r
+       MDPRINTK("mite_handle_interrupt\n");\r
+       writel(CHOR_CLRLC, devpriv->mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(0));\r
+#if 0\r
+       //Don't munge the data, just update the user's status variables\r
+       s->async->buf_int_count=mite_bytes_transferred(devpriv->mite, 0);\r
+       s->async->buf_int_ptr= s->async->buf_int_count % s->async->prealloc_bufsz;     \r
+#else\r
+       //Munge the ADC data to change its format from twos complement to unsigned int\r
+       //This is slow but makes it more compatible with other cards\r
+       { \r
+       unsigned int raw_ptr;\r
+       s->async->buf_int_count = mite_bytes_transferred(devpriv->mite, 0);\r
+       raw_ptr = s->async->buf_int_count % s->async->prealloc_bufsz;\r
+       if(s->async->buf_int_ptr > raw_ptr) {\r
+               ni_munge(dev,s,s->async->buf_int_ptr+s->async->prealloc_buf, \r
+                       s->async->prealloc_buf+s->async->prealloc_bufsz);\r
+               s->async->buf_int_ptr = 0;\r
+       }\r
+       ni_munge(dev,s,s->async->buf_int_ptr+s->async->prealloc_buf, \r
+               raw_ptr+s->async->prealloc_buf);\r
+       s->async->buf_int_ptr = raw_ptr;\r
+       }\r
+#endif\r
+       MDPRINTK("CHSR is 0x%08lx, count is %d\n",m_status,s->async->buf_int_count);\r
+       if(m_status&CHSR_DONE){\r
+               writel(CHOR_CLRDONE, devpriv->mite->mite_io_addr+MITE_CHOR+CHAN_OFFSET(0));\r
+               //printk("buf_int_count is %d, buf_int_ptr is %d\n",\r
+               //              s->async->buf_int_count,s->async->buf_int_ptr);\r
+               ni_handle_block_dma(dev);\r
+       }       \r
+       MDPRINTK("exit mite_handle_interrupt\n");\r
+       return; \r
+}      \r
+\r
+#endif //PCIDMA\r
+\r
+static void handle_a_interrupt(comedi_device *dev,unsigned short status)\r
+{\r
+       comedi_subdevice *s=dev->subdevices+0;\r
+       unsigned short ack=0;\r
+\r
+       s->async->events = 0;\r
+\r
+       /* uncommon interrupt events */\r
+       if(status&(AI_Overrun_St|AI_Overflow_St|AI_SC_TC_Error_St|AI_SC_TC_St|AI_START1_St)){\r
+               if(status==0xffff){\r
+                       rt_printk("ni_mio_common: a_status=0xffff.  Card removed?\n");\r
+                       /* we probably aren't even running a command now,\r
+                        * so it's a good idea to be careful. */\r
+                       if(s->subdev_flags&SDF_RUNNING)comedi_done(dev,s);\r
+                       return;\r
+               }\r
+               if(status&(AI_Overrun_St|AI_Overflow_St|AI_SC_TC_Error_St)){\r
+                       rt_printk("ni_mio_common: ai error a_status=%04x\n",\r
+                               status);\r
+                       ni_mio_print_status_a(status);\r
+                       \r
+                       //TIM 5/11/01\r
+                       win_out(AI_Error_Interrupt_Ack, Interrupt_A_Ack_Register);\r
+                       \r
+                       #ifndef PCIDMA\r
+                       ni_handle_fifo_dregs(dev);\r
                        #endif \r
-                                               
-                       //TIM 4/17/01
-                       //win_out(0x0000,Interrupt_A_Enable_Register);
-                       //turn off all AI interrupts
-                       ni_set_bits(dev, Interrupt_A_Enable_Register,
-                               AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|
-                               AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|
-                               AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|
-                               AI_FIFO_Interrupt_Enable,0);
-                               
-                       ni_ai_reset(dev,dev->subdevices);//added by tim
-                       comedi_done(dev,s);
-                       return;
-               }
-               if(status&AI_SC_TC_St){
-#ifdef DEBUG_INTERRUPT
-                       rt_printk("ni_mio_common: SC_TC interrupt\n");
-#endif
-#ifdef TRY_BLOCK
-                       ni_handle_block(dev);
-#else
-                       //for MITE DMA ignore the terminal count from the STC
-                       //instead finish up when the MITE asserts DONE
-#ifndef PCIDMA
-                       
-                       if(!devpriv->ai_continuous){
-                               ni_handle_fifo_dregs(dev);
-                               //win_out(0x0000,Interrupt_A_Enable_Register); TIM 4/17/01
-                               ni_set_bits(dev, Interrupt_A_Enable_Register,
-                               AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|
-                               AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|
-                               AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|
-                               AI_FIFO_Interrupt_Enable,0);
-
-                               comedi_done(dev,s);
-                       }
-#endif //PCIDMA
-#endif //TRY_BLOCK
-                       ack|=AI_SC_TC_Interrupt_Ack;
-               }
-               if(status&AI_START1_St){
-                       ack|=AI_START1_Interrupt_Ack;
-               }
-       }
-#ifndef PCIDMA
-       if(status&AI_FIFO_Half_Full_St){
-               ni_handle_fifo_half_full(dev);
-       }
-#endif //PCIDMA
-       if(devpriv->aimode==AIMODE_SCAN && status&AI_STOP_St){
-               ni_handle_fifo_dregs(dev);
-
-               s->async->events |= COMEDI_CB_EOS;
-
-               /* we need to ack the START, also */
-               ack|=AI_STOP_Interrupt_Ack|AI_START_Interrupt_Ack;
-       }
-       if(devpriv->aimode==AIMODE_SAMPLE){
-               ni_handle_fifo_dregs(dev);
-
-               //s->async->events |= COMEDI_CB_SAMPLE;
-       }
-
-       if(ack) ni_writew(ack,Interrupt_A_Ack);
-
-       comedi_event(dev,s,s->async->events);
-}
-
-static void handle_b_interrupt(comedi_device *dev,unsigned short b_status)
-{
-       comedi_subdevice *s=dev->subdevices+1;
-       //unsigned short ack=0;
-
-       if(b_status==0xffff)return;
-       if(b_status&AO_Overrun_St){
-               rt_printk("ni-E: AO FIFO underrun status=0x%04x status2=0x%04x\n",b_status,ni_readw(AO_Status_2));
-       }
-
-       if(b_status&AO_BC_TC_St){
-               rt_printk("ni-E: AO BC_TC status=0x%04x status2=0x%04x\n",b_status,ni_readw(AO_Status_2));
-       }
-
-       if(b_status&AO_FIFO_Request_St)
-               ni_ao_fifo_half_empty(dev,s);
-
-       b_status=ni_readw(AO_Status_1);
-       if(b_status&Interrupt_B_St){
-               if(b_status&AO_FIFO_Request_St){
-                       rt_printk("ni_mio_common: AO buffer underrun\n");
-               }
-               rt_printk("Ack! didn't clear AO interrupt. b_status=0x%04x\n",b_status);
-               win_out(0,Interrupt_B_Enable_Register);
-       }
-}
-
-#ifdef DEBUG_STATUS_A
-static char *status_a_strings[]={
-       "passthru0","fifo","G0_gate","G0_TC",
-       "stop","start","sc_tc","start1",
-       "start2","sc_tc_error","overflow","overrun",
-       "fifo_empty","fifo_half_full","fifo_full","interrupt_a"
-};
-
-static void ni_mio_print_status_a(int status)
-{
-       int i;
-
-       rt_printk("A status:");
-       for(i=15;i>=0;i--){
-               if(status&(1<<i)){
-                       rt_printk(" %s",status_a_strings[i]);
-               }
-       }
-       rt_printk("\n");
-}
-#endif
-
-#ifdef DEBUG_STATUS_B
-static char *status_b_strings[]={
-       "passthru1","fifo","G1_gate","G1_TC",
-       "UI2_TC","UPDATE","UC_TC","BC_TC",
-       "start1","overrun","start","bc_tc_error",
-       "fifo_empty","fifo_half_full","fifo_full","interrupt_b"
-};
-
-static void ni_mio_print_status_b(int status)
-{
-       int i;
-
-       rt_printk("B status:");
-       for(i=15;i>=0;i--){
-               if(status&(1<<i)){
-                       rt_printk(" %s",status_b_strings[i]);
-               }
-       }
-       rt_printk("\n");
-}
-#endif
-
-static void ni_ai_fifo_read(comedi_device *dev,comedi_subdevice *s,
-               sampl_t *data,int n)
-{
-       comedi_async *async = s->async;
-       int i,j;
-       sampl_t d;
-       unsigned int mask;
-
-       mask=(1<<boardtype.adbits)-1;
-       j=async->cur_chan;
-       for(i=0;i<n;i++){
-               d=ni_readw(ADC_FIFO_Data_Register);
-               d^=devpriv->ai_xorlist[j];
-               d&=mask;
-               data[i]=d;
-               j++;
-               if(j>=async->cur_chanlist_len){
-                       j=0;
-                       async->events |= COMEDI_CB_EOS;
-               }
-       }
-       async->cur_chan=j;
-}
-
-#ifdef PCIDMA
-void ni_munge(comedi_device *dev,comedi_subdevice *s,sampl_t *start, sampl_t *stop)
-{
-       comedi_async *async = s->async;
-       int j;
-       sampl_t *i;
-       unsigned int mask;
-
-       mask=(1<<boardtype.adbits)-1;
-       j=async->cur_chan;
-       for(i=start;i<stop;i++){
-               *i ^=devpriv->ai_xorlist[j];
-               *i &=mask;
-               j++;
-               j %= async->cur_chanlist_len;
-       }
-       async->cur_chan=j;
-}
-
-static void ni_handle_block_dma(comedi_device *dev)
-{
-       MDPRINTK("ni_handle_block_dma\n");
-       //mite_dump_regs(devpriv->mite);  
-       mite_dma_disarm(devpriv->mite);
-       //TIM 4/17/01 win_out(0x0000,Interrupt_A_Enable_Register);
-       ni_set_bits(dev, Interrupt_A_Enable_Register,
-               AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|
-               AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|
-               AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|
-               AI_FIFO_Interrupt_Enable,0);
-
-       ni_ai_reset(dev,dev->subdevices);
-       comedi_done(dev,dev->subdevices);
-       MDPRINTK("exit ni_handle_block_dma\n");
-}
-#endif
-
-#ifdef TRY_BLOCK
-/* Blocked mode is used to get interrupts at convenient places
- * to do DMA.  It is also useful when you want to count greater
- * than 16M scans.
- */
-static void ni_handle_block(comedi_device *dev)
-{
-       int n;
-
-       if(devpriv->ai_continuous){
-               n = devpriv->blocksize;
-       }else{
-               if(devpriv->n_left==0){
-                       ni_handle_fifo_dregs(dev);
-                       printk("end\n");
-                       //TIM 4/17/01 win_out(0x0000,Interrupt_A_Enable_Register);
-                       ni_set_bits(dev, Interrupt_A_Enable_Register,
-                               AI_SC_TC_Interrupt_Enable | AI_Start1_Interrupt_Enable|
-                               AI_Start2_Interrupt_Enable| AI_Start_Interrupt_Enable|
-                               AI_Stop_Interrupt_Enable| AI_Error_Interrupt_Enable|
-                               AI_FIFO_Interrupt_Enable,0);
-                       ni_ai_reset(dev,dev->subdevices);
-                       comedi_done(dev,dev->subdevices);
-               }else if(devpriv->n_left<=devpriv->blocksize){
-                       printk("last block %d\n",devpriv->n_left);
-                       n = devpriv->n_left;
-                       devpriv->n_left = 0;
-               }else{
-                       printk("block %d\n",devpriv->n_left);
-                       n = devpriv->blocksize;
-                       devpriv->n_left -= devpriv->blocksize;
-               }
-       }
-#if 0
-       {
-               int size=0x10000;
-
-       /* stage number of scans */
-       win_out((size-1)>>16,AI_SC_Load_A_Registers);
-       win_out((size-1)&0xffff,AI_SC_Load_A_Registers+1);
-
-       //mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
-       mode1 |= 0xe;
-       win_out(mode1,AI_Mode_1_Register);
-
-       /* load SC (Scan Count) */
-       win_out(AI_SC_Load,AI_Command_1_Register);
-
-       }
-#endif
-}
-#endif
-
-static void ni_handle_fifo_half_full(comedi_device *dev)
-{
-       int n,m;
-       comedi_subdevice *s=dev->subdevices+0;
-       comedi_async *async=s->async;
-
-       /*
-          if we got a fifo_half_full interrupt, we can transfer fifo/2
-          samples without checking the empty flag.  It doesn't matter if
-          we transfer the rest of the samples, the performance trade-off
-          is minimal (checking empty flag for a few samples vs. having
-          1% more interrupts.)  At really high speeds, it's better to
-          ignore them.
-
-       */
-
-       n=boardtype.ai_fifo_depth/2;
-
-       /* this makes the assumption that the buffer length is
-          greater than the half-fifo depth. */
-
-       if(async->buf_int_ptr+n*sizeof(sampl_t)>=async->data_len){
-               m=(async->data_len-async->buf_int_ptr)/sizeof(sampl_t);
-               ni_ai_fifo_read(dev,s,async->data+async->buf_int_ptr,m);
-               async->buf_int_count+=m*sizeof(sampl_t);
-               n-=m;
-               async->buf_int_ptr=0;
-
-               async->events |= COMEDI_CB_EOBUF;
-       }
-       ni_ai_fifo_read(dev,s,async->data+async->buf_int_ptr,n);
-       async->buf_int_count+=n*sizeof(sampl_t);
-       async->buf_int_ptr+=n*sizeof(sampl_t);
-
-       async->events |= COMEDI_CB_BLOCK;
-}
-
-/*
-   Empties the AI fifo
-*/
-static void ni_handle_fifo_dregs(comedi_device *dev)
-{
-       comedi_subdevice *s=dev->subdevices+0;
-       sampl_t *data,d;
-       int i,n;
-       int j;
-       unsigned int mask;
-
-       mask=(1<<boardtype.adbits)-1;
-       j=s->async->cur_chan;
-       data=s->async->data+s->async->buf_int_ptr;
-       while(1){
-               n=(s->async->data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
-               for(i=0;i<n;i++){
-                       if(ni_readw(AI_Status_1)&AI_FIFO_Empty_St){
-                               s->async->cur_chan=j;
-                               return;
-                       }
-                       d=ni_readw(ADC_FIFO_Data_Register);
-                       d^=devpriv->ai_xorlist[j];
-                       d&=mask;
-                       *data=d;
-                       j++;
-                       if(j>=s->async->cur_chanlist_len){
-                               j=0;
-                               //s->events |= COMEDI_CB_EOS;
-                       }
-                       data++;
-                       s->async->buf_int_ptr+=sizeof(sampl_t);
-                       s->async->buf_int_count+=sizeof(sampl_t);
-               }
-               s->async->buf_int_ptr=0;
-               data=s->async->data;
-               s->async->events |= COMEDI_CB_EOBUF;
-       }
-}
-
-#ifdef PCIDMA
-int ni_ai_setup_block_dma(comedi_device *dev,int frob,int mode1)
-{
-       int n;
-       int len;
-       unsigned long ll_start;
-       comedi_cmd *cmd=&dev->subdevices->async->cmd;
-               
-       MDPRINTK("ni_ai_setup_block_dma\n");
-               
-       /*Build MITE linked list and configure the MITE
-        * ******WARNING******
-        * There is no error handling here, 
-        * the memory buffer *Must* be mlock'ed by the user*/
-
-       len = sizeof(sampl_t)*cmd->stop_arg*cmd->scan_end_arg;
-
-       /*use kvmem if no user buf specified */
-       ll_start = mite_ll_from_kvmem(devpriv->mite,dev->subdevices->async,
-               len);
-
-       mite_setregs(devpriv->mite, ll_start,0,COMEDI_INPUT);
-
-       /*tell the STC to use DMA0 for AI. 
-        * Select the MITE DMA channel to use, 0x01=A*/
-       ni_writeb(0x01,AI_AO_Select);
-
-       /* stage number of scans */
-       n = cmd->stop_arg;
-       win_out((n-1)>>16,AI_SC_Load_A_Registers);
-       win_out((n-1)&0xffff,AI_SC_Load_A_Registers+1);
-       win_out((n-1)>>16,AI_SC_Load_B_Registers);
-       win_out((n-1)&0xffff,AI_SC_Load_B_Registers+1);
-               
-       /* load SC (Scan Count) */
-       win_out(AI_SC_Load,AI_Command_1_Register);
-
-       mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
-       win_out(mode1,AI_Mode_1_Register);
-               
-       /*start the MITE*/
-       mite_dma_arm(devpriv->mite);
-               
-       MDPRINTK("exit ni_ai_setup_block_dma\n");
-
-       return mode1;
-}
-#endif
-
-#ifdef TRY_BLOCK
-int ni_ai_setup_block(comedi_device *dev,int frob,int mode1)
-{
-       int n;
-       int last=0;
-
-printk("n_left = %d\n",devpriv->n_left);
-       if(devpriv->ai_continuous){
-               n=devpriv->blocksize;
-               last=0;
-       }else{
-               n=devpriv->n_left;
-               if(n>devpriv->blocksize){
-                       n=devpriv->blocksize;
-                       last=0;
-               }else{
-                       last=1;
-               }
-               devpriv->n_left -= n;
-       }
-
-       if(frob){
-               /* stage number of scans */
-               win_out((n-1)>>16,AI_SC_Load_A_Registers);
-               win_out((n-1)&0xffff,AI_SC_Load_A_Registers+1);
-               win_out((n-1)>>16,AI_SC_Load_B_Registers);
-               win_out((n-1)&0xffff,AI_SC_Load_B_Registers+1);
-
-               /* load SC (Scan Count) */
-               win_out(AI_SC_Load,AI_Command_1_Register);
-#if 0
-               if(!last){
-                       mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
-               }else{
-                       mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
-               }
-#endif
-               mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
-               win_out(mode1,AI_Mode_1_Register);
-
-       }
-
-       return mode1;
-}
-#endif
-
-#ifdef PCIDMA
-int ni_ai_setup_MITE_dma(comedi_device *dev,comedi_cmd *cmd,int mode1)
-{
-       int n,len;
-       unsigned long ll_start;
-       comedi_async *async_mite;
-       
-       len = sizeof(sampl_t)*cmd->stop_arg*cmd->scan_end_arg;
-       async_mite=dev->subdevices[cmd->subdev].async;
-       ll_start = mite_ll_from_kvmem(devpriv->mite, async_mite,len);
-       mite_setregs(devpriv->mite, ll_start,0,COMEDI_INPUT);
-
-       /*tell the STC to use DMA0 for AI.
-       Select the MITE DMA channel to use, 0x01=A*/
-       ni_writeb(0x01,AI_AO_Select);
-
-       /* stage number of scans */
-       n = cmd->stop_arg;
-       win_out((n-1)>>16,AI_SC_Load_A_Registers);
-       win_out((n-1)&0xffff,AI_SC_Load_A_Registers+1);
-       win_out((n-1)>>16,AI_SC_Load_B_Registers);
-       win_out((n-1)&0xffff,AI_SC_Load_B_Registers+1);
-       
-       /* load SC (Scan Count) */
-       win_out(AI_SC_Load,AI_Command_1_Register);
-
-       mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
-       win_out(mode1,AI_Mode_1_Register);
-       
-       /*start the MITE*/
-       mite_dma_arm(devpriv->mite);
-       return mode1;
-}
-#endif
-
-/*
-   used for both cancel ioctl and board initialization
-
-   this is pretty harsh for a cancel, but it works...
- */
-static int ni_ai_reset(comedi_device *dev,comedi_subdevice *s)
-{
-#ifdef PCIDMA
-       mite_dma_disarm(devpriv->mite);
-#endif
-       //TIM 4/17/01 win_out(0x0000,Interrupt_A_Enable_Register);
-       ni_set_bits(dev, Interrupt_A_Enable_Register,
-               AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|
-               AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|
-               AI_STOP_Interrupt_Enable|   AI_Error_Interrupt_Enable|
-               AI_FIFO_Interrupt_Enable,0);
-
-       win_out(AI_Reset,Joint_Reset_Register);
-
-       win_out(1,ADC_FIFO_Clear);
-
-       /* ai configuration */
-
-       win_out(AI_Configuration_Start,Joint_Reset_Register);
-
-       win_out(0x0000,AI_Command_1_Register); /* reset pulses */
-       win_out(0x000d,AI_Mode_1_Register);
-       win_out(0x0000,AI_Mode_2_Register);
-#if 0
-       win_out((1<<6)|0x0000,AI_Mode_3_Register); /* generate FIFO interrupts on half full */
-#else
-       win_out((0<<6)|0x0000,AI_Mode_3_Register); /* generate FIFO interrupts on non-empty */
-#endif
-       /* TIM 5/11/01 
-       0xA4A0 causes overrun errors at high speeds.  0xA420 fixes it,
-       but I haven't tested to see if it breaks something else. I don't think it would*/
-       #ifdef PCIDMA  
-       win_out(0xA420,AI_Personal_Register); 
-       #else
-       win_out(0xa4a0,AI_Personal_Register); /* ? */
-       #endif
-       win_out(0x032e,AI_Output_Control_Register);
-       win_out(0x0060,AI_Trigger_Select_Register); /* trigger source */
-
-       /* this should be done in _ai_modeX() */
-       win_out(0x29e0,AI_START_STOP_Select_Register);
-
-       /* the following registers should not be changed, because there
-        * are no backup registers in devpriv.  If you want to change
-        * any of these, add a backup register and other appropriate code:
-        *      Clock_and_FOUT_Register
-        *      AI_Mode_1_Register
-        *      AI_Mode_3_Register
-        *      AI_Personal_Register
-        *      AI_Output_Control_Register
-        *      AI_Trigger_Select_Register
-       */
-       win_out(0x3f80,Interrupt_A_Ack_Register); /* clear interrupts */
-
-       win_out(AI_Configuration_End,Joint_Reset_Register);
-
-       return 0;
-}
-
-static int ni_ai_poll(comedi_device *dev,comedi_subdevice *s)
-{
-       unsigned long flags;
-
-       comedi_spin_lock_irqsave(&dev->spinlock,flags);
-       ni_handle_fifo_dregs(dev);
-       comedi_spin_unlock_irqrestore(&dev->spinlock,flags);
-
-       comedi_event(dev,s,s->async->events);
-
-       return s->async->buf_int_count-s->async->buf_user_count;
-}
-
-static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,unsigned int *list,int dither);
-
-#define NI_TIMEOUT 1000
-
-
-static int ni_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
-{
-       int i,n;
-       int wsave;
-       unsigned int mask,sign;
-
-       wsave=win_save();
-
-       win_out(1,ADC_FIFO_Clear);
-
-       /* interrupt on errors */
-       //TIM 4/17/01 win_out(0x0020,Interrupt_A_Enable_Register);
-       ni_set_bits(dev, Interrupt_A_Enable_Register, AI_Error_Interrupt_Enable,1);
-
-
-       //ni_load_channelgain_list(dev,1,&insn->chanspec,(insn->flags&TRIG_DITHER)==TRIG_DITHER);
-       ni_load_channelgain_list(dev,1,&insn->chanspec,0);
-
-#if 0
-#define NI_TIMEOUT 1000
-#endif
-       mask=(1<<boardtype.adbits)-1;
-       sign=devpriv->ai_xorlist[0];
-       for(n=0;n<insn->n;n++){
-               win_out(1,AI_Command_1_Register);
-               for(i=0;i<NI_TIMEOUT;i++){
-                       if(!(ni_readw(AI_Status_1)&AI_FIFO_Empty_St))
-                               break;
-               }
-               if(i==NI_TIMEOUT){
-                       rt_printk("ni_E: timeout 2\n");
-                       win_restore(wsave);
-                       return -ETIME;
-               }
-               data[n]=(ni_readw(ADC_FIFO_Data_Register)&mask)^sign;
-       }
-       win_restore(wsave);
-       return insn->n;
-}
-
-
-static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,unsigned int *list,int dither)
-{
-       unsigned int chan,range,aref;
-       unsigned int i;
-       unsigned int hi,lo;
-       unsigned short sign;
-
-       if(n_chan==1){
-               if(devpriv->changain_state && devpriv->changain_spec==list[0]){
-                       // ready to go.
-                       return;
-               }
-               devpriv->changain_state=1;
-               devpriv->changain_spec=list[0];
-       }else{
-               devpriv->changain_state=0;
-       }
-
-       win_out(1,Configuration_Memory_Clear);
-
-       sign=1<<(boardtype.adbits-1);
-       for(i=0;i<n_chan;i++){
-               chan=CR_CHAN(list[i]);
-               range=CR_RANGE(list[i]);
-               aref=CR_AREF(list[i]);
-
-               /* fix the external/internal range differences */
-               range=ni_gainlkup[boardtype.gainlkup][range];
-               devpriv->ai_xorlist[i]=(range<8)?sign:0;
-
-               hi=ni_modebits1[aref]|(chan&ni_modebits2[aref]);
-               ni_writew(hi,Configuration_Memory_High);
-
-               lo=((i==n_chan-1)?0x8000:0) | ((range&0x8)<<5) | (range&0x7) | (dither<<9);
-               ni_writew(lo,Configuration_Memory_Low);
-       }
-
-       /* prime the channel/gain list */
-
-       win_out(1,AI_Command_1_Register);
-       for(i=0;i<1000;i++){
-               if(!(ni_readw(AI_Status_1)&AI_FIFO_Empty_St)){
-                       win_out(1,ADC_FIFO_Clear);
-                       return;
-               }
-               //udelay(25);
-       }
-       rt_printk("ni_E: timeout 1\n");
-}
-
-#define TIMER_BASE 50 /* 20 Mhz base */
-
-static int ni_ns_to_timer(int *nanosec,int round_mode)
-{
-       int divider,base;
-
-       base=TIMER_BASE;
-
-       switch(round_mode){
-       case TRIG_ROUND_NEAREST:
-       default:
-               divider=(*nanosec+base/2)/base;
-               break;
-       case TRIG_ROUND_DOWN:
-               divider=(*nanosec)/base;
-               break;
-       case TRIG_ROUND_UP:
-               divider=(*nanosec+base-1)/base;
-               break;
-       }
-
-       *nanosec=base*divider;
-       return divider-1;
-}
-
-static int ni_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
-{
-       int err=0;
-       int tmp;
-
-       /* step 1: make sure trigger sources are trivially valid */
-
-       tmp=cmd->start_src;
-       cmd->start_src &= TRIG_NOW|TRIG_INT;
-       if(!cmd->start_src || tmp!=cmd->start_src)err++;
-
-       tmp=cmd->scan_begin_src;
-       cmd->scan_begin_src &= TRIG_TIMER|TRIG_EXT;
-       if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
-
-       tmp=cmd->convert_src;
-       cmd->convert_src &= TRIG_TIMER|TRIG_EXT;
-       if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
-
-       tmp=cmd->scan_end_src;
-       cmd->scan_end_src &= TRIG_COUNT;
-       if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
-
-       tmp=cmd->stop_src;
-       cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
-       if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
-
-       if(err)return 1;
-
-       /* step 2: make sure trigger sources are unique and mutually compatible */
-
-       /* note that mutual compatiblity is not an issue here */
-       if(cmd->start_src!=TRIG_NOW &&
-          cmd->start_src!=TRIG_INT)err++;
-       if(cmd->scan_begin_src!=TRIG_TIMER &&
-          cmd->scan_begin_src!=TRIG_EXT)err++;
-       if(cmd->convert_src!=TRIG_TIMER &&
-          cmd->convert_src!=TRIG_EXT)err++;
-       if(cmd->stop_src!=TRIG_COUNT &&
-          cmd->stop_src!=TRIG_NONE)err++;
-
-       if(err)return 2;
-
-       /* step 3: make sure arguments are trivially compatible */
-
-       if(cmd->start_arg!=0){
-               /* true for both TRIG_NOW and TRIG_INT */
-               cmd->start_arg=0;
-               err++;
-       }
-       if(cmd->scan_begin_src==TRIG_TIMER){
-               if(cmd->scan_begin_arg<boardtype.ai_speed){
-                       cmd->scan_begin_arg=boardtype.ai_speed;
-                       err++;
-               }
-               if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){
-                       cmd->scan_begin_arg=TIMER_BASE*0xffffff;
-                       err++;
-               }
-       }else{
-               /* external trigger */
-               /* should be level/edge, hi/lo specification here */
-               /* should specify multiple external triggers */
-#if 0
-/* XXX This is disabled, since we want to use bits 30 and 31 to
- * refer to edge/level and hi/lo triggering. */
-               if(cmd->scan_begin_arg>9){
-                       cmd->scan_begin_arg=9;
-                       err++;
-               }
-#endif
-       }
-       if(cmd->convert_src==TRIG_TIMER){
-               if(cmd->convert_arg<boardtype.ai_speed){
-                       cmd->convert_arg=boardtype.ai_speed;
-                       err++;
-               }
-               if(cmd->convert_arg>TIMER_BASE*0xffff){
-                       cmd->convert_arg=TIMER_BASE*0xffff;
-                       err++;
-               }
-       }else{
-               /* external trigger */
-               /* see above */
-#if 0
-/* XXX This is disabled, since we want to use bits 30 and 31 to
- * refer to edge/level and hi/lo triggering. */
-               if(cmd->convert_arg>9){
-                       cmd->convert_arg=9;
-                       err++;
-               }
-#endif
-       }
-
-       if(cmd->scan_end_arg!=cmd->chanlist_len){
-               cmd->scan_end_arg=cmd->chanlist_len;
-               err++;
-       }
-       if(cmd->stop_src==TRIG_COUNT){
-               if(cmd->stop_arg>0x00ffffff){
-                       cmd->stop_arg=0x00ffffff;
-                       err++;
-               }
-       }else{
-               /* TRIG_NONE */
-               if(cmd->stop_arg!=0){
-                       cmd->stop_arg=0;
-                       err++;
-               }
-       }
-
-       if(err)return 3;
-
-       /* step 4: fix up any arguments */
-
-       if(cmd->scan_begin_src==TRIG_TIMER){
-               tmp=cmd->scan_begin_arg;
-               ni_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);
-               if(tmp!=cmd->scan_begin_arg)err++;
-       }
-       if(cmd->convert_src==TRIG_TIMER){
-               tmp=cmd->convert_arg;
-               ni_ns_to_timer(&cmd->convert_arg,cmd->flags&TRIG_ROUND_MASK);
-               if(tmp!=cmd->convert_arg)err++;
-               if(cmd->scan_begin_src==TRIG_TIMER &&
-                 cmd->scan_begin_arg<cmd->convert_arg*cmd->scan_end_arg){
-                       cmd->scan_begin_arg=cmd->convert_arg*cmd->scan_end_arg;
-                       err++;
-               }
-       }
-
-       if(err)return 4;
-
-       return 0;
-}
-
-static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s)
-{
-       int wsave;
-       comedi_cmd *cmd=&s->async->cmd;
-       int timer;
-       int mode1=0; /* mode1 is needed for both stop and convert */
-       int mode2=0;
-
-       MDPRINTK("ni_ai_cmd\n");
-       wsave = win_save();
-
-       win_out(1,ADC_FIFO_Clear);
-
-       ni_load_channelgain_list(dev,cmd->chanlist_len,cmd->chanlist,
-               (cmd->flags&TRIG_DITHER)==TRIG_DITHER);
-
-       /* start configuration */
-       win_out(AI_Configuration_Start,Joint_Reset_Register);
-
-#ifndef TRY_BLOCK
-       #ifdef PCIDMA
-       ni_ai_setup_MITE_dma(dev,cmd,mode1);    
-       #else
-       switch(cmd->stop_src){
-       case TRIG_COUNT:
-               /* stage number of scans */
-               win_out((cmd->stop_arg-1)>>16,AI_SC_Load_A_Registers);
-               win_out((cmd->stop_arg-1)&0xffff,AI_SC_Load_A_Registers+1);
-
-               mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
-               win_out(mode1,AI_Mode_1_Register);
-
-               /* load SC (Scan Count) */
-               win_out(AI_SC_Load,AI_Command_1_Register);
-
-               devpriv->ai_continuous = 0;
-
-               break;
-       case TRIG_NONE:
-               /* stage number of scans */
-               win_out(0,AI_SC_Load_A_Registers);
-               win_out(0,AI_SC_Load_A_Registers+1);
-
-               mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
-               win_out(mode1,AI_Mode_1_Register);
-
-               /* load SC (Scan Count) */
-               win_out(AI_SC_Load,AI_Command_1_Register);
-
-               devpriv->ai_continuous = 1;
-
-               break;
-       }
-       #endif
-#else
-       devpriv->blocksize = 0x4000;
-       switch(cmd->stop_src){
-       case TRIG_COUNT:
-               devpriv->ai_continuous = 0;
-               devpriv->n_left = cmd->stop_arg;
-               break;
-       case TRIG_NONE:
-               devpriv->ai_continuous = 1;
-               devpriv->n_left = 0;
-               break;
-       }
-
-       mode1 = ni_ai_setup_block(dev,1,mode1);
-#endif
-
-
-       switch(cmd->scan_begin_src){
-       case TRIG_TIMER:
-               /*
-               AI_SI_Special_Trigger_Delay=0
-               AI_Pre_Trigger=0
-               AI_START_STOP_Select_Register:
-                   AI_START_Polarity=0 (?)     rising edge
-                   AI_START_Edge=1             edge triggered
-                   AI_START_Sync=1 (?)
-                   AI_START_Select=0           SI_TC
-                   AI_STOP_Polarity=0          rising edge
-                   AI_STOP_Edge=0              level
-                   AI_STOP_Sync=1
-                   AI_STOP_Select=19           external pin (configuration mem)
-                */
-               win_out(AI_START_Edge|AI_START_Sync|
-                       AI_STOP_Select(19)|AI_STOP_Sync,
-                       AI_START_STOP_Select_Register);
-
-               timer=ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);
-               win_out((timer>>16),AI_SI_Load_A_Registers);
-               win_out((timer&0xffff),AI_SI_Load_A_Registers+1);
-
-               /* AI_SI_Initial_Load_Source=A */
-               mode2 |= AI_SI_Initial_Load_Source&0;
-//mode2 |= AI_SC_Reload_Mode;
-               win_out(mode2,AI_Mode_2_Register);
-
-               /* load SI */
-               win_out(AI_SI_Load,AI_Command_1_Register);
-
-               /* stage freq. counter into SI B */
-               win_out((timer>>16),AI_SI_Load_B_Registers);
-               win_out((timer&0xffff),AI_SI_Load_B_Registers+1);
-
-               break;
-       case TRIG_EXT:
-           {
-               unsigned int reg = 0;
-
-/* XXX duh, these should be moved, but I need to think about it
- * a bit first.  --ds */
-#define COMEDI_TRIG_LEVEL      0
-#define COMEDI_TRIG_EDGE       (1<<31)
-#define COMEDI_TRIG_FALLING    0
-#define COMEDI_TRIG_RISING     (1<<30)
-
-               if(cmd->scan_begin_arg&COMEDI_TRIG_EDGE)
-                       reg |= AI_START_Edge;
-               /* AI_START_Polarity==1 is falling edge */
-               if(!(cmd->scan_begin_arg&COMEDI_TRIG_RISING))
-                       reg |= AI_START_Polarity;
-               reg |= AI_START_Sync;
-               reg |= AI_START_Select(1+(cmd->scan_begin_arg&0xf));
-               reg |= AI_STOP_Select(19)|AI_STOP_Sync;
-
-               win_out(reg,AI_START_STOP_Select_Register);
-               break;
-           }
-       }
-
-       switch(cmd->convert_src){
-       case TRIG_TIMER:
-               timer=ni_ns_to_timer(&cmd->convert_arg,TRIG_ROUND_NEAREST);
-               win_out(1,AI_SI2_Load_A_Register); /* 0,0 does not work. */
-               win_out(timer,AI_SI2_Load_B_Register);
-
-               /* AI_SI2_Reload_Mode = alternate */
-               /* AI_SI2_Initial_Load_Source = A */
-               win_out((AI_SI2_Initial_Load_Source&0)|
-                       (AI_SI2_Reload_Mode),
-                       AI_Mode_2_Register);
-
-               /* AI_SI2_Load */
-               win_out(AI_SI2_Load,AI_Command_1_Register);
-
-               //mode2 |= AI_SI_Reload_Mode(0);
-       /* XXX the AI_SI stuff should go to the scan_begin_src area */
-               mode2 |= AI_SI_Reload_Mode(1);
-               //mode2 |= 0&AI_SI_Initial_Load_Source;
-               mode2 |= AI_SI_Initial_Load_Source;
-               mode2 |= AI_SI2_Reload_Mode; // alternate
-               mode2 |= AI_SI2_Initial_Load_Source; // B
-
-               win_out(mode2,AI_Mode_2_Register);
-
-               break;
-       case TRIG_EXT:
-               mode1 |= AI_CONVERT_Source_Select(1+cmd->convert_arg) |
-                       AI_CONVERT_Source_Polarity;
-               win_out(mode1,AI_Mode_1_Register);
-
-               win_out(mode2 | AI_SI2_Reload_Mode,AI_Mode_2_Register);
-
-               mode2 |= AI_SI_Reload_Mode(0);
-               mode2 |= 0&AI_SI_Initial_Load_Source;
-               mode2 |= AI_SI2_Reload_Mode; // alternate
-               mode2 |= AI_SI2_Initial_Load_Source; // B
-
-               win_out(mode2,AI_Mode_2_Register);
-
-               break;
-       }
-
-       if(dev->irq){
-               int bits;
-
-               /* interrupt on FIFO, errors, SC_TC */
-               bits= AI_Error_Interrupt_Enable|
-                       AI_SC_TC_Interrupt_Enable;
-
-#ifndef PCIDMA
-               bits|=AI_FIFO_Interrupt_Enable;
-#endif
-
-               if(s->async->cb_mask&COMEDI_CB_EOS){
-                       /* wake on end-of-scan */
-                       devpriv->aimode=AIMODE_SCAN;
-               }else{
-                       devpriv->aimode=AIMODE_HALF_FULL;
-               }
-
-               switch(devpriv->aimode){
-               case AIMODE_HALF_FULL:
-                       /*generate FIFO interrupts on half-full */
-                       win_out(AI_FIFO_Mode_HF|0x0000,AI_Mode_3_Register);
-                       break;
-               case AIMODE_SAMPLE:
-                       /*generate FIFO interrupts on non-empty */
-                       win_out(AI_FIFO_Mode_NE|0x0000,AI_Mode_3_Register);
-                       break;
-               case AIMODE_SCAN:
-                       /*generate FIFO interrupts on half-full */
-                       win_out(AI_FIFO_Mode_HF|0x0000,AI_Mode_3_Register);
-                       bits|=AI_STOP_Interrupt_Enable;
-                       break;
-               default:
-                       break;
-               }
-
-               win_out(0x3f80,Interrupt_A_Ack_Register); /* clear interrupts */
-
-               //TIM 4/17/01 win_out(bits,Interrupt_A_Enable_Register) ;
-               ni_set_bits(dev, Interrupt_A_Enable_Register, bits, 1);
-               
-               MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",bits);
-       }else{
-               /* interrupt on nothing */
-               win_out(0x0000,Interrupt_A_Enable_Register) ;
-
-               /* XXX start polling if necessary */
-               MDPRINTK("interrupting on nothing\n");
-       }
-
-       /* end configuration */
-       win_out(AI_Configuration_End,Joint_Reset_Register);
-
-       switch(cmd->scan_begin_src){
-       case TRIG_TIMER:
-               /* AI_SI2_Arm, AI_SI_Arm, AI_DIV_Arm, AI_SC_Arm */
-               win_out(0x1540,AI_Command_1_Register);
-               break;
-       case TRIG_EXT:
-               /* AI_SI2_Arm, AI_DIV_Arm, AI_SC_Arm */
-               win_out(0x1540,AI_Command_1_Register);
-               break;
-       }
-
-       if(cmd->start_src==TRIG_NOW){
-               /* TRIG_NOW */
-               /* AI_START1_Pulse */
-               win_out(AI_START1_Pulse,AI_Command_2_Register);
-               s->async->inttrig=NULL;
-       }else{
-               /* TRIG_INT */
-               s->async->inttrig=ni_ai_inttrig;
-       }
-
-       win_restore(wsave);
-
-       //mite_dump_regs(devpriv->mite);
-       MDPRINTK("exit ni_ai_cmd\n");
-       
-       return 0;
-}
-
-static int ni_ai_inttrig(comedi_device *dev,comedi_subdevice *s,
-       unsigned int trignum)
-{
-       int wsave;
-
-       if(trignum!=0)return -EINVAL;
-
-       wsave = win_save();
-
-       win_out(AI_START1_Pulse,AI_Command_2_Register);
-       s->async->inttrig=NULL;
-
-       win_restore(wsave);
-
-       return 1;
-}
-
-static void ni_ao_fifo_load(comedi_device *dev,comedi_subdevice *s,
-               sampl_t *data,int n)
-{
-       int i;
-
-       for(i=0;i<n;i++){
-               ni_writew(data[i],DAC_FIFO_Data);
-       }
-}
-
-
-/*
- *  There's a small problem if the FIFO gets really low and we
- *  don't have the data to fill it.  Basically, if after we fill
- *  the FIFO with all the data available, the FIFO is _still_
- *  less than half full, we never clear the interrupt.  If the
- *  IRQ is in edge mode, we never get another interrupt, because
- *  this one wasn't cleared.  If in level mode, we get flooded
- *  with interrupts that we can't fulfill, because nothing ever
- *  gets put into the buffer.
- *
- *  This kind of situation is recoverable, but it is easier to
- *  just pretend we had a FIFO underrun, since there is a good
- *  chance it will happen anyway.  This is _not_ the case for
- *  RT code, as RT code might purposely be running close to the
- *  metal.  Needs to be fixed eventually.
- */
-static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s)
-{
-       int n,m;
-
-       n=(s->async->buf_int_count-s->async->buf_user_count)/sizeof(sampl_t);
-       if(n==0)return 0;
-       if(n>boardtype.ao_fifo_depth/2)
-               n=boardtype.ao_fifo_depth/2;
-
-       if(s->async->buf_int_ptr+n*sizeof(sampl_t)>s->async->data_len){
-               m=(s->async->data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
-               ni_ao_fifo_load(dev,s,s->async->data+s->async->buf_int_ptr,m);
-               s->async->buf_int_count+=m*sizeof(sampl_t);
-               s->async->buf_int_ptr=0;
-               n-=m;
-       }
-       ni_ao_fifo_load(dev,s,s->async->data+s->async->buf_int_ptr,n);
-       s->async->buf_int_count+=n*sizeof(sampl_t);
-       s->async->buf_int_ptr+=n*sizeof(sampl_t);
-
-       comedi_bufcheck(dev,s);
-
-       return 1;
-}
-
-static int ni_ao_prep_fifo(comedi_device *dev,comedi_subdevice *s)
-{
-       int n;
-
-       /* reset fifo */
-       win_out(0,DAC_FIFO_Clear);
-
-       /* load some data */
-       n=(s->async->buf_int_count-s->async->buf_user_count)/sizeof(sampl_t);
-       if(n==0)return 0;
-       if(n>boardtype.ao_fifo_depth)
-               n=boardtype.ao_fifo_depth;
-
-       ni_ao_fifo_load(dev,s,s->async->data+s->async->buf_int_ptr,n);
-       s->async->buf_int_count+=n*sizeof(sampl_t);
-       s->async->buf_int_ptr+=n*sizeof(sampl_t);
-
-       return n;
-}
-
-
-static int ni_ao_insn_read(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data)
-{
-       data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
-
-       return 1;
-}
-
-static int ni_ao_insn_write(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data)
-{
-       unsigned int conf;
-       unsigned int chan;
-       unsigned int range;
-       unsigned int dat = data[0];
-
-       chan=CR_CHAN(insn->chanspec);
-
-       conf=chan<<8;
-
-       /* XXX check range with current range in flaglist[chan] */
-       /* should update calibration if range changes (ick) */
-
-       range = CR_RANGE(insn->chanspec);
-       if(boardtype.ao_unipolar){
-               conf |= (range&1)^1;
-       }
-       conf |= (range&2)<<1;
-
-#if 0
-       /* XXX oops.  forgot flags in insn! */
-       /* not all boards can deglitch, but this shouldn't hurt */
-       if(insn->flags & TRIG_DEGLITCH)
-               conf |= 2;
-#endif
-
-       /* analog reference */
-       /* AREF_OTHER connects AO ground to AI ground, i think */
-       conf |= (CR_AREF(insn->chanspec)==AREF_OTHER)? 8 : 0;
-
-       ni_writew(conf,AO_Configuration);
-
-       devpriv->ao[chan] = dat;
-
-       if(((range&1)==0) || !boardtype.ao_unipolar)
-               dat^=(1<<(boardtype.aobits-1));
-
-       ni_writew(dat,(chan)? DAC1_Direct_Data : DAC0_Direct_Data);
-
-       return 1;
-}
-
-static int ni_ao_cmd(comedi_device *dev,comedi_subdevice *s)
-{
-       comedi_cmd *cmd = &s->async->cmd;
-       unsigned int conf;
-       unsigned int chan;
-       unsigned int range;
-       int trigvar;
-       int i;
-       
-       trigvar = ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);
-
-       win_out(AO_Disarm,AO_Command_1_Register);
-
-       for(i=0;i<cmd->chanlist_len;i++){
-               chan=CR_CHAN(cmd->chanlist[i]);
-
-               conf=chan<<8;
-       
-               /* XXX check range with current range in flaglist[chan] */
-               /* should update calibration if range changes (ick) */
-
-               range = CR_RANGE(cmd->chanlist[i]);
-               conf |= (range&1);
-               conf |= (range&2)<<1;
-       
-               /* not all boards can deglitch, but this shouldn't hurt */
-               if(cmd->flags & TRIG_DEGLITCH) /* XXX ? */
-                       conf |= 2;
-
-               /* analog reference */
-               /* AREF_OTHER connects AO ground to AI ground, i think */
-               conf |= (CR_AREF(cmd->chanlist[i])==AREF_OTHER)? 8 : 0;
-
-               ni_writew(conf,AO_Configuration);
-       }
-
-       /* user is supposed to write() to buffer before triggering */
-       if(ni_ao_prep_fifo(dev,s)==0)
-               return -EIO;
-
-       win_out(AO_Configuration_Start,Joint_Reset_Register);
-
-       devpriv->ao_mode1|=AO_Trigger_Once;
-       win_out(devpriv->ao_mode1,AO_Mode_1_Register);
-       devpriv->ao_trigger_select&=~(AO_START1_Polarity|AO_START1_Select(-1));
-       devpriv->ao_trigger_select|=AO_START1_Edge|AO_START1_Sync;
-       win_out(devpriv->ao_trigger_select,AO_Trigger_Select_Register);
-       devpriv->ao_mode3&=~AO_Trigger_Length;
-       win_out(devpriv->ao_mode3,AO_Mode_3_Register);
-
-       if(cmd->stop_src==TRIG_NOW){
-               devpriv->ao_mode1|=AO_Continuous;
-       }else{
-               devpriv->ao_mode1&=~AO_Continuous;
-       }
-       win_out(devpriv->ao_mode1,AO_Mode_1_Register);
-       devpriv->ao_mode2&=~AO_BC_Initial_Load_Source;
-       win_out(devpriv->ao_mode2,AO_Mode_2_Register);
-       if(cmd->stop_src==TRIG_NOW){
-               win_out(0xff,AO_BC_Load_A_Register_High);
-               win_out(0xffff,AO_BC_Load_A_Register_Low);
-       }else{
-               win_out(0,AO_BC_Load_A_Register_High);
-               win_out(0,AO_BC_Load_A_Register_Low);
-       }
-       win_out(AO_BC_Load,AO_Command_1_Register);
-       devpriv->ao_mode2&=~AO_UC_Initial_Load_Source;
-       win_out(devpriv->ao_mode2,AO_Mode_2_Register);
-       if(cmd->stop_src==TRIG_NOW){
-               win_out(0xff,AO_UC_Load_A_Register_High);
-               win_out(0xffff,AO_UC_Load_A_Register_Low);
-               win_out(AO_UC_Load,AO_Command_1_Register);
-               win_out(0xff,AO_UC_Load_A_Register_High);
-               win_out(0xffff,AO_UC_Load_A_Register_Low);
-       }else{
-               win_out(0,AO_UC_Load_A_Register_High);
-               win_out(0,AO_UC_Load_A_Register_Low);
-               win_out(AO_UC_Load,AO_Command_1_Register);
-               win_out((cmd->stop_arg-1)>>16,AO_UC_Load_A_Register_High);
-               win_out((cmd->stop_arg-1)&0xffff,AO_UC_Load_A_Register_Low);
-       }
-
-       devpriv->ao_cmd2&=~AO_BC_Gate_Enable;
-       ni_writew(devpriv->ao_cmd2,AO_Command_2);
-       devpriv->ao_mode1&=~(AO_UI_Source_Select(0x1f)|AO_UI_Source_Polarity);
-       win_out(devpriv->ao_mode1,AO_Mode_1_Register);
-       devpriv->ao_mode2&=~(AO_UI_Reload_Mode(3)|AO_UI_Initial_Load_Source);
-       win_out(devpriv->ao_mode2,AO_Mode_2_Register);
-       win_out(0,AO_UI_Load_A_Register_High);
-       win_out(1,AO_UI_Load_A_Register_Low);
-       win_out(AO_UI_Load,AO_Command_1_Register);
-       win_out((trigvar>>16),AO_UI_Load_A_Register_High);
-       win_out((trigvar&0xffff),AO_UI_Load_A_Register_Low);
-
-       if(cmd->scan_end_arg>1){
-               devpriv->ao_mode1|=AO_Multiple_Channels;
-               win_out(AO_Number_Of_Channels(cmd->scan_end_arg-1)|
-                       AO_UPDATE_Output_Select(1),
-                       AO_Output_Control_Register);
-       }else{
-               devpriv->ao_mode1&=~AO_Multiple_Channels;
-               win_out(AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]))|
-                       AO_UPDATE_Output_Select(1),
-                       AO_Output_Control_Register);
-       }
-       win_out(devpriv->ao_mode1,AO_Mode_1_Register);
-
-       win_out(AO_DAC0_Update_Mode|AO_DAC1_Update_Mode,AO_Command_1_Register);
-
-       devpriv->ao_mode3|=AO_Stop_On_Overrun_Error;
-       win_out(devpriv->ao_mode3,AO_Mode_3_Register);
-
-devpriv->ao_mode2|=AO_FIFO_Mode(1);
-       devpriv->ao_mode2&=~AO_FIFO_Retransmit_Enable;
-       win_out(devpriv->ao_mode2,AO_Mode_2_Register);
-
-       win_out(AO_Configuration_End,Joint_Reset_Register);
-
-       win_out(devpriv->ao_mode3|AO_Not_An_UPDATE,AO_Mode_3_Register);
-       win_out(devpriv->ao_mode3,AO_Mode_3_Register);
-
-       /* wait for DACs to be loaded */
-       udelay(100);
-
-       win_out(devpriv->ao_cmd1|AO_UI_Arm|AO_UC_Arm|AO_BC_Arm|AO_DAC1_Update_Mode|AO_DAC0_Update_Mode,
-               AO_Command_1_Register);
-
-       //TIM 4/17/01 win_out(AO_FIFO_Interrupt_Enable|AO_Error_Interrupt_Enable,Interrupt_B_Enable_Register);
-       ni_set_bits(dev, Interrupt_B_Enable_Register,
-               AO_FIFO_Interrupt_Enable|AO_Error_Interrupt_Enable, 1);
-
-       ni_writew(devpriv->ao_cmd2|AO_START1_Pulse,AO_Command_2);
-       
-       return 0;
-}
-
-static int ni_ao_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
-{
-       int err=0;
-       int tmp;
-
-       /* step 1: make sure trigger sources are trivially valid */
-
-       tmp=cmd->start_src;
-       cmd->start_src &= TRIG_NOW;
-       if(!cmd->start_src || tmp!=cmd->start_src)err++;
-
-       tmp=cmd->scan_begin_src;
-       cmd->scan_begin_src &= TRIG_TIMER;
-       if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
-
-       tmp=cmd->convert_src;
-       cmd->convert_src &= TRIG_NOW;
-       if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
-
-       tmp=cmd->scan_end_src;
-       cmd->scan_end_src &= TRIG_COUNT;
-       if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
-
-       tmp=cmd->stop_src;
-       cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
-       if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
-
-       if(err)return 1;
-
-       /* step 2: make sure trigger sources are unique and mutually compatible */
-
-       if(cmd->stop_src!=TRIG_COUNT &&
-          cmd->stop_src!=TRIG_NONE)err++;
-
-       if(err)return 2;
-
-       /* step 3: make sure arguments are trivially compatible */
-
-       if(cmd->start_arg!=0){
-               cmd->start_arg=0;
-               err++;
-       }
-#if 0
-       /* XXX need ao_speed */
-       if(cmd->scan_begin_arg<boardtype.ao_speed){
-               cmd->scan_begin_arg=boardtype.ao_speed;
-               err++;
-       }
-#endif
-       if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){ /* XXX check */
-               cmd->scan_begin_arg=TIMER_BASE*0xffffff;
-               err++;
-       }
-       if(cmd->convert_arg!=0){
-               cmd->convert_arg=0;
-               err++;
-       }
-       if(cmd->scan_end_arg!=cmd->chanlist_len){
-               cmd->scan_end_arg=cmd->chanlist_len;
-               err++;
-       }
-       if(cmd->stop_src==TRIG_COUNT){ /* XXX check */
-               if(cmd->stop_arg>0x00ffffff){
-                       cmd->stop_arg=0x00ffffff;
-                       err++;
-               }
-       }else{
-               /* TRIG_NONE */
-               if(cmd->stop_arg!=0){
-                       cmd->stop_arg=0;
-                       err++;
-               }
-       }
-
-       if(err)return 3;
-
-       /* step 4: fix up any arguments */
-
-       tmp = cmd->scan_begin_arg;
-       ni_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);
-       if(tmp!=cmd->scan_begin_arg)err++;
-       
-       if(err)return 4;
-
-       return 0;
-}
-
-
-static int ni_dio_insn_config(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data)
-{
-#ifdef DEBUG_DIO
-       printk("ni_dio_insn_config() chan=%d io=%d\n",
-               CR_CHAN(insn->chanspec),data[0]);
-#endif
-       if(insn->n!=1)return -EINVAL;
-       switch(data[0]){
-       case COMEDI_OUTPUT:
-               s->io_bits |= 1<<CR_CHAN(insn->chanspec);
-               break;
-       case COMEDI_INPUT:
-               s->io_bits &= ~(1<<CR_CHAN(insn->chanspec));
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
-       devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
-       win_out(devpriv->dio_control,DIO_Control_Register);
-
-       return 1;
-}
-
-static int ni_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data)
-{
-#ifdef DEBUG_DIO
-       printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n",data[0],data[1]);
-#endif
-       if(insn->n!=2)return -EINVAL;
-       if(data[0]){
-               s->state &= ~data[0];
-               s->state |= (data[0]&data[1]);
-               devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
-               devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
-               win_out(devpriv->dio_output,DIO_Output_Register);
-       }
-       data[1] = ni_readw(DIO_Parallel_Input);
-
-       return 2;
-}
-
-static void mio_common_detach(comedi_device *dev)
-{
-       if(dev->subdevices && boardtype.has_8255)
-               subdev_8255_cleanup(dev,dev->subdevices+3);
-}
-
-static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
-{
-       comedi_subdevice *s;
-       
-       dev->n_subdevices=7;
-       
-       if(alloc_subdevices(dev)<0)
-               return -ENOMEM;
-       
-       /* analog input subdevice */
-
-       s=dev->subdevices+0;
-       dev->read_subdev=s;
-       s->type=COMEDI_SUBD_AI;
-       s->subdev_flags=SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON|SDF_DIFF|SDF_OTHER;
-       s->subdev_flags|=SDF_DITHER;
-       s->n_chan=boardtype.n_adchan;
-       s->len_chanlist=512;
-       s->maxdata=(1<<boardtype.adbits)-1;
-       s->range_table=ni_range_lkup[boardtype.gainlkup];
-       s->insn_read=ni_ai_insn_read;
-       s->do_cmdtest=ni_ai_cmdtest;
-       s->do_cmd=ni_ai_cmd;
-       s->cancel=ni_ai_reset;
-       s->poll=ni_ai_poll;
-
-       /* analog output subdevice */
-
-       s=dev->subdevices+1;
-       if(boardtype.n_aochan){
-               dev->write_subdev=s;
-               s->type=COMEDI_SUBD_AO;
-               s->subdev_flags=SDF_WRITEABLE|SDF_RT|SDF_DEGLITCH|SDF_GROUND|SDF_OTHER;
-               s->n_chan=boardtype.n_aochan;
-               s->maxdata=(1<<boardtype.aobits)-1;
-               if(boardtype.ao_unipolar){
-                       s->range_table=&range_ni_E_ao_ext;      /* XXX wrong for some boards */
-               }else{
-                       s->range_table=&range_bipolar10;
-               }
-               s->insn_read=ni_ao_insn_read;
-               s->insn_write=ni_ao_insn_write;
-               s->do_cmd=ni_ao_cmd;
-               s->do_cmdtest=ni_ao_cmdtest;
-               s->len_chanlist = 2;
-       }else{
-               s->type=COMEDI_SUBD_UNUSED;
-       }
-       
-       /* digital i/o subdevice */
-       
-       s=dev->subdevices+2;
-       s->type=COMEDI_SUBD_DIO;
-       s->subdev_flags=SDF_WRITEABLE|SDF_READABLE|SDF_RT;
-       s->n_chan=8;
-       s->maxdata=1;
-       s->range_table=&range_digital;
-       s->io_bits=0;           /* all bits input */
-       s->insn_bits=ni_dio_insn_bits;
-       s->insn_config=ni_dio_insn_config;
-
-       /* dio setup */
-       devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
-       win_out(devpriv->dio_control,DIO_Control_Register);
-       
-       /* 8255 device */
-       s=dev->subdevices+3;
-       if(boardtype.has_8255){
-               subdev_8255_init(dev,s,ni_8255_callback,dev);
-       }else{
-               s->type=COMEDI_SUBD_UNUSED;
-       }
-       /* XXX */
-       
-       /* general purpose counter/timer device */
-       s=dev->subdevices+4;
-       s->type=COMEDI_SUBD_COUNTER;
-       s->subdev_flags=SDF_READABLE|SDF_WRITEABLE;
-       s->insn_read=ni_gpct_insn_read;
-       s->insn_config=ni_gpct_insn_config;
-       s->n_chan=1; /* XXX */
-       s->maxdata=1;
-       
-       s=dev->subdevices+4;
-       s->type=COMEDI_SUBD_COUNTER;
-       s->subdev_flags=SDF_READABLE|SDF_WRITEABLE;
-       s->insn_read=  ni_gpct_insn_read;
-       s->insn_write= ni_gpct_insn_write;
-       s->insn_config=ni_gpct_insn_config;
-       s->n_chan=2;
-       s->maxdata=1;
-       devpriv->an_trig_etc_reg = 0;
-       GPCT_Reset(dev,0);
-       GPCT_Reset(dev,1);
-       
-       /* calibration subdevice -- ai and ao */
-       s=dev->subdevices+5;
-       s->type=COMEDI_SUBD_CALIB;
-       s->subdev_flags=SDF_WRITEABLE|SDF_INTERNAL;
-       caldac_setup(dev,s);
-       s->insn_read=ni_calib_insn_read;
-       s->insn_write=ni_calib_insn_write;
-       
-       /* EEPROM */
-       s=dev->subdevices+6;
-       s->type=COMEDI_SUBD_MEMORY;
-       s->subdev_flags=SDF_READABLE|SDF_INTERNAL;
-       s->n_chan=512;
-       s->maxdata=0xff;
-       s->insn_read=ni_eeprom_insn_read;
-       
-       /* ai configuration */
-       ni_ai_reset(dev,dev->subdevices+0);
-       win_out(0x1ba0,Clock_and_FOUT_Register);
-
-
-       /* analog output configuration */
-       
-       devpriv->ao0p=0x0000;
-       ni_writew(devpriv->ao0p,AO_Configuration);
-       devpriv->ao1p=0x0100;
-       ni_writew(devpriv->ao1p,AO_Configuration);
-       win_out(AO_Configuration_Start,Joint_Reset_Register);
-       win_out(AO_Disarm,AO_Command_1_Register);
-       win_out(0,Interrupt_B_Enable_Register);
-       win_out(0x0010,AO_Personal_Register);
-       ni_writew(0x3f98,Interrupt_B_Ack);
-       win_out(0x1430,AO_Personal_Register);
-       win_out(0,AO_Output_Control_Register);
-       win_out(0,AO_Start_Select_Register);
-       devpriv->ao_cmd1=0;
-       win_out(devpriv->ao_cmd1,AO_Command_1_Register);
-       devpriv->ao_cmd2=0;
-       devpriv->ao_mode1=0;
-       devpriv->ao_mode2=0;
-       devpriv->ao_mode3=0;
-       devpriv->ao_trigger_select=0;
-
-        if(dev->irq){
-                win_out((IRQ_POLARITY<<0) |  /* polarity : active high */
-                        (0<<1) |  /* no interrupt on 3 pins */
-                        (1<<11) |  /* enable int A */
-                        (1<<15) |  /* enable int B */
-                        (interrupt_pin(dev->irq)<<8) |  /* interrupt output pin A */
-                        (interrupt_pin(dev->irq)<<12) ,  /* interrupt output pin B */
-                        Interrupt_Control_Register
-                );
-        }
-
-       pfi_setup(dev);
-
-       printk("\n");
-
-       return 0;
-}
-
-
-
-
-/*
-       presents the EEPROM as a subdevice
-*/
-
-static int ni_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data)
-{
-       data[0]=ni_read_eeprom(dev,CR_CHAN(insn->chanspec));
-
-       return 1;
-}
-
-/*
-       reads bytes out of eeprom
-*/
-
-static int ni_read_eeprom(comedi_device *dev,int addr)
-{
-       int bit;
-       int bitstring;
-
-       bitstring=0x0300|((addr&0x100)<<3)|(addr&0xff);
-       ni_writeb_p(0x04,Serial_Command);
-       for(bit=0x8000;bit;bit>>=1){
-               ni_writeb_p(0x04|((bit&bitstring)?0x02:0),Serial_Command);
-               ni_writeb_p(0x05|((bit&bitstring)?0x02:0),Serial_Command);
-       }
-       bitstring=0;
-       for(bit=0x80;bit;bit>>=1){
-               ni_writeb_p(0x04,Serial_Command);
-               ni_writeb_p(0x05,Serial_Command);
-               bitstring|=((ni_readb_p(XXX_Status)&0x01)?bit:0);
-       }
-       ni_writeb_p(0x00,Serial_Command);
-       
-       return bitstring;
-}
-
-static void ni_write_caldac(comedi_device *dev,int addr,int val);
-/*
-       calibration subdevice
-*/
-static int ni_calib_insn_write(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data)
-{
-       ni_write_caldac(dev,CR_CHAN(insn->chanspec),data[0]);
-       devpriv->caldacs[CR_CHAN(insn->chanspec)] = data[0];
-
-       return 1;
-}
-
-static int ni_calib_insn_read(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data)
-{
-       data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
-
-       return 1;
-}
-
-static int pack_mb88341(int addr,int val,int *bitstring);
-static int pack_dac8800(int addr,int val,int *bitstring);
-static int pack_dac8043(int addr,int val,int *bitstring);
-#ifdef PCIMIO
-static int pack_ad8522(int addr,int val,int *bitstring);
-#endif
-
-struct caldac_struct{
-       int n_chans;
-       int n_bits;
-       int (*packbits)(int,int,int *);
-};
-
-static struct caldac_struct caldac_mb88341={ 12, 8, pack_mb88341 };
-static struct caldac_struct caldac_dac8800={ 8, 8, pack_dac8800 };
-static struct caldac_struct caldac_dac8043={ 1, 12, pack_dac8043 };
-#ifdef PCIMIO
-static struct caldac_struct caldac_ad8522={ 2, 12, pack_ad8522 };
-#endif
-
-
-static void caldac_setup(comedi_device *dev,comedi_subdevice *s)
-{
-       int i,j;
-       int n_dacs;
-       int n_chans=0;
-       int n_bits;
-       int diffbits=0;
-       
-       if(!boardtype.caldac[0])return;
-       n_bits=boardtype.caldac[0]->n_bits;
-       for(i=0;i<3;i++){
-               if(!boardtype.caldac[i])break;
-               if(boardtype.caldac[i]->n_bits!=n_bits)diffbits=1;
-               n_chans+=boardtype.caldac[i]->n_chans;
-       }
-       n_dacs=i;
-       s->n_chan=n_chans;
-
-       if(diffbits){
-               int chan;
-
-               s->maxdata_list=kmalloc(sizeof(int)*n_chans,GFP_KERNEL);
-               chan=0;
-               for(i=0;i<n_dacs;i++){
-                       for(j=0;j<boardtype.caldac[i]->n_chans;j++){
-                               s->maxdata_list[chan]=
-                                       (1<<boardtype.caldac[i]->n_bits)-1;
-                               chan++;
-                       }
-               }
-       }else{
-               s->maxdata=(1<<boardtype.caldac[0]->n_bits)-1;
-       }
-}
-
-static void ni_write_caldac(comedi_device *dev,int addr,int val)
-{
-       int loadbit=0,bits=0,bit,bitstring=0;
-       int i;
-       
-       for(i=0;i<3;i++){
-               if(!boardtype.caldac[i])return;
-               if(addr<boardtype.caldac[i]->n_chans){
-                       bits=boardtype.caldac[i]->packbits(addr,val,&bitstring);
-                       loadbit=SerDacLd(i);
-                       break;
-               }
-               addr-=boardtype.caldac[i]->n_chans;
-       }
-
-       for(bit=1<<(bits-1);bit;bit>>=1){
-               ni_writeb(((bit&bitstring)?0x02:0),Serial_Command);
-               ni_writeb(1|((bit&bitstring)?0x02:0),Serial_Command);
-       }
-       ni_writeb(loadbit,Serial_Command);
-       ni_writeb(0,Serial_Command);
-}
-
-
-
-static int pack_mb88341(int addr,int val,int *bitstring)
-{
-       /*
-          Fujitsu MB 88341
-          Note that address bits are reversed.  Thanks to
-          Ingo Keen for noticing this.
-
-          Note also that the 88341 expects address values from
-          1-12, whereas we use channel numbers 0-11.  The NI
-          docs use 1-12, also, so be careful here.
-       */
-       addr++;
-       *bitstring=((addr&0x1)<<11) |
-                 ((addr&0x2)<<9)  |
-                 ((addr&0x4)<<7)  |
-                 ((addr&0x8)<<5)  |
-                 (val&0xff);
-       return 12;
-}
-
-static int pack_dac8800(int addr,int val,int *bitstring)
-{
-       *bitstring=((addr&0x7)<<8)|(val&0xff);
-       return 11;
-}
-
-static int pack_dac8043(int addr,int val,int *bitstring)
-{
-       *bitstring=val&0xfff;
-       return 12;
-}
-       
-#ifdef PCIMIO
-static int pack_ad8522(int addr,int val,int *bitstring)
-{
-       *bitstring=(val&0xfff)|(addr ? 0xc000:0xa000);
-       return 16;
-}
-#endif
-
-
-
-/*
- *
- *  Programmable Function Inputs
- *
- */
-
-
-static void pfi_setup(comedi_device *dev)
-{
-       /* currently, we don't output any signals, thus, all
-          the PFI's are input */
-       
-       //TIM 4/17/01 win_out(0,IO_Bidirection_Pin_Register);
-       ni_set_bits(dev, IO_Bidirection_Pin_Register, 0x03ff, 0);
-}
-
-
-
-/*
- *
- *  General Purpose Counter/Timer section
- *
- */
-
-/*
-*   Low level stuff...Each STC counter has two 24 bit load registers (A&B).  Just make
-* it easier to access them.
-*/
-static void GPCT_Load_A(comedi_device *dev, int chan, long value)
-{
-       win_out( (value>>16) & 0x00ff, G_Load_A_Register_High(chan));
-       win_out( value & 0xffff, G_Load_A_Register_Low(chan));
-}
-
-static void GPCT_Load_B(comedi_device *dev, int chan, long value)
-{
-       win_out( (value>>16) & 0x00ff, G_Load_B_Register_High(chan));
-       win_out( value & 0xffff, G_Load_B_Register_Low(chan));
-}
-
-/*  Load a value into the counter, using register A as the intermediate step.
-*  You might use GPCT_Load_Using_A to load a 0x000000 into a counter
-*  reset its value.
-*/
-static void GPCT_Load_Using_A(comedi_device *dev, int chan, long value)
-{
-       devpriv->gpct_mode[chan] &= (~G_Load_Source_Select);
-       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
-       GPCT_Load_A(dev,chan,value);
-       win_out( devpriv->gpct_command[chan]|G_Load,G_Command_Register(chan));
-}
-
-/*     Don't use this by itself!  The read is not atomic and quite unsafe.
-*      If you think you need this function, use GPCT_G_Watch instead.
-*/
-int inline GPCT_G_Read(comedi_device *dev, int chan)
-{
-       int tmp;
-       tmp = win_in( G_Save_Register_High(chan)) << 16;
-       tmp |= win_in(G_Save_Register_Low(chan));
-       return tmp;
-}
-
-/*
-*      Read the GPCTs current value.  
-*      This function is actually straight out of the STC RLPM.
-*/
-int GPCT_G_Watch(comedi_device *dev, int chan)
-{
-       int save1,save2;
-       
-       devpriv->gpct_command[chan] &= ~G_Save_Trace;
-       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
-       
-       devpriv->gpct_command[chan] |= G_Save_Trace;
-       win_out( devpriv->gpct_command[chan], G_Command_Register(chan));
-
-       save1 = GPCT_G_Read(dev,chan);
-       save2 = GPCT_G_Read(dev,chan);
-       
-       /*if the value changed during the read, try again*/
-       if (save1 != save2) {
-               save1 = GPCT_G_Read(dev,chan);
-       }
-       return save1;
-}
-
-
-int GPCT_Disarm(comedi_device *dev, int chan)
-{
-       win_out( devpriv->gpct_command[chan] | G_Disarm,G_Command_Register(chan));
-       return 0;
-}
-
-
-int GPCT_Arm(comedi_device *dev, int chan)
-{
-       win_out( devpriv->gpct_command[chan] | G_Arm,G_Command_Register(chan));
-       /* If the counter is doing pulse width measurement, then make
-        sure that the counter did not start counting right away.  This would
-        indicate that we started acquiring the pulse after it had already 
-        started and our measurement would be inaccurate */
-       if(devpriv->gpct_cur_operation[chan] == GPCT_SINGLE_PW){
-               int g_status; 
-
-               g_status=win_in(G_Status_Register);
-               
-               if(chan == 0){
-                       //TIM 5/2/01 possible error with very short pulses
-                       if((G0_Counting_St & g_status)|| !(G0_Armed_St&g_status)) {
-                               //error: we missed the beginning of the pulse
-                               return -EINVAL; //there is probably a more accurate error code...
-                       }
-               }else{
-                       if((G1_Counting_St & g_status)|| !(G1_Armed_St&g_status)) {
-                               //error: we missed the beginning of the pulse
-                               return -EINVAL;
-                       }
-               }
-       }
-       return 0;
-}
-
-int GPCT_Set_Source(comedi_device *dev,int chan ,int source)
-{
-       //printk("GPCT_Set_Source...");
-       devpriv->gpct_input_select[chan] &= ~G_Source_Select(0x1f);//reset gate to 0
-       switch(source) {
-               case GPCT_INT_CLOCK:
-               devpriv->gpct_input_select[chan] |= G_Source_Select(0);//INT_TIMEBASE
-               break;
-       case GPCT_EXT_PIN:
-               if(chan==0)
-                       devpriv->gpct_input_select[chan] |= G_Source_Select(9);//PFI8
-               else
-                       devpriv->gpct_input_select[chan] |= G_Source_Select(4);//PFI3
-               break;
-       default:
-               return -EINVAL;
-       }
-       win_out(devpriv->gpct_input_select[chan], G_Input_Select_Register(chan));
-       //printk("exit GPCT_Set_Source\n");
-       return 0;
-}
-
-int GPCT_Set_Gate(comedi_device *dev,int chan ,int gate)
-{
-       //printk("GPCT_Set_Gate...");
-       devpriv->gpct_input_select[chan] &= ~G_Gate_Select(0x1f);//reset gate to 0
-       switch(gate) {
-       case GPCT_NO_GATE:
-               devpriv->gpct_input_select[chan] |= G_Gate_Select(31);//Low
-               devpriv->gpct_mode[chan] |= G_Gate_Polarity;
-               break;
-       case GPCT_EXT_PIN:
-               devpriv->gpct_mode[chan] &= ~G_Gate_Polarity;
-               if(chan==0){
-                       devpriv->gpct_input_select[chan] |= G_Gate_Select(10);//PFI9
-               }else{
-                       devpriv->gpct_input_select[chan] |= G_Gate_Select(5);//PFI4
-               }
-               break;
-       default:
-               return -EINVAL;
-       }
-       win_out(devpriv->gpct_input_select[chan], G_Input_Select_Register(chan));
-       win_out(devpriv->gpct_mode[chan], G_Mode_Register(chan));
-       //printk("exit GPCT_Set_Gate\n");
-       return 0;
-}
-
-int GPCT_Set_Direction(comedi_device *dev,int chan,int direction)
-{
-       //printk("GPCT_Set_Direction...");
-       
-       devpriv->gpct_command[chan] &= ~G_Up_Down(0x3);
-       switch (direction) {
-               case GPCT_UP:
-                       devpriv->gpct_command[chan] |= G_Up_Down(1);
-                       break;
-               case GPCT_DOWN:
-                       devpriv->gpct_command[chan] |= G_Up_Down(0);
-                       break;
-               case GPCT_HWUD:
-                       devpriv->gpct_command[chan] |= G_Up_Down(2);
-                       break;
-               default:
-                       printk("Error direction=0x%08x..",direction);
-                       return -EINVAL;
-       }
-       win_out(devpriv->gpct_command[chan], G_Command_Register(chan));
-       //TIM 4/23/01 win_out(devpriv->gpct_mode[chan], G_Mode_Register(chan));
-       //printk("exit GPCT_Set_Direction\n");
-       return 0;
-}
-
-void GPCT_Event_Counting(comedi_device *dev,int chan)
-{
-
-       //NOTE: possible residual bits from multibit masks can corrupt
-       //If you config for several measurements between Resets, watch out!
-       
-       //printk("GPCT_Event_Counting...");
-       
-       devpriv->gpct_cur_operation[chan] = GPCT_SIMPLE_EVENT;
-       
-       // Gating_Mode = 1
-       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Gating_Mode(1);
-       
-       // Trigger_Mode_For_Edge_Gate = 1
-       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
-       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
-
-       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
-       //printk("exit GPCT_Event_Counting\n");
-}
-
-void GPCT_Period_Meas(comedi_device *dev, int chan)
-{
-       //printk("GPCT_Period_Meas...");
-       
-       devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PERIOD;
-
-       
-       //NOTE: possible residual bits from multibit masks can corrupt
-       //If you config for several measurements between Resets, watch out!     
-       devpriv->gpct_mode[chan] &= ~G_OR_Gate;
-       devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
-       
-       // Output_Mode = 3 
-       devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Output_Mode(3);
-       
-       
-       //Gating Mode=2
-       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Gating_Mode(2);
-       
-       // Trigger_Mode_For_Edge_Gate=0
-       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
-       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(0);
-
-       devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;
-       devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;
-       devpriv->gpct_mode[chan] &= ~G_Loading_On_TC;
-       devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
-
-       // Stop_Mode = 2
-       devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Stop_Mode(0);
-       
-       // Counting_Once = 2 
-       devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
-       devpriv->gpct_mode[chan] |= G_Counting_Once(2);
-
-       // Up_Down = 1 
-       devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
-       devpriv->gpct_command[chan] |= G_Up_Down(1);
-
-       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
-       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
-       //printk("exit GPCT_Period_Meas\n");
-}
-
-void GPCT_Pulse_Width_Meas(comedi_device *dev, int chan)
-{
-       //printk("GPCT_Pulse_Width_Meas...");
-
-       devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PW;
-
-       devpriv->gpct_mode[chan] &= ~G_OR_Gate;
-       devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
-
-       // Output_Mode = 3 
-       devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Output_Mode(3);
-       
-       //Gating Mode=1
-       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Gating_Mode(1);//TIM 4/24/01 was 2
-       
-       // Trigger_Mode_For_Edge_Gate=2
-       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
-       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);//TIM 4/24/01 was 0
-
-
-       devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;//TIM 4/24/01 was 1
-       devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;//TIM 4/24/01 was 0
-
-       devpriv->gpct_mode[chan] &= ~G_Loading_On_TC;
-       devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
-
-       // Stop_Mode = 0
-       devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Stop_Mode(0);
-       
-       // Counting_Once = 2 
-       devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
-       devpriv->gpct_mode[chan] |= G_Counting_Once(2);
-
-       // Up_Down = 1 
-       devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
-       devpriv->gpct_command[chan] |= G_Up_Down(1);
-
-       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
-       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
-
-       //printk("exit GPCT_Pulse_Width_Meas\n");
-}
-
-/* GPCT_Gen_Single_Pulse() creates pulse of length pulsewidth which starts after the Arm
-signal is sent.  The pulse is delayed by the value already in the counter.  This function could
-be modified to send a pulse in response to a trigger event at its gate.*/
-void GPCT_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length)
-{
-       //printk("GPCT_Gen_Cont...");
-
-       devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PULSE_OUT;
-
-       // Set length of the pulse
-       GPCT_Load_B(dev,chan, length-1);
-
-       //Load next time using B, This is reset by GPCT_Load_Using_A()
-       devpriv->gpct_mode[chan] |= G_Load_Source_Select;
-       
-       devpriv->gpct_mode[chan] &= ~G_OR_Gate;
-       devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
-
-       // Output_Mode = 3 
-       devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Output_Mode(2); //TIM 4/26/01 was 3
-       
-       //Gating Mode=0 for untriggered single pulse
-       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Gating_Mode(0); //TIM 4/25/01 was 1
-       
-       // Trigger_Mode_For_Edge_Gate=0
-       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
-       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
-
-
-       devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;
-       devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;
-       devpriv->gpct_mode[chan] |= G_Loading_On_TC; //TIM 4/25/01
-       devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
-
-       // Stop_Mode = 2
-       devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Stop_Mode(2); //TIM 4/25/01
-       
-       // Counting_Once = 2 
-       devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
-       devpriv->gpct_mode[chan] |= G_Counting_Once(1); //TIM 4/25/01
-
-       // Up_Down = 1 
-       devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
-       devpriv->gpct_command[chan] |= G_Up_Down(0); //TIM 4/25/01 was 1
-
-       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
-       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
-
-       //printk("exit GPCT_Gen_Cont\n");
-}
-
-void GPCT_Gen_Cont_Pulse(comedi_device *dev, int chan, unsigned int length)
-{
-       //printk("GPCT_Gen_Cont...");
-
-       devpriv->gpct_cur_operation[chan] = GPCT_CONT_PULSE_OUT;
-
-       // Set length of the pulse
-       GPCT_Load_B(dev,chan, length-1);
-
-       //Load next time using B, This is reset by GPCT_Load_Using_A()
-       devpriv->gpct_mode[chan] |= G_Load_Source_Select;
-       
-       devpriv->gpct_mode[chan] &= ~G_OR_Gate;
-       devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;
-
-       // Output_Mode = 3 
-       devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Output_Mode(2); //TIM 4/26/01 was 3
-       
-       //Gating Mode=0 for untriggered single pulse
-       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Gating_Mode(0); //TIM 4/26/01 was 0
-       
-       // Trigger_Mode_For_Edge_Gate=0
-       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));
-       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);
-
-
-       devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;
-       devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;
-       devpriv->gpct_mode[chan] |= G_Loading_On_TC; 
-       devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;
-
-       // Stop_Mode = 2
-       devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));
-       devpriv->gpct_mode[chan] |= G_Stop_Mode(0); //TIM 4/26/01
-       
-       // Counting_Once = 2 
-       devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));
-       devpriv->gpct_mode[chan] |= G_Counting_Once(0); //TIM 4/26/01
-
-       // Up_Down = 1 
-       devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));
-       devpriv->gpct_command[chan] |= G_Up_Down(0); 
-
-       //TIM 4/26/01
-       //This seems pretty unsafe since I don't think it is cleared anywhere.
-       //I don't think this is working
-       //devpriv->gpct_command[chan] &= ~G_Bank_Switch_Enable;
-       //devpriv->gpct_command[chan] &= ~G_Bank_Switch_Mode;
-       
-
-       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
-       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));
-
-       //printk("exit GPCT_Gen_Cont\n");
-}
-
-void GPCT_Reset(comedi_device *dev, int chan)
-{
-       unsigned long irqflags;
-       int temp_ack_reg=0;
-       
-       //printk("GPCT_Reset...");
-       devpriv->gpct_cur_operation[chan] = GPCT_RESET;
-
-       switch (chan) {
-               case 0:
-                       //note: I need to share the soft copies of the Enable Register with the ISRs.
-                       // so I'm using comedi_spin_lock_irqsave() to guard this section of code
-                       win_out(G0_Reset,Joint_Reset_Register);
-                       comedi_spin_lock_irqsave(&dev->spinlock, irqflags);
-                       ni_set_bits(dev,Interrupt_A_Enable_Register,G0_TC_Interrupt_Enable,  0);
-                       ni_set_bits(dev,Interrupt_A_Enable_Register,G0_Gate_Interrupt_Enable,0);
-                       comedi_spin_unlock_irqrestore(&dev->spinlock, irqflags);
-                       temp_ack_reg |= G0_Gate_Error_Confirm;
-                       temp_ack_reg |= G0_TC_Error_Confirm;
-                       temp_ack_reg |= G0_TC_Interrupt_Ack;
-                       temp_ack_reg |= G0_Gate_Interrupt_Ack;
-                       win_out(temp_ack_reg,Interrupt_A_Ack_Register);
-               
-                       //problem...this interferes with the other ctr...
-                       devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
-                       win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);
-                       break;
-               case 1:
-                       win_out(G1_Reset,Joint_Reset_Register);
-                       comedi_spin_lock_irqsave(&dev->spinlock, irqflags);
-                       ni_set_bits(dev,Interrupt_B_Enable_Register,G1_TC_Interrupt_Enable,  0);
-                       ni_set_bits(dev,Interrupt_B_Enable_Register,G0_Gate_Interrupt_Enable,0);
-                       comedi_spin_unlock_irqrestore(&dev->spinlock, irqflags);
-                       temp_ack_reg |= G1_Gate_Error_Confirm;
-                       temp_ack_reg |= G1_TC_Error_Confirm;
-                       temp_ack_reg |= G1_TC_Interrupt_Ack;
-                       temp_ack_reg |= G1_Gate_Interrupt_Ack;
-                       win_out(temp_ack_reg,Interrupt_B_Ack_Register);
-               
-                       devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
-                       win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);
-                       break;
-       };
-       
-       devpriv->gpct_mode[chan] = 0;
-       devpriv->gpct_input_select[chan] = 0;
-       devpriv->gpct_command[chan] = 0;
-       
-       devpriv->gpct_command[chan] |= G_Synchronized_Gate;
-       
-       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));
-       win_out( devpriv->gpct_input_select[chan],G_Input_Select_Register(chan));
-       win_out( 0,G_Autoincrement_Register(chan)); 
-               
-       //printk("exit GPCT_Reset\n");
-}
-
-static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data)
-{
-       int retval=0;
-       //printk("data[0] is 0x%08x, data[1] is 0x%08x\n",data[0],data[1]);
-       switch(data[0]){
-       case GPCT_RESET:
-               if(insn->n!=1)return -EINVAL;
-               GPCT_Reset(dev,insn->chanspec);
-               break;
-       case GPCT_SET_SOURCE:
-               if(insn->n!=2)return -EINVAL;
-               retval=GPCT_Set_Source(dev,insn->chanspec,data[1]);
-               break;
-       case GPCT_SET_GATE:
-               if(insn->n!=2)return -EINVAL;
-               retval=GPCT_Set_Gate(dev,insn->chanspec,data[1]);
-               break;
-       case GPCT_SET_DIRECTION:
-               if(insn->n!=2) return -EINVAL;
-               retval=GPCT_Set_Direction(dev,insn->chanspec,data[1]);
-               break;
-       case GPCT_GET_INT_CLK_FRQ:
-               if(insn->n!=2) return -EINVAL;
-               //There are actually 2 internal clocks on the STC, we always
-               //use the fast 20MHz one at this time.  Tim  Ousley 5/1/01
-               //NOTE: This is not the final interface, ideally the user
-               //will never need to know the int. clk. freq.
-               data[1]=50;//50ns = 20MHz = internal timebase of STC
-               break;
-       case GPCT_SET_OPERATION:
-               //TIM 5/1/01 if((insn->n<2)||(insn->n>3))return -EINVAL;
-               switch(data[1]){
-                       case GPCT_SIMPLE_EVENT:
-                               GPCT_Event_Counting(dev,insn->chanspec);
-                               break;
-                       case GPCT_SINGLE_PERIOD:
-                               GPCT_Period_Meas(dev,insn->chanspec);
-                               break;
-                       case GPCT_SINGLE_PW:
-                               GPCT_Pulse_Width_Meas(dev,insn->chanspec);
-                               break;
-                       case GPCT_SINGLE_PULSE_OUT:
-                               GPCT_Gen_Single_Pulse(dev,insn->chanspec,data[2]);
-                               break;
-                       case GPCT_CONT_PULSE_OUT:
-                               GPCT_Gen_Cont_Pulse(dev,insn->chanspec,data[2]);
-                               break;
-                       default:
-                               printk("unsupported GPCT operation!\n");
-                               return -EINVAL;
-               }
-               break;
-       case GPCT_ARM:
-               if(insn->n!=1)return -EINVAL;
-               retval=GPCT_Arm(dev,insn->chanspec);
-               break;
-       case GPCT_DISARM:
-               if(insn->n!=1)return -EINVAL;
-               retval=GPCT_Disarm(dev,insn->chanspec);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       //catch any errors from return values
-       if(retval==0){
-               return insn->n;
-       }else{
-               if(data[0]!=GPCT_ARM){ 
-                       printk("error: retval was %d\n",retval);
-                       printk("data[0] is 0x%08x, data[1] is 0x%08x\n",data[0],data[1]);
-               }
-
-               return retval;
-       }
-}
-
-static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data) {
-
-       int chan=insn->chanspec;
-       int cur_op = devpriv->gpct_cur_operation[chan];
-               
-       //printk("in ni_gpct_insn_read, n=%d, data[0]=%d\n",insn->chanspec,data[0]);
-       if(insn->n!=1)return -EINVAL;
-               
-       data[0] = GPCT_G_Watch(dev,insn->chanspec);
-               
-       /* for certain modes (period and pulse width measurment), the value
-       in the counter is not valid until the counter stops.  If the value is 
-       invalid, return a 0 */
-       if((cur_op == GPCT_SINGLE_PERIOD) || (cur_op == GPCT_SINGLE_PW)){
-               /* is the counter still running? */
-               if(win_in(G_Status_Register) & (chan?G1_Counting_St:G0_Counting_St))
-                       data[0]=0;
-       }
-       return 1;
-}
-
-static int ni_gpct_insn_write(comedi_device *dev,comedi_subdevice *s,
-       comedi_insn *insn,lsampl_t *data) {
-
-       //printk("in ni_gpct_insn_write");
-       if(insn->n!=1)return -EINVAL;
-       GPCT_Load_Using_A(dev,insn->chanspec,data[0]);
-       return 1;
-}
-
-
-static int ni_8255_callback(int dir,int port,int data,void *arg)
-{
-       comedi_device *dev=arg;
-
-       if(dir){
-               ni_writeb(data,Port_A+2*port);
-               return 0;
-       }else{
-               return ni_readb(Port_A+2*port);
-       }
-}
+                                               \r
+                       //TIM 4/17/01\r
+                       //win_out(0x0000,Interrupt_A_Enable_Register);\r
+                       //turn off all AI interrupts\r
+                       ni_set_bits(dev, Interrupt_A_Enable_Register,\r
+                               AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|\r
+                               AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|\r
+                               AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|\r
+                               AI_FIFO_Interrupt_Enable,0);\r
+                               \r
+                       ni_ai_reset(dev,dev->subdevices);//added by tim\r
+                       comedi_done(dev,s);\r
+                       return;\r
+               }\r
+               if(status&AI_SC_TC_St){\r
+#ifdef DEBUG_INTERRUPT\r
+                       rt_printk("ni_mio_common: SC_TC interrupt\n");\r
+#endif\r
+#ifdef TRY_BLOCK\r
+                       ni_handle_block(dev);\r
+#else\r
+                       //for MITE DMA ignore the terminal count from the STC\r
+                       //instead finish up when the MITE asserts DONE\r
+#ifndef PCIDMA\r
+                       \r
+                       if(!devpriv->ai_continuous){\r
+                               ni_handle_fifo_dregs(dev);\r
+                               //win_out(0x0000,Interrupt_A_Enable_Register); TIM 4/17/01\r
+                               ni_set_bits(dev, Interrupt_A_Enable_Register,\r
+                               AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|\r
+                               AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|\r
+                               AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|\r
+                               AI_FIFO_Interrupt_Enable,0);\r
+\r
+                               comedi_done(dev,s);\r
+                       }\r
+#endif //PCIDMA\r
+#endif //TRY_BLOCK\r
+                       ack|=AI_SC_TC_Interrupt_Ack;\r
+               }\r
+               if(status&AI_START1_St){\r
+                       ack|=AI_START1_Interrupt_Ack;\r
+               }\r
+       }\r
+#ifndef PCIDMA\r
+       if(status&AI_FIFO_Half_Full_St){\r
+               ni_handle_fifo_half_full(dev);\r
+       }\r
+#endif //PCIDMA\r
+       if(devpriv->aimode==AIMODE_SCAN && status&AI_STOP_St){\r
+               ni_handle_fifo_dregs(dev);\r
+\r
+               s->async->events |= COMEDI_CB_EOS;\r
+\r
+               /* we need to ack the START, also */\r
+               ack|=AI_STOP_Interrupt_Ack|AI_START_Interrupt_Ack;\r
+       }\r
+       if(devpriv->aimode==AIMODE_SAMPLE){\r
+               ni_handle_fifo_dregs(dev);\r
+\r
+               //s->async->events |= COMEDI_CB_SAMPLE;\r
+       }\r
+\r
+       if(ack) ni_writew(ack,Interrupt_A_Ack);\r
+\r
+       comedi_event(dev,s,s->async->events);\r
+}\r
+\r
+static void handle_b_interrupt(comedi_device *dev,unsigned short b_status)\r
+{\r
+       comedi_subdevice *s=dev->subdevices+1;\r
+       //unsigned short ack=0;\r
+\r
+       if(b_status==0xffff)return;\r
+       if(b_status&AO_Overrun_St){\r
+               rt_printk("ni-E: AO FIFO underrun status=0x%04x status2=0x%04x\n",b_status,ni_readw(AO_Status_2));\r
+       }\r
+\r
+       if(b_status&AO_BC_TC_St){\r
+               rt_printk("ni-E: AO BC_TC status=0x%04x status2=0x%04x\n",b_status,ni_readw(AO_Status_2));\r
+       }\r
+\r
+       if(b_status&AO_FIFO_Request_St)\r
+               ni_ao_fifo_half_empty(dev,s);\r
+\r
+       b_status=ni_readw(AO_Status_1);\r
+       if(b_status&Interrupt_B_St){\r
+               if(b_status&AO_FIFO_Request_St){\r
+                       rt_printk("ni_mio_common: AO buffer underrun\n");\r
+               }\r
+               rt_printk("Ack! didn't clear AO interrupt. b_status=0x%04x\n",b_status);\r
+               win_out(0,Interrupt_B_Enable_Register);\r
+       }\r
+}\r
+\r
+#ifdef DEBUG_STATUS_A\r
+static char *status_a_strings[]={\r
+       "passthru0","fifo","G0_gate","G0_TC",\r
+       "stop","start","sc_tc","start1",\r
+       "start2","sc_tc_error","overflow","overrun",\r
+       "fifo_empty","fifo_half_full","fifo_full","interrupt_a"\r
+};\r
+\r
+static void ni_mio_print_status_a(int status)\r
+{\r
+       int i;\r
+\r
+       rt_printk("A status:");\r
+       for(i=15;i>=0;i--){\r
+               if(status&(1<<i)){\r
+                       rt_printk(" %s",status_a_strings[i]);\r
+               }\r
+       }\r
+       rt_printk("\n");\r
+}\r
+#endif\r
+\r
+#ifdef DEBUG_STATUS_B\r
+static char *status_b_strings[]={\r
+       "passthru1","fifo","G1_gate","G1_TC",\r
+       "UI2_TC","UPDATE","UC_TC","BC_TC",\r
+       "start1","overrun","start","bc_tc_error",\r
+       "fifo_empty","fifo_half_full","fifo_full","interrupt_b"\r
+};\r
+\r
+static void ni_mio_print_status_b(int status)\r
+{\r
+       int i;\r
+\r
+       rt_printk("B status:");\r
+       for(i=15;i>=0;i--){\r
+               if(status&(1<<i)){\r
+                       rt_printk(" %s",status_b_strings[i]);\r
+               }\r
+       }\r
+       rt_printk("\n");\r
+}\r
+#endif\r
+\r
+static void ni_ai_fifo_read(comedi_device *dev,comedi_subdevice *s,\r
+               sampl_t *data,int n)\r
+{\r
+       comedi_async *async = s->async;\r
+       int i,j;\r
+       sampl_t d;\r
+       unsigned int mask;\r
+\r
+       mask=(1<<boardtype.adbits)-1;\r
+       j=async->cur_chan;\r
+       for(i=0;i<n;i++){\r
+               d=ni_readw(ADC_FIFO_Data_Register);\r
+               d^=devpriv->ai_xorlist[j];\r
+               d&=mask;\r
+               data[i]=d;\r
+               j++;\r
+               if(j>=async->cur_chanlist_len){\r
+                       j=0;\r
+                       async->events |= COMEDI_CB_EOS;\r
+               }\r
+       }\r
+       async->cur_chan=j;\r
+}\r
+\r
+#ifdef PCIDMA\r
+void ni_munge(comedi_device *dev,comedi_subdevice *s,sampl_t *start, sampl_t *stop)\r
+{\r
+       comedi_async *async = s->async;\r
+       int j;\r
+       sampl_t *i;\r
+       unsigned int mask;\r
+\r
+       mask=(1<<boardtype.adbits)-1;\r
+       j=async->cur_chan;\r
+       for(i=start;i<stop;i++){\r
+               *i ^=devpriv->ai_xorlist[j];\r
+               *i &=mask;\r
+               j++;\r
+               j %= async->cur_chanlist_len;\r
+       }\r
+       async->cur_chan=j;\r
+}\r
+\r
+static void ni_handle_block_dma(comedi_device *dev)\r
+{\r
+       MDPRINTK("ni_handle_block_dma\n");\r
+       //mite_dump_regs(devpriv->mite);  \r
+       mite_dma_disarm(devpriv->mite);\r
+       //TIM 4/17/01 win_out(0x0000,Interrupt_A_Enable_Register);\r
+       ni_set_bits(dev, Interrupt_A_Enable_Register,\r
+               AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|\r
+               AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|\r
+               AI_STOP_Interrupt_Enable| AI_Error_Interrupt_Enable|\r
+               AI_FIFO_Interrupt_Enable,0);\r
+\r
+       ni_ai_reset(dev,dev->subdevices);\r
+       comedi_done(dev,dev->subdevices);\r
+       MDPRINTK("exit ni_handle_block_dma\n");\r
+}\r
+#endif\r
+\r
+#ifdef TRY_BLOCK\r
+/* Blocked mode is used to get interrupts at convenient places\r
+ * to do DMA.  It is also useful when you want to count greater\r
+ * than 16M scans.\r
+ */\r
+static void ni_handle_block(comedi_device *dev)\r
+{\r
+       int n;\r
+\r
+       if(devpriv->ai_continuous){\r
+               n = devpriv->blocksize;\r
+       }else{\r
+               if(devpriv->n_left==0){\r
+                       ni_handle_fifo_dregs(dev);\r
+                       printk("end\n");\r
+                       //TIM 4/17/01 win_out(0x0000,Interrupt_A_Enable_Register);\r
+                       ni_set_bits(dev, Interrupt_A_Enable_Register,\r
+                               AI_SC_TC_Interrupt_Enable | AI_Start1_Interrupt_Enable|\r
+                               AI_Start2_Interrupt_Enable| AI_Start_Interrupt_Enable|\r
+                               AI_Stop_Interrupt_Enable| AI_Error_Interrupt_Enable|\r
+                               AI_FIFO_Interrupt_Enable,0);\r
+                       ni_ai_reset(dev,dev->subdevices);\r
+                       comedi_done(dev,dev->subdevices);\r
+               }else if(devpriv->n_left<=devpriv->blocksize){\r
+                       printk("last block %d\n",devpriv->n_left);\r
+                       n = devpriv->n_left;\r
+                       devpriv->n_left = 0;\r
+               }else{\r
+                       printk("block %d\n",devpriv->n_left);\r
+                       n = devpriv->blocksize;\r
+                       devpriv->n_left -= devpriv->blocksize;\r
+               }\r
+       }\r
+#if 0\r
+       {\r
+               int size=0x10000;\r
+\r
+       /* stage number of scans */\r
+       win_out((size-1)>>16,AI_SC_Load_A_Registers);\r
+       win_out((size-1)&0xffff,AI_SC_Load_A_Registers+1);\r
+\r
+       //mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;\r
+       mode1 |= 0xe;\r
+       win_out(mode1,AI_Mode_1_Register);\r
+\r
+       /* load SC (Scan Count) */\r
+       win_out(AI_SC_Load,AI_Command_1_Register);\r
+\r
+       }\r
+#endif\r
+}\r
+#endif\r
+\r
+static void ni_handle_fifo_half_full(comedi_device *dev)\r
+{\r
+       int n,m;\r
+       comedi_subdevice *s=dev->subdevices+0;\r
+       comedi_async *async=s->async;\r
+\r
+       /*\r
+          if we got a fifo_half_full interrupt, we can transfer fifo/2\r
+          samples without checking the empty flag.  It doesn't matter if\r
+          we transfer the rest of the samples, the performance trade-off\r
+          is minimal (checking empty flag for a few samples vs. having\r
+          1% more interrupts.)  At really high speeds, it's better to\r
+          ignore them.\r
+\r
+       */\r
+\r
+       n=boardtype.ai_fifo_depth/2;\r
+\r
+       /* this makes the assumption that the buffer length is\r
+          greater than the half-fifo depth. */\r
+\r
+       if(async->buf_int_ptr+n*sizeof(sampl_t)>=async->data_len){\r
+               m=(async->data_len-async->buf_int_ptr)/sizeof(sampl_t);\r
+               ni_ai_fifo_read(dev,s,async->data+async->buf_int_ptr,m);\r
+               async->buf_int_count+=m*sizeof(sampl_t);\r
+               n-=m;\r
+               async->buf_int_ptr=0;\r
+\r
+               async->events |= COMEDI_CB_EOBUF;\r
+       }\r
+       ni_ai_fifo_read(dev,s,async->data+async->buf_int_ptr,n);\r
+       async->buf_int_count+=n*sizeof(sampl_t);\r
+       async->buf_int_ptr+=n*sizeof(sampl_t);\r
+\r
+       async->events |= COMEDI_CB_BLOCK;\r
+}\r
+\r
+/*\r
+   Empties the AI fifo\r
+*/\r
+static void ni_handle_fifo_dregs(comedi_device *dev)\r
+{\r
+       comedi_subdevice *s=dev->subdevices+0;\r
+       sampl_t *data,d;\r
+       int i,n;\r
+       int j;\r
+       unsigned int mask;\r
+\r
+       mask=(1<<boardtype.adbits)-1;\r
+       j=s->async->cur_chan;\r
+       data=s->async->data+s->async->buf_int_ptr;\r
+       while(1){\r
+               n=(s->async->data_len-s->async->buf_int_ptr)/sizeof(sampl_t);\r
+               for(i=0;i<n;i++){\r
+                       if(ni_readw(AI_Status_1)&AI_FIFO_Empty_St){\r
+                               s->async->cur_chan=j;\r
+                               return;\r
+                       }\r
+                       d=ni_readw(ADC_FIFO_Data_Register);\r
+                       d^=devpriv->ai_xorlist[j];\r
+                       d&=mask;\r
+                       *data=d;\r
+                       j++;\r
+                       if(j>=s->async->cur_chanlist_len){\r
+                               j=0;\r
+                               //s->events |= COMEDI_CB_EOS;\r
+                       }\r
+                       data++;\r
+                       s->async->buf_int_ptr+=sizeof(sampl_t);\r
+                       s->async->buf_int_count+=sizeof(sampl_t);\r
+               }\r
+               s->async->buf_int_ptr=0;\r
+               data=s->async->data;\r
+               s->async->events |= COMEDI_CB_EOBUF;\r
+       }\r
+}\r
+\r
+#ifdef PCIDMA\r
+int ni_ai_setup_block_dma(comedi_device *dev,int frob,int mode1)\r
+{\r
+       int n;\r
+       int len;\r
+       unsigned long ll_start;\r
+       comedi_cmd *cmd=&dev->subdevices->async->cmd;\r
+               \r
+       MDPRINTK("ni_ai_setup_block_dma\n");\r
+               \r
+       /*Build MITE linked list and configure the MITE\r
+        * ******WARNING******\r
+        * There is no error handling here, \r
+        * the memory buffer *Must* be mlock'ed by the user*/\r
+\r
+       len = sizeof(sampl_t)*cmd->stop_arg*cmd->scan_end_arg;\r
+\r
+       /*use kvmem if no user buf specified */\r
+       ll_start = mite_ll_from_kvmem(devpriv->mite,dev->subdevices->async,\r
+               len);\r
+\r
+       mite_setregs(devpriv->mite, ll_start,0,COMEDI_INPUT);\r
+\r
+       /*tell the STC to use DMA0 for AI. \r
+        * Select the MITE DMA channel to use, 0x01=A*/\r
+       ni_writeb(0x01,AI_AO_Select);\r
+\r
+       /* stage number of scans */\r
+       n = cmd->stop_arg;\r
+       win_out((n-1)>>16,AI_SC_Load_A_Registers);\r
+       win_out((n-1)&0xffff,AI_SC_Load_A_Registers+1);\r
+       win_out((n-1)>>16,AI_SC_Load_B_Registers);\r
+       win_out((n-1)&0xffff,AI_SC_Load_B_Registers+1);\r
+               \r
+       /* load SC (Scan Count) */\r
+       win_out(AI_SC_Load,AI_Command_1_Register);\r
+\r
+       mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;\r
+       win_out(mode1,AI_Mode_1_Register);\r
+               \r
+       /*start the MITE*/\r
+       mite_dma_arm(devpriv->mite);\r
+               \r
+       MDPRINTK("exit ni_ai_setup_block_dma\n");\r
+\r
+       return mode1;\r
+}\r
+#endif\r
+\r
+#ifdef TRY_BLOCK\r
+int ni_ai_setup_block(comedi_device *dev,int frob,int mode1)\r
+{\r
+       int n;\r
+       int last=0;\r
+\r
+printk("n_left = %d\n",devpriv->n_left);\r
+       if(devpriv->ai_continuous){\r
+               n=devpriv->blocksize;\r
+               last=0;\r
+       }else{\r
+               n=devpriv->n_left;\r
+               if(n>devpriv->blocksize){\r
+                       n=devpriv->blocksize;\r
+                       last=0;\r
+               }else{\r
+                       last=1;\r
+               }\r
+               devpriv->n_left -= n;\r
+       }\r
+\r
+       if(frob){\r
+               /* stage number of scans */\r
+               win_out((n-1)>>16,AI_SC_Load_A_Registers);\r
+               win_out((n-1)&0xffff,AI_SC_Load_A_Registers+1);\r
+               win_out((n-1)>>16,AI_SC_Load_B_Registers);\r
+               win_out((n-1)&0xffff,AI_SC_Load_B_Registers+1);\r
+\r
+               /* load SC (Scan Count) */\r
+               win_out(AI_SC_Load,AI_Command_1_Register);\r
+#if 0\r
+               if(!last){\r
+                       mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;\r
+               }else{\r
+                       mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;\r
+               }\r
+#endif\r
+               mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;\r
+               win_out(mode1,AI_Mode_1_Register);\r
+\r
+       }\r
+\r
+       return mode1;\r
+}\r
+#endif\r
+\r
+#ifdef PCIDMA\r
+int ni_ai_setup_MITE_dma(comedi_device *dev,comedi_cmd *cmd,int mode1)\r
+{\r
+       int n,len;\r
+       unsigned long ll_start;\r
+       comedi_async *async_mite;\r
+       \r
+       len = sizeof(sampl_t)*cmd->stop_arg*cmd->scan_end_arg;\r
+       async_mite=dev->subdevices[cmd->subdev].async;\r
+       ll_start = mite_ll_from_kvmem(devpriv->mite, async_mite,len);\r
+       mite_setregs(devpriv->mite, ll_start,0,COMEDI_INPUT);\r
+\r
+       /*tell the STC to use DMA0 for AI.\r
+       Select the MITE DMA channel to use, 0x01=A*/\r
+       ni_writeb(0x01,AI_AO_Select);\r
+\r
+       /* stage number of scans */\r
+       n = cmd->stop_arg;\r
+       win_out((n-1)>>16,AI_SC_Load_A_Registers);\r
+       win_out((n-1)&0xffff,AI_SC_Load_A_Registers+1);\r
+       win_out((n-1)>>16,AI_SC_Load_B_Registers);\r
+       win_out((n-1)&0xffff,AI_SC_Load_B_Registers+1);\r
+       \r
+       /* load SC (Scan Count) */\r
+       win_out(AI_SC_Load,AI_Command_1_Register);\r
+\r
+       mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;\r
+       win_out(mode1,AI_Mode_1_Register);\r
+       \r
+       /*start the MITE*/\r
+       mite_dma_arm(devpriv->mite);\r
+       return mode1;\r
+}\r
+#endif\r
+\r
+/*\r
+   used for both cancel ioctl and board initialization\r
+\r
+   this is pretty harsh for a cancel, but it works...\r
+ */\r
+static int ni_ai_reset(comedi_device *dev,comedi_subdevice *s)\r
+{\r
+#ifdef PCIDMA\r
+       mite_dma_disarm(devpriv->mite);\r
+#endif\r
+       //TIM 4/17/01 win_out(0x0000,Interrupt_A_Enable_Register);\r
+       ni_set_bits(dev, Interrupt_A_Enable_Register,\r
+               AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable|\r
+               AI_START2_Interrupt_Enable| AI_START_Interrupt_Enable|\r
+               AI_STOP_Interrupt_Enable|   AI_Error_Interrupt_Enable|\r
+               AI_FIFO_Interrupt_Enable,0);\r
+\r
+       win_out(AI_Reset,Joint_Reset_Register);\r
+\r
+       win_out(1,ADC_FIFO_Clear);\r
+\r
+       /* ai configuration */\r
+\r
+       win_out(AI_Configuration_Start,Joint_Reset_Register);\r
+\r
+       win_out(0x0000,AI_Command_1_Register); /* reset pulses */\r
+       win_out(0x000d,AI_Mode_1_Register);\r
+       win_out(0x0000,AI_Mode_2_Register);\r
+#if 0\r
+       win_out((1<<6)|0x0000,AI_Mode_3_Register); /* generate FIFO interrupts on half full */\r
+#else\r
+       win_out((0<<6)|0x0000,AI_Mode_3_Register); /* generate FIFO interrupts on non-empty */\r
+#endif\r
+       /* TIM 5/11/01 \r
+       0xA4A0 causes overrun errors at high speeds.  0xA420 fixes it,\r
+       but I haven't tested to see if it breaks something else. I don't think it would*/\r
+       #ifdef PCIDMA  \r
+       win_out(0xA420,AI_Personal_Register); \r
+       #else\r
+       win_out(0xa4a0,AI_Personal_Register); /* ? */\r
+       #endif\r
+       win_out(0x032e,AI_Output_Control_Register);\r
+       win_out(0x0060,AI_Trigger_Select_Register); /* trigger source */\r
+\r
+       /* this should be done in _ai_modeX() */\r
+       win_out(0x29e0,AI_START_STOP_Select_Register);\r
+\r
+       /* the following registers should not be changed, because there\r
+        * are no backup registers in devpriv.  If you want to change\r
+        * any of these, add a backup register and other appropriate code:\r
+        *      Clock_and_FOUT_Register\r
+        *      AI_Mode_1_Register\r
+        *      AI_Mode_3_Register\r
+        *      AI_Personal_Register\r
+        *      AI_Output_Control_Register\r
+        *      AI_Trigger_Select_Register\r
+       */\r
+       win_out(0x3f80,Interrupt_A_Ack_Register); /* clear interrupts */\r
+\r
+       win_out(AI_Configuration_End,Joint_Reset_Register);\r
+\r
+       return 0;\r
+}\r
+\r
+static int ni_ai_poll(comedi_device *dev,comedi_subdevice *s)\r
+{\r
+       unsigned long flags;\r
+\r
+       comedi_spin_lock_irqsave(&dev->spinlock,flags);\r
+       ni_handle_fifo_dregs(dev);\r
+       comedi_spin_unlock_irqrestore(&dev->spinlock,flags);\r
+\r
+       comedi_event(dev,s,s->async->events);\r
+\r
+       return s->async->buf_int_count-s->async->buf_user_count;\r
+}\r
+\r
+static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,unsigned int *list,int dither);\r
+\r
+#define NI_TIMEOUT 1000\r
+\r
+\r
+static int ni_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)\r
+{\r
+       int i,n;\r
+       int wsave;\r
+       unsigned int mask,sign;\r
+\r
+       wsave=win_save();\r
+\r
+       win_out(1,ADC_FIFO_Clear);\r
+\r
+       /* interrupt on errors */\r
+       //TIM 4/17/01 win_out(0x0020,Interrupt_A_Enable_Register);\r
+       ni_set_bits(dev, Interrupt_A_Enable_Register, AI_Error_Interrupt_Enable,1);\r
+\r
+\r
+       //ni_load_channelgain_list(dev,1,&insn->chanspec,(insn->flags&TRIG_DITHER)==TRIG_DITHER);\r
+       ni_load_channelgain_list(dev,1,&insn->chanspec,0);\r
+\r
+#if 0\r
+#define NI_TIMEOUT 1000\r
+#endif\r
+       mask=(1<<boardtype.adbits)-1;\r
+       sign=devpriv->ai_xorlist[0];\r
+       for(n=0;n<insn->n;n++){\r
+               win_out(1,AI_Command_1_Register);\r
+               for(i=0;i<NI_TIMEOUT;i++){\r
+                       if(!(ni_readw(AI_Status_1)&AI_FIFO_Empty_St))\r
+                               break;\r
+               }\r
+               if(i==NI_TIMEOUT){\r
+                       rt_printk("ni_E: timeout 2\n");\r
+                       win_restore(wsave);\r
+                       return -ETIME;\r
+               }\r
+               data[n]=(ni_readw(ADC_FIFO_Data_Register)&mask)^sign;\r
+       }\r
+       win_restore(wsave);\r
+       return insn->n;\r
+}\r
+\r
+\r
+static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,unsigned int *list,int dither)\r
+{\r
+       unsigned int chan,range,aref;\r
+       unsigned int i;\r
+       unsigned int hi,lo;\r
+       unsigned short sign;\r
+\r
+       if(n_chan==1){\r
+               if(devpriv->changain_state && devpriv->changain_spec==list[0]){\r
+                       // ready to go.\r
+                       return;\r
+               }\r
+               devpriv->changain_state=1;\r
+               devpriv->changain_spec=list[0];\r
+       }else{\r
+               devpriv->changain_state=0;\r
+       }\r
+\r
+       win_out(1,Configuration_Memory_Clear);\r
+\r
+       sign=1<<(boardtype.adbits-1);\r
+       for(i=0;i<n_chan;i++){\r
+               chan=CR_CHAN(list[i]);\r
+               range=CR_RANGE(list[i]);\r
+               aref=CR_AREF(list[i]);\r
+\r
+               /* fix the external/internal range differences */\r
+               range=ni_gainlkup[boardtype.gainlkup][range];\r
+               devpriv->ai_xorlist[i]=(range<8)?sign:0;\r
+\r
+               hi=ni_modebits1[aref]|(chan&ni_modebits2[aref]);\r
+               ni_writew(hi,Configuration_Memory_High);\r
+\r
+               lo=((i==n_chan-1)?0x8000:0) | ((range&0x8)<<5) | (range&0x7) | (dither<<9);\r
+               ni_writew(lo,Configuration_Memory_Low);\r
+       }\r
+\r
+       /* prime the channel/gain list */\r
+\r
+       win_out(1,AI_Command_1_Register);\r
+       for(i=0;i<1000;i++){\r
+               if(!(ni_readw(AI_Status_1)&AI_FIFO_Empty_St)){\r
+                       win_out(1,ADC_FIFO_Clear);\r
+                       return;\r
+               }\r
+               //udelay(25);\r
+       }\r
+       rt_printk("ni_E: timeout 1\n");\r
+}\r
+\r
+#define TIMER_BASE 50 /* 20 Mhz base */\r
+\r
+static int ni_ns_to_timer(int *nanosec,int round_mode)\r
+{\r
+       int divider,base;\r
+\r
+       base=TIMER_BASE;\r
+\r
+       switch(round_mode){\r
+       case TRIG_ROUND_NEAREST:\r
+       default:\r
+               divider=(*nanosec+base/2)/base;\r
+               break;\r
+       case TRIG_ROUND_DOWN:\r
+               divider=(*nanosec)/base;\r
+               break;\r
+       case TRIG_ROUND_UP:\r
+               divider=(*nanosec+base-1)/base;\r
+               break;\r
+       }\r
+\r
+       *nanosec=base*divider;\r
+       return divider-1;\r
+}\r
+\r
+static int ni_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)\r
+{\r
+       int err=0;\r
+       int tmp;\r
+\r
+       /* step 1: make sure trigger sources are trivially valid */\r
+\r
+       tmp=cmd->start_src;\r
+       cmd->start_src &= TRIG_NOW|TRIG_INT;\r
+       if(!cmd->start_src || tmp!=cmd->start_src)err++;\r
+\r
+       tmp=cmd->scan_begin_src;\r
+       cmd->scan_begin_src &= TRIG_TIMER|TRIG_EXT;\r
+       if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;\r
+\r
+       tmp=cmd->convert_src;\r
+       cmd->convert_src &= TRIG_TIMER|TRIG_EXT;\r
+       if(!cmd->convert_src || tmp!=cmd->convert_src)err++;\r
+\r
+       tmp=cmd->scan_end_src;\r
+       cmd->scan_end_src &= TRIG_COUNT;\r
+       if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;\r
+\r
+       tmp=cmd->stop_src;\r
+       cmd->stop_src &= TRIG_COUNT|TRIG_NONE;\r
+       if(!cmd->stop_src || tmp!=cmd->stop_src)err++;\r
+\r
+       if(err)return 1;\r
+\r
+       /* step 2: make sure trigger sources are unique and mutually compatible */\r
+\r
+       /* note that mutual compatiblity is not an issue here */\r
+       if(cmd->start_src!=TRIG_NOW &&\r
+          cmd->start_src!=TRIG_INT)err++;\r
+       if(cmd->scan_begin_src!=TRIG_TIMER &&\r
+          cmd->scan_begin_src!=TRIG_EXT)err++;\r
+       if(cmd->convert_src!=TRIG_TIMER &&\r
+          cmd->convert_src!=TRIG_EXT)err++;\r
+       if(cmd->stop_src!=TRIG_COUNT &&\r
+          cmd->stop_src!=TRIG_NONE)err++;\r
+\r
+       if(err)return 2;\r
+\r
+       /* step 3: make sure arguments are trivially compatible */\r
+\r
+       if(cmd->start_arg!=0){\r
+               /* true for both TRIG_NOW and TRIG_INT */\r
+               cmd->start_arg=0;\r
+               err++;\r
+       }\r
+       if(cmd->scan_begin_src==TRIG_TIMER){\r
+               if(cmd->scan_begin_arg<boardtype.ai_speed){\r
+                       cmd->scan_begin_arg=boardtype.ai_speed;\r
+                       err++;\r
+               }\r
+               if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){\r
+                       cmd->scan_begin_arg=TIMER_BASE*0xffffff;\r
+                       err++;\r
+               }\r
+       }else{\r
+               /* external trigger */\r
+               /* should be level/edge, hi/lo specification here */\r
+               /* should specify multiple external triggers */\r
+#if 0\r
+/* XXX This is disabled, since we want to use bits 30 and 31 to\r
+ * refer to edge/level and hi/lo triggering. */\r
+               if(cmd->scan_begin_arg>9){\r
+                       cmd->scan_begin_arg=9;\r
+                       err++;\r
+               }\r
+#endif\r
+       }\r
+       if(cmd->convert_src==TRIG_TIMER){\r
+               if(cmd->convert_arg<boardtype.ai_speed){\r
+                       cmd->convert_arg=boardtype.ai_speed;\r
+                       err++;\r
+               }\r
+               if(cmd->convert_arg>TIMER_BASE*0xffff){\r
+                       cmd->convert_arg=TIMER_BASE*0xffff;\r
+                       err++;\r
+               }\r
+       }else{\r
+               /* external trigger */\r
+               /* see above */\r
+#if 0\r
+/* XXX This is disabled, since we want to use bits 30 and 31 to\r
+ * refer to edge/level and hi/lo triggering. */\r
+               if(cmd->convert_arg>9){\r
+                       cmd->convert_arg=9;\r
+                       err++;\r
+               }\r
+#endif\r
+       }\r
+\r
+       if(cmd->scan_end_arg!=cmd->chanlist_len){\r
+               cmd->scan_end_arg=cmd->chanlist_len;\r
+               err++;\r
+       }\r
+       if(cmd->stop_src==TRIG_COUNT){\r
+               if(cmd->stop_arg>0x00ffffff){\r
+                       cmd->stop_arg=0x00ffffff;\r
+                       err++;\r
+               }\r
+       }else{\r
+               /* TRIG_NONE */\r
+               if(cmd->stop_arg!=0){\r
+                       cmd->stop_arg=0;\r
+                       err++;\r
+               }\r
+       }\r
+\r
+       if(err)return 3;\r
+\r
+       /* step 4: fix up any arguments */\r
+\r
+       if(cmd->scan_begin_src==TRIG_TIMER){\r
+               tmp=cmd->scan_begin_arg;\r
+               ni_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);\r
+               if(tmp!=cmd->scan_begin_arg)err++;\r
+       }\r
+       if(cmd->convert_src==TRIG_TIMER){\r
+               tmp=cmd->convert_arg;\r
+               ni_ns_to_timer(&cmd->convert_arg,cmd->flags&TRIG_ROUND_MASK);\r
+               if(tmp!=cmd->convert_arg)err++;\r
+               if(cmd->scan_begin_src==TRIG_TIMER &&\r
+                 cmd->scan_begin_arg<cmd->convert_arg*cmd->scan_end_arg){\r
+                       cmd->scan_begin_arg=cmd->convert_arg*cmd->scan_end_arg;\r
+                       err++;\r
+               }\r
+       }\r
+\r
+       if(err)return 4;\r
+\r
+       return 0;\r
+}\r
+\r
+static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s)\r
+{\r
+       int wsave;\r
+       comedi_cmd *cmd=&s->async->cmd;\r
+       int timer;\r
+       int mode1=0; /* mode1 is needed for both stop and convert */\r
+       int mode2=0;\r
+\r
+       MDPRINTK("ni_ai_cmd\n");\r
+       wsave = win_save();\r
+\r
+       win_out(1,ADC_FIFO_Clear);\r
+\r
+       ni_load_channelgain_list(dev,cmd->chanlist_len,cmd->chanlist,\r
+               (cmd->flags&TRIG_DITHER)==TRIG_DITHER);\r
+\r
+       /* start configuration */\r
+       win_out(AI_Configuration_Start,Joint_Reset_Register);\r
+\r
+#ifndef TRY_BLOCK\r
+       #ifdef PCIDMA\r
+       ni_ai_setup_MITE_dma(dev,cmd,mode1);    \r
+       #else\r
+       switch(cmd->stop_src){\r
+       case TRIG_COUNT:\r
+               /* stage number of scans */\r
+               win_out((cmd->stop_arg-1)>>16,AI_SC_Load_A_Registers);\r
+               win_out((cmd->stop_arg-1)&0xffff,AI_SC_Load_A_Registers+1);\r
+\r
+               mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;\r
+               win_out(mode1,AI_Mode_1_Register);\r
+\r
+               /* load SC (Scan Count) */\r
+               win_out(AI_SC_Load,AI_Command_1_Register);\r
+\r
+               devpriv->ai_continuous = 0;\r
+\r
+               break;\r
+       case TRIG_NONE:\r
+               /* stage number of scans */\r
+               win_out(0,AI_SC_Load_A_Registers);\r
+               win_out(0,AI_SC_Load_A_Registers+1);\r
+\r
+               mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;\r
+               win_out(mode1,AI_Mode_1_Register);\r
+\r
+               /* load SC (Scan Count) */\r
+               win_out(AI_SC_Load,AI_Command_1_Register);\r
+\r
+               devpriv->ai_continuous = 1;\r
+\r
+               break;\r
+       }\r
+       #endif\r
+#else\r
+       devpriv->blocksize = 0x4000;\r
+       switch(cmd->stop_src){\r
+       case TRIG_COUNT:\r
+               devpriv->ai_continuous = 0;\r
+               devpriv->n_left = cmd->stop_arg;\r
+               break;\r
+       case TRIG_NONE:\r
+               devpriv->ai_continuous = 1;\r
+               devpriv->n_left = 0;\r
+               break;\r
+       }\r
+\r
+       mode1 = ni_ai_setup_block(dev,1,mode1);\r
+#endif\r
+\r
+\r
+       switch(cmd->scan_begin_src){\r
+       case TRIG_TIMER:\r
+               /*\r
+               AI_SI_Special_Trigger_Delay=0\r
+               AI_Pre_Trigger=0\r
+               AI_START_STOP_Select_Register:\r
+                   AI_START_Polarity=0 (?)     rising edge\r
+                   AI_START_Edge=1             edge triggered\r
+                   AI_START_Sync=1 (?)\r
+                   AI_START_Select=0           SI_TC\r
+                   AI_STOP_Polarity=0          rising edge\r
+                   AI_STOP_Edge=0              level\r
+                   AI_STOP_Sync=1\r
+                   AI_STOP_Select=19           external pin (configuration mem)\r
+                */\r
+               win_out(AI_START_Edge|AI_START_Sync|\r
+                       AI_STOP_Select(19)|AI_STOP_Sync,\r
+                       AI_START_STOP_Select_Register);\r
+\r
+               timer=ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);\r
+               win_out((timer>>16),AI_SI_Load_A_Registers);\r
+               win_out((timer&0xffff),AI_SI_Load_A_Registers+1);\r
+\r
+               /* AI_SI_Initial_Load_Source=A */\r
+               mode2 |= AI_SI_Initial_Load_Source&0;\r
+//mode2 |= AI_SC_Reload_Mode;\r
+               win_out(mode2,AI_Mode_2_Register);\r
+\r
+               /* load SI */\r
+               win_out(AI_SI_Load,AI_Command_1_Register);\r
+\r
+               /* stage freq. counter into SI B */\r
+               win_out((timer>>16),AI_SI_Load_B_Registers);\r
+               win_out((timer&0xffff),AI_SI_Load_B_Registers+1);\r
+\r
+               break;\r
+       case TRIG_EXT:\r
+           {\r
+               unsigned int reg = 0;\r
+\r
+/* XXX duh, these should be moved, but I need to think about it\r
+ * a bit first.  --ds */\r
+#define COMEDI_TRIG_LEVEL      0\r
+#define COMEDI_TRIG_EDGE       (1<<31)\r
+#define COMEDI_TRIG_FALLING    0\r
+#define COMEDI_TRIG_RISING     (1<<30)\r
+\r
+               if(cmd->scan_begin_arg&COMEDI_TRIG_EDGE)\r
+                       reg |= AI_START_Edge;\r
+               /* AI_START_Polarity==1 is falling edge */\r
+               if(!(cmd->scan_begin_arg&COMEDI_TRIG_RISING))\r
+                       reg |= AI_START_Polarity;\r
+               reg |= AI_START_Sync;\r
+               reg |= AI_START_Select(1+(cmd->scan_begin_arg&0xf));\r
+               reg |= AI_STOP_Select(19)|AI_STOP_Sync;\r
+\r
+               win_out(reg,AI_START_STOP_Select_Register);\r
+               break;\r
+           }\r
+       }\r
+\r
+       switch(cmd->convert_src){\r
+       case TRIG_TIMER:\r
+               timer=ni_ns_to_timer(&cmd->convert_arg,TRIG_ROUND_NEAREST);\r
+               win_out(1,AI_SI2_Load_A_Register); /* 0,0 does not work. */\r
+               win_out(timer,AI_SI2_Load_B_Register);\r
+\r
+               /* AI_SI2_Reload_Mode = alternate */\r
+               /* AI_SI2_Initial_Load_Source = A */\r
+               win_out((AI_SI2_Initial_Load_Source&0)|\r
+                       (AI_SI2_Reload_Mode),\r
+                       AI_Mode_2_Register);\r
+\r
+               /* AI_SI2_Load */\r
+               win_out(AI_SI2_Load,AI_Command_1_Register);\r
+\r
+               //mode2 |= AI_SI_Reload_Mode(0);\r
+       /* XXX the AI_SI stuff should go to the scan_begin_src area */\r
+               mode2 |= AI_SI_Reload_Mode(1);\r
+               //mode2 |= 0&AI_SI_Initial_Load_Source;\r
+               mode2 |= AI_SI_Initial_Load_Source;\r
+               mode2 |= AI_SI2_Reload_Mode; // alternate\r
+               mode2 |= AI_SI2_Initial_Load_Source; // B\r
+\r
+               win_out(mode2,AI_Mode_2_Register);\r
+\r
+               break;\r
+       case TRIG_EXT:\r
+               mode1 |= AI_CONVERT_Source_Select(1+cmd->convert_arg) |\r
+                       AI_CONVERT_Source_Polarity;\r
+               win_out(mode1,AI_Mode_1_Register);\r
+\r
+               win_out(mode2 | AI_SI2_Reload_Mode,AI_Mode_2_Register);\r
+\r
+               mode2 |= AI_SI_Reload_Mode(0);\r
+               mode2 |= 0&AI_SI_Initial_Load_Source;\r
+               mode2 |= AI_SI2_Reload_Mode; // alternate\r
+               mode2 |= AI_SI2_Initial_Load_Source; // B\r
+\r
+               win_out(mode2,AI_Mode_2_Register);\r
+\r
+               break;\r
+       }\r
+\r
+       if(dev->irq){\r
+               int bits;\r
+\r
+               /* interrupt on FIFO, errors, SC_TC */\r
+               bits= AI_Error_Interrupt_Enable|\r
+                       AI_SC_TC_Interrupt_Enable;\r
+\r
+#ifndef PCIDMA\r
+               bits|=AI_FIFO_Interrupt_Enable;\r
+#endif\r
+\r
+               if(s->async->cb_mask&COMEDI_CB_EOS){\r
+                       /* wake on end-of-scan */\r
+                       devpriv->aimode=AIMODE_SCAN;\r
+               }else{\r
+                       devpriv->aimode=AIMODE_HALF_FULL;\r
+               }\r
+\r
+               switch(devpriv->aimode){\r
+               case AIMODE_HALF_FULL:\r
+                       /*generate FIFO interrupts on half-full */\r
+                       win_out(AI_FIFO_Mode_HF|0x0000,AI_Mode_3_Register);\r
+                       break;\r
+               case AIMODE_SAMPLE:\r
+                       /*generate FIFO interrupts on non-empty */\r
+                       win_out(AI_FIFO_Mode_NE|0x0000,AI_Mode_3_Register);\r
+                       break;\r
+               case AIMODE_SCAN:\r
+                       /*generate FIFO interrupts on half-full */\r
+                       win_out(AI_FIFO_Mode_HF|0x0000,AI_Mode_3_Register);\r
+                       bits|=AI_STOP_Interrupt_Enable;\r
+                       break;\r
+               default:\r
+                       break;\r
+               }\r
+\r
+               win_out(0x3f80,Interrupt_A_Ack_Register); /* clear interrupts */\r
+\r
+               //TIM 4/17/01 win_out(bits,Interrupt_A_Enable_Register) ;\r
+               ni_set_bits(dev, Interrupt_A_Enable_Register, bits, 1);\r
+               \r
+               MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",bits);\r
+       }else{\r
+               /* interrupt on nothing */\r
+               win_out(0x0000,Interrupt_A_Enable_Register) ;\r
+\r
+               /* XXX start polling if necessary */\r
+               MDPRINTK("interrupting on nothing\n");\r
+       }\r
+\r
+       /* end configuration */\r
+       win_out(AI_Configuration_End,Joint_Reset_Register);\r
+\r
+       switch(cmd->scan_begin_src){\r
+       case TRIG_TIMER:\r
+               /* AI_SI2_Arm, AI_SI_Arm, AI_DIV_Arm, AI_SC_Arm */\r
+               win_out(0x1540,AI_Command_1_Register);\r
+               break;\r
+       case TRIG_EXT:\r
+               /* AI_SI2_Arm, AI_DIV_Arm, AI_SC_Arm */\r
+               win_out(0x1540,AI_Command_1_Register);\r
+               break;\r
+       }\r
+\r
+       if(cmd->start_src==TRIG_NOW){\r
+               /* TRIG_NOW */\r
+               /* AI_START1_Pulse */\r
+               win_out(AI_START1_Pulse,AI_Command_2_Register);\r
+               s->async->inttrig=NULL;\r
+       }else{\r
+               /* TRIG_INT */\r
+               s->async->inttrig=ni_ai_inttrig;\r
+       }\r
+\r
+       win_restore(wsave);\r
+\r
+       //mite_dump_regs(devpriv->mite);\r
+       MDPRINTK("exit ni_ai_cmd\n");\r
+       \r
+       return 0;\r
+}\r
+\r
+static int ni_ai_inttrig(comedi_device *dev,comedi_subdevice *s,\r
+       unsigned int trignum)\r
+{\r
+       int wsave;\r
+\r
+       if(trignum!=0)return -EINVAL;\r
+\r
+       wsave = win_save();\r
+\r
+       win_out(AI_START1_Pulse,AI_Command_2_Register);\r
+       s->async->inttrig=NULL;\r
+\r
+       win_restore(wsave);\r
+\r
+       return 1;\r
+}\r
+\r
+static void ni_ao_fifo_load(comedi_device *dev,comedi_subdevice *s,\r
+               sampl_t *data,int n)\r
+{\r
+       int i;\r
+\r
+       for(i=0;i<n;i++){\r
+               ni_writew(data[i],DAC_FIFO_Data);\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ *  There's a small problem if the FIFO gets really low and we\r
+ *  don't have the data to fill it.  Basically, if after we fill\r
+ *  the FIFO with all the data available, the FIFO is _still_\r
+ *  less than half full, we never clear the interrupt.  If the\r
+ *  IRQ is in edge mode, we never get another interrupt, because\r
+ *  this one wasn't cleared.  If in level mode, we get flooded\r
+ *  with interrupts that we can't fulfill, because nothing ever\r
+ *  gets put into the buffer.\r
+ *\r
+ *  This kind of situation is recoverable, but it is easier to\r
+ *  just pretend we had a FIFO underrun, since there is a good\r
+ *  chance it will happen anyway.  This is _not_ the case for\r
+ *  RT code, as RT code might purposely be running close to the\r
+ *  metal.  Needs to be fixed eventually.\r
+ */\r
+static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s)\r
+{\r
+       int n,m;\r
+\r
+       n=(s->async->buf_int_count-s->async->buf_user_count)/sizeof(sampl_t);\r
+       if(n==0)return 0;\r
+       if(n>boardtype.ao_fifo_depth/2)\r
+               n=boardtype.ao_fifo_depth/2;\r
+\r
+       if(s->async->buf_int_ptr+n*sizeof(sampl_t)>s->async->data_len){\r
+               m=(s->async->data_len-s->async->buf_int_ptr)/sizeof(sampl_t);\r
+               ni_ao_fifo_load(dev,s,s->async->data+s->async->buf_int_ptr,m);\r
+               s->async->buf_int_count+=m*sizeof(sampl_t);\r
+               s->async->buf_int_ptr=0;\r
+               n-=m;\r
+       }\r
+       ni_ao_fifo_load(dev,s,s->async->data+s->async->buf_int_ptr,n);\r
+       s->async->buf_int_count+=n*sizeof(sampl_t);\r
+       s->async->buf_int_ptr+=n*sizeof(sampl_t);\r
+\r
+       comedi_bufcheck(dev,s);\r
+\r
+       return 1;\r
+}\r
+\r
+static int ni_ao_prep_fifo(comedi_device *dev,comedi_subdevice *s)\r
+{\r
+       int n;\r
+\r
+       /* reset fifo */\r
+       win_out(0,DAC_FIFO_Clear);\r
+\r
+       /* load some data */\r
+       n=(s->async->buf_int_count-s->async->buf_user_count)/sizeof(sampl_t);\r
+       if(n==0)return 0;\r
+       if(n>boardtype.ao_fifo_depth)\r
+               n=boardtype.ao_fifo_depth;\r
+\r
+       ni_ao_fifo_load(dev,s,s->async->data+s->async->buf_int_ptr,n);\r
+       s->async->buf_int_count+=n*sizeof(sampl_t);\r
+       s->async->buf_int_ptr+=n*sizeof(sampl_t);\r
+\r
+       return n;\r
+}\r
+\r
+\r
+static int ni_ao_insn_read(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data)\r
+{\r
+       data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];\r
+\r
+       return 1;\r
+}\r
+\r
+static int ni_ao_insn_write(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data)\r
+{\r
+       unsigned int conf;\r
+       unsigned int chan;\r
+       unsigned int range;\r
+       unsigned int dat = data[0];\r
+\r
+       chan=CR_CHAN(insn->chanspec);\r
+\r
+       conf=chan<<8;\r
+\r
+       /* XXX check range with current range in flaglist[chan] */\r
+       /* should update calibration if range changes (ick) */\r
+\r
+       range = CR_RANGE(insn->chanspec);\r
+       if(boardtype.ao_unipolar){\r
+               conf |= (range&1)^1;\r
+       }\r
+       conf |= (range&2)<<1;\r
+\r
+#if 0\r
+       /* XXX oops.  forgot flags in insn! */\r
+       /* not all boards can deglitch, but this shouldn't hurt */\r
+       if(insn->flags & TRIG_DEGLITCH)\r
+               conf |= 2;\r
+#endif\r
+\r
+       /* analog reference */\r
+       /* AREF_OTHER connects AO ground to AI ground, i think */\r
+       conf |= (CR_AREF(insn->chanspec)==AREF_OTHER)? 8 : 0;\r
+\r
+       ni_writew(conf,AO_Configuration);\r
+\r
+       devpriv->ao[chan] = dat;\r
+\r
+       if(((range&1)==0) || !boardtype.ao_unipolar)\r
+               dat^=(1<<(boardtype.aobits-1));\r
+\r
+       ni_writew(dat,(chan)? DAC1_Direct_Data : DAC0_Direct_Data);\r
+\r
+       return 1;\r
+}\r
+\r
+static int ni_ao_cmd(comedi_device *dev,comedi_subdevice *s)\r
+{\r
+       comedi_cmd *cmd = &s->async->cmd;\r
+       unsigned int conf;\r
+       unsigned int chan;\r
+       unsigned int range;\r
+       int trigvar;\r
+       int i;\r
+       \r
+       trigvar = ni_ns_to_timer(&cmd->scan_begin_arg,TRIG_ROUND_NEAREST);\r
+\r
+       win_out(AO_Disarm,AO_Command_1_Register);\r
+\r
+       for(i=0;i<cmd->chanlist_len;i++){\r
+               chan=CR_CHAN(cmd->chanlist[i]);\r
+\r
+               conf=chan<<8;\r
+       \r
+               /* XXX check range with current range in flaglist[chan] */\r
+               /* should update calibration if range changes (ick) */\r
+\r
+               range = CR_RANGE(cmd->chanlist[i]);\r
+               conf |= (range&1);\r
+               conf |= (range&2)<<1;\r
+       \r
+               /* not all boards can deglitch, but this shouldn't hurt */\r
+               if(cmd->flags & TRIG_DEGLITCH) /* XXX ? */\r
+                       conf |= 2;\r
+\r
+               /* analog reference */\r
+               /* AREF_OTHER connects AO ground to AI ground, i think */\r
+               conf |= (CR_AREF(cmd->chanlist[i])==AREF_OTHER)? 8 : 0;\r
+\r
+               ni_writew(conf,AO_Configuration);\r
+       }\r
+\r
+       /* user is supposed to write() to buffer before triggering */\r
+       if(ni_ao_prep_fifo(dev,s)==0)\r
+               return -EIO;\r
+\r
+       win_out(AO_Configuration_Start,Joint_Reset_Register);\r
+\r
+       devpriv->ao_mode1|=AO_Trigger_Once;\r
+       win_out(devpriv->ao_mode1,AO_Mode_1_Register);\r
+       devpriv->ao_trigger_select&=~(AO_START1_Polarity|AO_START1_Select(-1));\r
+       devpriv->ao_trigger_select|=AO_START1_Edge|AO_START1_Sync;\r
+       win_out(devpriv->ao_trigger_select,AO_Trigger_Select_Register);\r
+       devpriv->ao_mode3&=~AO_Trigger_Length;\r
+       win_out(devpriv->ao_mode3,AO_Mode_3_Register);\r
+\r
+       if(cmd->stop_src==TRIG_NOW){\r
+               devpriv->ao_mode1|=AO_Continuous;\r
+       }else{\r
+               devpriv->ao_mode1&=~AO_Continuous;\r
+       }\r
+       win_out(devpriv->ao_mode1,AO_Mode_1_Register);\r
+       devpriv->ao_mode2&=~AO_BC_Initial_Load_Source;\r
+       win_out(devpriv->ao_mode2,AO_Mode_2_Register);\r
+       if(cmd->stop_src==TRIG_NOW){\r
+               win_out(0xff,AO_BC_Load_A_Register_High);\r
+               win_out(0xffff,AO_BC_Load_A_Register_Low);\r
+       }else{\r
+               win_out(0,AO_BC_Load_A_Register_High);\r
+               win_out(0,AO_BC_Load_A_Register_Low);\r
+       }\r
+       win_out(AO_BC_Load,AO_Command_1_Register);\r
+       devpriv->ao_mode2&=~AO_UC_Initial_Load_Source;\r
+       win_out(devpriv->ao_mode2,AO_Mode_2_Register);\r
+       if(cmd->stop_src==TRIG_NOW){\r
+               win_out(0xff,AO_UC_Load_A_Register_High);\r
+               win_out(0xffff,AO_UC_Load_A_Register_Low);\r
+               win_out(AO_UC_Load,AO_Command_1_Register);\r
+               win_out(0xff,AO_UC_Load_A_Register_High);\r
+               win_out(0xffff,AO_UC_Load_A_Register_Low);\r
+       }else{\r
+               win_out(0,AO_UC_Load_A_Register_High);\r
+               win_out(0,AO_UC_Load_A_Register_Low);\r
+               win_out(AO_UC_Load,AO_Command_1_Register);\r
+               win_out((cmd->stop_arg-1)>>16,AO_UC_Load_A_Register_High);\r
+               win_out((cmd->stop_arg-1)&0xffff,AO_UC_Load_A_Register_Low);\r
+       }\r
+\r
+       devpriv->ao_cmd2&=~AO_BC_Gate_Enable;\r
+       ni_writew(devpriv->ao_cmd2,AO_Command_2);\r
+       devpriv->ao_mode1&=~(AO_UI_Source_Select(0x1f)|AO_UI_Source_Polarity);\r
+       win_out(devpriv->ao_mode1,AO_Mode_1_Register);\r
+       devpriv->ao_mode2&=~(AO_UI_Reload_Mode(3)|AO_UI_Initial_Load_Source);\r
+       win_out(devpriv->ao_mode2,AO_Mode_2_Register);\r
+       win_out(0,AO_UI_Load_A_Register_High);\r
+       win_out(1,AO_UI_Load_A_Register_Low);\r
+       win_out(AO_UI_Load,AO_Command_1_Register);\r
+       win_out((trigvar>>16),AO_UI_Load_A_Register_High);\r
+       win_out((trigvar&0xffff),AO_UI_Load_A_Register_Low);\r
+\r
+       if(cmd->scan_end_arg>1){\r
+               devpriv->ao_mode1|=AO_Multiple_Channels;\r
+               win_out(AO_Number_Of_Channels(cmd->scan_end_arg-1)|\r
+                       AO_UPDATE_Output_Select(1),\r
+                       AO_Output_Control_Register);\r
+       }else{\r
+               devpriv->ao_mode1&=~AO_Multiple_Channels;\r
+               win_out(AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]))|\r
+                       AO_UPDATE_Output_Select(1),\r
+                       AO_Output_Control_Register);\r
+       }\r
+       win_out(devpriv->ao_mode1,AO_Mode_1_Register);\r
+\r
+       win_out(AO_DAC0_Update_Mode|AO_DAC1_Update_Mode,AO_Command_1_Register);\r
+\r
+       devpriv->ao_mode3|=AO_Stop_On_Overrun_Error;\r
+       win_out(devpriv->ao_mode3,AO_Mode_3_Register);\r
+\r
+devpriv->ao_mode2|=AO_FIFO_Mode(1);\r
+       devpriv->ao_mode2&=~AO_FIFO_Retransmit_Enable;\r
+       win_out(devpriv->ao_mode2,AO_Mode_2_Register);\r
+\r
+       win_out(AO_Configuration_End,Joint_Reset_Register);\r
+\r
+       win_out(devpriv->ao_mode3|AO_Not_An_UPDATE,AO_Mode_3_Register);\r
+       win_out(devpriv->ao_mode3,AO_Mode_3_Register);\r
+\r
+       /* wait for DACs to be loaded */\r
+       udelay(100);\r
+\r
+       win_out(devpriv->ao_cmd1|AO_UI_Arm|AO_UC_Arm|AO_BC_Arm|AO_DAC1_Update_Mode|AO_DAC0_Update_Mode,\r
+               AO_Command_1_Register);\r
+\r
+       //TIM 4/17/01 win_out(AO_FIFO_Interrupt_Enable|AO_Error_Interrupt_Enable,Interrupt_B_Enable_Register);\r
+       ni_set_bits(dev, Interrupt_B_Enable_Register,\r
+               AO_FIFO_Interrupt_Enable|AO_Error_Interrupt_Enable, 1);\r
+\r
+       ni_writew(devpriv->ao_cmd2|AO_START1_Pulse,AO_Command_2);\r
+       \r
+       return 0;\r
+}\r
+\r
+static int ni_ao_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)\r
+{\r
+       int err=0;\r
+       int tmp;\r
+\r
+       /* step 1: make sure trigger sources are trivially valid */\r
+\r
+       tmp=cmd->start_src;\r
+       cmd->start_src &= TRIG_NOW;\r
+       if(!cmd->start_src || tmp!=cmd->start_src)err++;\r
+\r
+       tmp=cmd->scan_begin_src;\r
+       cmd->scan_begin_src &= TRIG_TIMER;\r
+       if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;\r
+\r
+       tmp=cmd->convert_src;\r
+       cmd->convert_src &= TRIG_NOW;\r
+       if(!cmd->convert_src || tmp!=cmd->convert_src)err++;\r
+\r
+       tmp=cmd->scan_end_src;\r
+       cmd->scan_end_src &= TRIG_COUNT;\r
+       if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;\r
+\r
+       tmp=cmd->stop_src;\r
+       cmd->stop_src &= TRIG_COUNT|TRIG_NONE;\r
+       if(!cmd->stop_src || tmp!=cmd->stop_src)err++;\r
+\r
+       if(err)return 1;\r
+\r
+       /* step 2: make sure trigger sources are unique and mutually compatible */\r
+\r
+       if(cmd->stop_src!=TRIG_COUNT &&\r
+          cmd->stop_src!=TRIG_NONE)err++;\r
+\r
+       if(err)return 2;\r
+\r
+       /* step 3: make sure arguments are trivially compatible */\r
+\r
+       if(cmd->start_arg!=0){\r
+               cmd->start_arg=0;\r
+               err++;\r
+       }\r
+#if 0\r
+       /* XXX need ao_speed */\r
+       if(cmd->scan_begin_arg<boardtype.ao_speed){\r
+               cmd->scan_begin_arg=boardtype.ao_speed;\r
+               err++;\r
+       }\r
+#endif\r
+       if(cmd->scan_begin_arg>TIMER_BASE*0xffffff){ /* XXX check */\r
+               cmd->scan_begin_arg=TIMER_BASE*0xffffff;\r
+               err++;\r
+       }\r
+       if(cmd->convert_arg!=0){\r
+               cmd->convert_arg=0;\r
+               err++;\r
+       }\r
+       if(cmd->scan_end_arg!=cmd->chanlist_len){\r
+               cmd->scan_end_arg=cmd->chanlist_len;\r
+               err++;\r
+       }\r
+       if(cmd->stop_src==TRIG_COUNT){ /* XXX check */\r
+               if(cmd->stop_arg>0x00ffffff){\r
+                       cmd->stop_arg=0x00ffffff;\r
+                       err++;\r
+               }\r
+       }else{\r
+               /* TRIG_NONE */\r
+               if(cmd->stop_arg!=0){\r
+                       cmd->stop_arg=0;\r
+                       err++;\r
+               }\r
+       }\r
+\r
+       if(err)return 3;\r
+\r
+       /* step 4: fix up any arguments */\r
+\r
+       tmp = cmd->scan_begin_arg;\r
+       ni_ns_to_timer(&cmd->scan_begin_arg,cmd->flags&TRIG_ROUND_MASK);\r
+       if(tmp!=cmd->scan_begin_arg)err++;\r
+       \r
+       if(err)return 4;\r
+\r
+       return 0;\r
+}\r
+\r
+\r
+static int ni_dio_insn_config(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data)\r
+{\r
+#ifdef DEBUG_DIO\r
+       printk("ni_dio_insn_config() chan=%d io=%d\n",\r
+               CR_CHAN(insn->chanspec),data[0]);\r
+#endif\r
+       if(insn->n!=1)return -EINVAL;\r
+       switch(data[0]){\r
+       case COMEDI_OUTPUT:\r
+               s->io_bits |= 1<<CR_CHAN(insn->chanspec);\r
+               break;\r
+       case COMEDI_INPUT:\r
+               s->io_bits &= ~(1<<CR_CHAN(insn->chanspec));\r
+               break;\r
+       default:\r
+               return -EINVAL;\r
+       }\r
+\r
+       devpriv->dio_control &= ~DIO_Pins_Dir_Mask;\r
+       devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);\r
+       win_out(devpriv->dio_control,DIO_Control_Register);\r
+\r
+       return 1;\r
+}\r
+\r
+static int ni_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data)\r
+{\r
+#ifdef DEBUG_DIO\r
+       printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n",data[0],data[1]);\r
+#endif\r
+       if(insn->n!=2)return -EINVAL;\r
+       if(data[0]){\r
+               s->state &= ~data[0];\r
+               s->state |= (data[0]&data[1]);\r
+               devpriv->dio_output &= ~DIO_Parallel_Data_Mask;\r
+               devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);\r
+               win_out(devpriv->dio_output,DIO_Output_Register);\r
+       }\r
+       data[1] = ni_readw(DIO_Parallel_Input);\r
+\r
+       return 2;\r
+}\r
+\r
+static void mio_common_detach(comedi_device *dev)\r
+{\r
+       if(dev->subdevices && boardtype.has_8255)\r
+               subdev_8255_cleanup(dev,dev->subdevices+3);\r
+}\r
+\r
+static int ni_E_init(comedi_device *dev,comedi_devconfig *it)\r
+{\r
+       comedi_subdevice *s;\r
+       \r
+       dev->n_subdevices=7;\r
+       \r
+       if(alloc_subdevices(dev)<0)\r
+               return -ENOMEM;\r
+       \r
+       /* analog input subdevice */\r
+\r
+       s=dev->subdevices+0;\r
+       dev->read_subdev=s;\r
+       s->type=COMEDI_SUBD_AI;\r
+       s->subdev_flags=SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON|SDF_DIFF|SDF_OTHER;\r
+       s->subdev_flags|=SDF_DITHER;\r
+       s->n_chan=boardtype.n_adchan;\r
+       s->len_chanlist=512;\r
+       s->maxdata=(1<<boardtype.adbits)-1;\r
+       s->range_table=ni_range_lkup[boardtype.gainlkup];\r
+       s->insn_read=ni_ai_insn_read;\r
+       s->do_cmdtest=ni_ai_cmdtest;\r
+       s->do_cmd=ni_ai_cmd;\r
+       s->cancel=ni_ai_reset;\r
+       s->poll=ni_ai_poll;\r
+\r
+       /* analog output subdevice */\r
+\r
+       s=dev->subdevices+1;\r
+       if(boardtype.n_aochan){\r
+               dev->write_subdev=s;\r
+               s->type=COMEDI_SUBD_AO;\r
+               s->subdev_flags=SDF_WRITEABLE|SDF_RT|SDF_DEGLITCH|SDF_GROUND|SDF_OTHER;\r
+               s->n_chan=boardtype.n_aochan;\r
+               s->maxdata=(1<<boardtype.aobits)-1;\r
+               if(boardtype.ao_unipolar){\r
+                       s->range_table=&range_ni_E_ao_ext;      /* XXX wrong for some boards */\r
+               }else{\r
+                       s->range_table=&range_bipolar10;\r
+               }\r
+               s->insn_read=ni_ao_insn_read;\r
+               s->insn_write=ni_ao_insn_write;\r
+               s->do_cmd=ni_ao_cmd;\r
+               s->do_cmdtest=ni_ao_cmdtest;\r
+               s->len_chanlist = 2;\r
+       }else{\r
+               s->type=COMEDI_SUBD_UNUSED;\r
+       }\r
+       \r
+       /* digital i/o subdevice */\r
+       \r
+       s=dev->subdevices+2;\r
+       s->type=COMEDI_SUBD_DIO;\r
+       s->subdev_flags=SDF_WRITEABLE|SDF_READABLE|SDF_RT;\r
+       s->n_chan=8;\r
+       s->maxdata=1;\r
+       s->range_table=&range_digital;\r
+       s->io_bits=0;           /* all bits input */\r
+       s->insn_bits=ni_dio_insn_bits;\r
+       s->insn_config=ni_dio_insn_config;\r
+\r
+       /* dio setup */\r
+       devpriv->dio_control = DIO_Pins_Dir(s->io_bits);\r
+       win_out(devpriv->dio_control,DIO_Control_Register);\r
+       \r
+       /* 8255 device */\r
+       s=dev->subdevices+3;\r
+       if(boardtype.has_8255){\r
+               subdev_8255_init(dev,s,ni_8255_callback,dev);\r
+       }else{\r
+               s->type=COMEDI_SUBD_UNUSED;\r
+       }\r
+       /* XXX */\r
+       \r
+       /* general purpose counter/timer device */\r
+       s=dev->subdevices+4;\r
+       s->type=COMEDI_SUBD_COUNTER;\r
+       s->subdev_flags=SDF_READABLE|SDF_WRITEABLE;\r
+       s->insn_read=ni_gpct_insn_read;\r
+       s->insn_config=ni_gpct_insn_config;\r
+       s->n_chan=1; /* XXX */\r
+       s->maxdata=1;\r
+       \r
+       s=dev->subdevices+4;\r
+       s->type=COMEDI_SUBD_COUNTER;\r
+       s->subdev_flags=SDF_READABLE|SDF_WRITEABLE;\r
+       s->insn_read=  ni_gpct_insn_read;\r
+       s->insn_write= ni_gpct_insn_write;\r
+       s->insn_config=ni_gpct_insn_config;\r
+       s->n_chan=2;\r
+       s->maxdata=1;\r
+       devpriv->an_trig_etc_reg = 0;\r
+       GPCT_Reset(dev,0);\r
+       GPCT_Reset(dev,1);\r
+       \r
+       /* calibration subdevice -- ai and ao */\r
+       s=dev->subdevices+5;\r
+       s->type=COMEDI_SUBD_CALIB;\r
+       s->subdev_flags=SDF_WRITEABLE|SDF_INTERNAL;\r
+       caldac_setup(dev,s);\r
+       s->insn_read=ni_calib_insn_read;\r
+       s->insn_write=ni_calib_insn_write;\r
+       \r
+       /* EEPROM */\r
+       s=dev->subdevices+6;\r
+       s->type=COMEDI_SUBD_MEMORY;\r
+       s->subdev_flags=SDF_READABLE|SDF_INTERNAL;\r
+       s->n_chan=512;\r
+       s->maxdata=0xff;\r
+       s->insn_read=ni_eeprom_insn_read;\r
+       \r
+       /* ai configuration */\r
+       ni_ai_reset(dev,dev->subdevices+0);\r
+       win_out(0x1ba0,Clock_and_FOUT_Register);\r
+\r
+\r
+       /* analog output configuration */\r
+       \r
+       devpriv->ao0p=0x0000;\r
+       ni_writew(devpriv->ao0p,AO_Configuration);\r
+       devpriv->ao1p=0x0100;\r
+       ni_writew(devpriv->ao1p,AO_Configuration);\r
+       win_out(AO_Configuration_Start,Joint_Reset_Register);\r
+       win_out(AO_Disarm,AO_Command_1_Register);\r
+       win_out(0,Interrupt_B_Enable_Register);\r
+       win_out(0x0010,AO_Personal_Register);\r
+       ni_writew(0x3f98,Interrupt_B_Ack);\r
+       win_out(0x1430,AO_Personal_Register);\r
+       win_out(0,AO_Output_Control_Register);\r
+       win_out(0,AO_Start_Select_Register);\r
+       devpriv->ao_cmd1=0;\r
+       win_out(devpriv->ao_cmd1,AO_Command_1_Register);\r
+       devpriv->ao_cmd2=0;\r
+       devpriv->ao_mode1=0;\r
+       devpriv->ao_mode2=0;\r
+       devpriv->ao_mode3=0;\r
+       devpriv->ao_trigger_select=0;\r
+\r
+        if(dev->irq){\r
+                win_out((IRQ_POLARITY<<0) |  /* polarity : active high */\r
+                        (0<<1) |  /* no interrupt on 3 pins */\r
+                        (1<<11) |  /* enable int A */\r
+                        (1<<15) |  /* enable int B */\r
+                        (interrupt_pin(dev->irq)<<8) |  /* interrupt output pin A */\r
+                        (interrupt_pin(dev->irq)<<12) ,  /* interrupt output pin B */\r
+                        Interrupt_Control_Register\r
+                );\r
+        }\r
+\r
+       pfi_setup(dev);\r
+\r
+       printk("\n");\r
+\r
+       return 0;\r
+}\r
+\r
+\r
+\r
+\r
+/*\r
+       presents the EEPROM as a subdevice\r
+*/\r
+\r
+static int ni_eeprom_insn_read(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data)\r
+{\r
+       data[0]=ni_read_eeprom(dev,CR_CHAN(insn->chanspec));\r
+\r
+       return 1;\r
+}\r
+\r
+/*\r
+       reads bytes out of eeprom\r
+*/\r
+\r
+static int ni_read_eeprom(comedi_device *dev,int addr)\r
+{\r
+       int bit;\r
+       int bitstring;\r
+\r
+       bitstring=0x0300|((addr&0x100)<<3)|(addr&0xff);\r
+       ni_writeb_p(0x04,Serial_Command);\r
+       for(bit=0x8000;bit;bit>>=1){\r
+               ni_writeb_p(0x04|((bit&bitstring)?0x02:0),Serial_Command);\r
+               ni_writeb_p(0x05|((bit&bitstring)?0x02:0),Serial_Command);\r
+       }\r
+       bitstring=0;\r
+       for(bit=0x80;bit;bit>>=1){\r
+               ni_writeb_p(0x04,Serial_Command);\r
+               ni_writeb_p(0x05,Serial_Command);\r
+               bitstring|=((ni_readb_p(XXX_Status)&0x01)?bit:0);\r
+       }\r
+       ni_writeb_p(0x00,Serial_Command);\r
+       \r
+       return bitstring;\r
+}\r
+\r
+static void ni_write_caldac(comedi_device *dev,int addr,int val);\r
+/*\r
+       calibration subdevice\r
+*/\r
+static int ni_calib_insn_write(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data)\r
+{\r
+       ni_write_caldac(dev,CR_CHAN(insn->chanspec),data[0]);\r
+       devpriv->caldacs[CR_CHAN(insn->chanspec)] = data[0];\r
+\r
+       return 1;\r
+}\r
+\r
+static int ni_calib_insn_read(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data)\r
+{\r
+       data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];\r
+\r
+       return 1;\r
+}\r
+\r
+static int pack_mb88341(int addr,int val,int *bitstring);\r
+static int pack_dac8800(int addr,int val,int *bitstring);\r
+static int pack_dac8043(int addr,int val,int *bitstring);\r
+#ifdef PCIMIO\r
+static int pack_ad8522(int addr,int val,int *bitstring);\r
+#endif\r
+\r
+struct caldac_struct{\r
+       int n_chans;\r
+       int n_bits;\r
+       int (*packbits)(int,int,int *);\r
+};\r
+\r
+static struct caldac_struct caldac_mb88341={ 12, 8, pack_mb88341 };\r
+static struct caldac_struct caldac_dac8800={ 8, 8, pack_dac8800 };\r
+static struct caldac_struct caldac_dac8043={ 1, 12, pack_dac8043 };\r
+#ifdef PCIMIO\r
+static struct caldac_struct caldac_ad8522={ 2, 12, pack_ad8522 };\r
+#endif\r
+\r
+\r
+static void caldac_setup(comedi_device *dev,comedi_subdevice *s)\r
+{\r
+       int i,j;\r
+       int n_dacs;\r
+       int n_chans=0;\r
+       int n_bits;\r
+       int diffbits=0;\r
+       \r
+       if(!boardtype.caldac[0])return;\r
+       n_bits=boardtype.caldac[0]->n_bits;\r
+       for(i=0;i<3;i++){\r
+               if(!boardtype.caldac[i])break;\r
+               if(boardtype.caldac[i]->n_bits!=n_bits)diffbits=1;\r
+               n_chans+=boardtype.caldac[i]->n_chans;\r
+       }\r
+       n_dacs=i;\r
+       s->n_chan=n_chans;\r
+\r
+       if(diffbits){\r
+               int chan;\r
+\r
+               s->maxdata_list=kmalloc(sizeof(int)*n_chans,GFP_KERNEL);\r
+               chan=0;\r
+               for(i=0;i<n_dacs;i++){\r
+                       for(j=0;j<boardtype.caldac[i]->n_chans;j++){\r
+                               s->maxdata_list[chan]=\r
+                                       (1<<boardtype.caldac[i]->n_bits)-1;\r
+                               chan++;\r
+                       }\r
+               }\r
+       }else{\r
+               s->maxdata=(1<<boardtype.caldac[0]->n_bits)-1;\r
+       }\r
+}\r
+\r
+static void ni_write_caldac(comedi_device *dev,int addr,int val)\r
+{\r
+       int loadbit=0,bits=0,bit,bitstring=0;\r
+       int i;\r
+       \r
+       for(i=0;i<3;i++){\r
+               if(!boardtype.caldac[i])return;\r
+               if(addr<boardtype.caldac[i]->n_chans){\r
+                       bits=boardtype.caldac[i]->packbits(addr,val,&bitstring);\r
+                       loadbit=SerDacLd(i);\r
+                       break;\r
+               }\r
+               addr-=boardtype.caldac[i]->n_chans;\r
+       }\r
+\r
+       for(bit=1<<(bits-1);bit;bit>>=1){\r
+               ni_writeb(((bit&bitstring)?0x02:0),Serial_Command);\r
+               ni_writeb(1|((bit&bitstring)?0x02:0),Serial_Command);\r
+       }\r
+       ni_writeb(loadbit,Serial_Command);\r
+       ni_writeb(0,Serial_Command);\r
+}\r
+\r
+\r
+\r
+static int pack_mb88341(int addr,int val,int *bitstring)\r
+{\r
+       /*\r
+          Fujitsu MB 88341\r
+          Note that address bits are reversed.  Thanks to\r
+          Ingo Keen for noticing this.\r
+\r
+          Note also that the 88341 expects address values from\r
+          1-12, whereas we use channel numbers 0-11.  The NI\r
+          docs use 1-12, also, so be careful here.\r
+       */\r
+       addr++;\r
+       *bitstring=((addr&0x1)<<11) |\r
+                 ((addr&0x2)<<9)  |\r
+                 ((addr&0x4)<<7)  |\r
+                 ((addr&0x8)<<5)  |\r
+                 (val&0xff);\r
+       return 12;\r
+}\r
+\r
+static int pack_dac8800(int addr,int val,int *bitstring)\r
+{\r
+       *bitstring=((addr&0x7)<<8)|(val&0xff);\r
+       return 11;\r
+}\r
+\r
+static int pack_dac8043(int addr,int val,int *bitstring)\r
+{\r
+       *bitstring=val&0xfff;\r
+       return 12;\r
+}\r
+       \r
+#ifdef PCIMIO\r
+static int pack_ad8522(int addr,int val,int *bitstring)\r
+{\r
+       *bitstring=(val&0xfff)|(addr ? 0xc000:0xa000);\r
+       return 16;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*\r
+ *\r
+ *  Programmable Function Inputs\r
+ *\r
+ */\r
+\r
+\r
+static void pfi_setup(comedi_device *dev)\r
+{\r
+       /* currently, we don't output any signals, thus, all\r
+          the PFI's are input */\r
+       \r
+       //TIM 4/17/01 win_out(0,IO_Bidirection_Pin_Register);\r
+       ni_set_bits(dev, IO_Bidirection_Pin_Register, 0x03ff, 0);\r
+}\r
+\r
+\r
+\r
+/*\r
+ *\r
+ *  General Purpose Counter/Timer section\r
+ *\r
+ */\r
+\r
+/*\r
+*   Low level stuff...Each STC counter has two 24 bit load registers (A&B).  Just make\r
+* it easier to access them.\r
+*/\r
+static void GPCT_Load_A(comedi_device *dev, int chan, long value)\r
+{\r
+       win_out( (value>>16) & 0x00ff, G_Load_A_Register_High(chan));\r
+       win_out( value & 0xffff, G_Load_A_Register_Low(chan));\r
+}\r
+\r
+static void GPCT_Load_B(comedi_device *dev, int chan, long value)\r
+{\r
+       win_out( (value>>16) & 0x00ff, G_Load_B_Register_High(chan));\r
+       win_out( value & 0xffff, G_Load_B_Register_Low(chan));\r
+}\r
+\r
+/*  Load a value into the counter, using register A as the intermediate step.\r
+*  You might use GPCT_Load_Using_A to load a 0x000000 into a counter\r
+*  reset its value.\r
+*/\r
+static void GPCT_Load_Using_A(comedi_device *dev, int chan, long value)\r
+{\r
+       devpriv->gpct_mode[chan] &= (~G_Load_Source_Select);\r
+       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));\r
+       GPCT_Load_A(dev,chan,value);\r
+       win_out( devpriv->gpct_command[chan]|G_Load,G_Command_Register(chan));\r
+}\r
+\r
+/*     Don't use this by itself!  The read is not atomic and quite unsafe.\r
+*      If you think you need this function, use GPCT_G_Watch instead.\r
+*/\r
+int inline GPCT_G_Read(comedi_device *dev, int chan)\r
+{\r
+       int tmp;\r
+       tmp = win_in( G_Save_Register_High(chan)) << 16;\r
+       tmp |= win_in(G_Save_Register_Low(chan));\r
+       return tmp;\r
+}\r
+\r
+/*\r
+*      Read the GPCTs current value.  \r
+*      This function is actually straight out of the STC RLPM.\r
+*/\r
+int GPCT_G_Watch(comedi_device *dev, int chan)\r
+{\r
+       int save1,save2;\r
+       \r
+       devpriv->gpct_command[chan] &= ~G_Save_Trace;\r
+       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));\r
+       \r
+       devpriv->gpct_command[chan] |= G_Save_Trace;\r
+       win_out( devpriv->gpct_command[chan], G_Command_Register(chan));\r
+\r
+       save1 = GPCT_G_Read(dev,chan);\r
+       save2 = GPCT_G_Read(dev,chan);\r
+       \r
+       /*if the value changed during the read, try again*/\r
+       if (save1 != save2) {\r
+               save1 = GPCT_G_Read(dev,chan);\r
+       }\r
+       return save1;\r
+}\r
+\r
+\r
+int GPCT_Disarm(comedi_device *dev, int chan)\r
+{\r
+       win_out( devpriv->gpct_command[chan] | G_Disarm,G_Command_Register(chan));\r
+       return 0;\r
+}\r
+\r
+\r
+int GPCT_Arm(comedi_device *dev, int chan)\r
+{\r
+       win_out( devpriv->gpct_command[chan] | G_Arm,G_Command_Register(chan));\r
+       /* If the counter is doing pulse width measurement, then make\r
+        sure that the counter did not start counting right away.  This would\r
+        indicate that we started acquiring the pulse after it had already \r
+        started and our measurement would be inaccurate */\r
+       if(devpriv->gpct_cur_operation[chan] == GPCT_SINGLE_PW){\r
+               int g_status; \r
+\r
+               g_status=win_in(G_Status_Register);\r
+               \r
+               if(chan == 0){\r
+                       //TIM 5/2/01 possible error with very short pulses\r
+                       if((G0_Counting_St & g_status)|| !(G0_Armed_St&g_status)) {\r
+                               //error: we missed the beginning of the pulse\r
+                               return -EINVAL; //there is probably a more accurate error code...\r
+                       }\r
+               }else{\r
+                       if((G1_Counting_St & g_status)|| !(G1_Armed_St&g_status)) {\r
+                               //error: we missed the beginning of the pulse\r
+                               return -EINVAL;\r
+                       }\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+\r
+int GPCT_Set_Source(comedi_device *dev,int chan ,int source)\r
+{\r
+       //printk("GPCT_Set_Source...");\r
+       devpriv->gpct_input_select[chan] &= ~G_Source_Select(0x1f);//reset gate to 0\r
+       switch(source) {\r
+               case GPCT_INT_CLOCK:\r
+               devpriv->gpct_input_select[chan] |= G_Source_Select(0);//INT_TIMEBASE\r
+               break;\r
+       case GPCT_EXT_PIN:\r
+               if(chan==0)\r
+                       devpriv->gpct_input_select[chan] |= G_Source_Select(9);//PFI8\r
+               else\r
+                       devpriv->gpct_input_select[chan] |= G_Source_Select(4);//PFI3\r
+               break;\r
+       default:\r
+               return -EINVAL;\r
+       }\r
+       win_out(devpriv->gpct_input_select[chan], G_Input_Select_Register(chan));\r
+       //printk("exit GPCT_Set_Source\n");\r
+       return 0;\r
+}\r
+\r
+int GPCT_Set_Gate(comedi_device *dev,int chan ,int gate)\r
+{\r
+       //printk("GPCT_Set_Gate...");\r
+       devpriv->gpct_input_select[chan] &= ~G_Gate_Select(0x1f);//reset gate to 0\r
+       switch(gate) {\r
+       case GPCT_NO_GATE:\r
+               devpriv->gpct_input_select[chan] |= G_Gate_Select(31);//Low\r
+               devpriv->gpct_mode[chan] |= G_Gate_Polarity;\r
+               break;\r
+       case GPCT_EXT_PIN:\r
+               devpriv->gpct_mode[chan] &= ~G_Gate_Polarity;\r
+               if(chan==0){\r
+                       devpriv->gpct_input_select[chan] |= G_Gate_Select(10);//PFI9\r
+               }else{\r
+                       devpriv->gpct_input_select[chan] |= G_Gate_Select(5);//PFI4\r
+               }\r
+               break;\r
+       default:\r
+               return -EINVAL;\r
+       }\r
+       win_out(devpriv->gpct_input_select[chan], G_Input_Select_Register(chan));\r
+       win_out(devpriv->gpct_mode[chan], G_Mode_Register(chan));\r
+       //printk("exit GPCT_Set_Gate\n");\r
+       return 0;\r
+}\r
+\r
+int GPCT_Set_Direction(comedi_device *dev,int chan,int direction)\r
+{\r
+       //printk("GPCT_Set_Direction...");\r
+       \r
+       devpriv->gpct_command[chan] &= ~G_Up_Down(0x3);\r
+       switch (direction) {\r
+               case GPCT_UP:\r
+                       devpriv->gpct_command[chan] |= G_Up_Down(1);\r
+                       break;\r
+               case GPCT_DOWN:\r
+                       devpriv->gpct_command[chan] |= G_Up_Down(0);\r
+                       break;\r
+               case GPCT_HWUD:\r
+                       devpriv->gpct_command[chan] |= G_Up_Down(2);\r
+                       break;\r
+               default:\r
+                       printk("Error direction=0x%08x..",direction);\r
+                       return -EINVAL;\r
+       }\r
+       win_out(devpriv->gpct_command[chan], G_Command_Register(chan));\r
+       //TIM 4/23/01 win_out(devpriv->gpct_mode[chan], G_Mode_Register(chan));\r
+       //printk("exit GPCT_Set_Direction\n");\r
+       return 0;\r
+}\r
+\r
+void GPCT_Event_Counting(comedi_device *dev,int chan)\r
+{\r
+\r
+       //NOTE: possible residual bits from multibit masks can corrupt\r
+       //If you config for several measurements between Resets, watch out!\r
+       \r
+       //printk("GPCT_Event_Counting...");\r
+       \r
+       devpriv->gpct_cur_operation[chan] = GPCT_SIMPLE_EVENT;\r
+       \r
+       // Gating_Mode = 1\r
+       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Gating_Mode(1);\r
+       \r
+       // Trigger_Mode_For_Edge_Gate = 1\r
+       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);\r
+\r
+       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));\r
+       //printk("exit GPCT_Event_Counting\n");\r
+}\r
+\r
+void GPCT_Period_Meas(comedi_device *dev, int chan)\r
+{\r
+       //printk("GPCT_Period_Meas...");\r
+       \r
+       devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PERIOD;\r
+\r
+       \r
+       //NOTE: possible residual bits from multibit masks can corrupt\r
+       //If you config for several measurements between Resets, watch out!     \r
+       devpriv->gpct_mode[chan] &= ~G_OR_Gate;\r
+       devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;\r
+       \r
+       // Output_Mode = 3 \r
+       devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Output_Mode(3);\r
+       \r
+       \r
+       //Gating Mode=2\r
+       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Gating_Mode(2);\r
+       \r
+       // Trigger_Mode_For_Edge_Gate=0\r
+       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(0);\r
+\r
+       devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;\r
+       devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;\r
+       devpriv->gpct_mode[chan] &= ~G_Loading_On_TC;\r
+       devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;\r
+\r
+       // Stop_Mode = 2\r
+       devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Stop_Mode(0);\r
+       \r
+       // Counting_Once = 2 \r
+       devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Counting_Once(2);\r
+\r
+       // Up_Down = 1 \r
+       devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));\r
+       devpriv->gpct_command[chan] |= G_Up_Down(1);\r
+\r
+       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));\r
+       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));\r
+       //printk("exit GPCT_Period_Meas\n");\r
+}\r
+\r
+void GPCT_Pulse_Width_Meas(comedi_device *dev, int chan)\r
+{\r
+       //printk("GPCT_Pulse_Width_Meas...");\r
+\r
+       devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PW;\r
+\r
+       devpriv->gpct_mode[chan] &= ~G_OR_Gate;\r
+       devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;\r
+\r
+       // Output_Mode = 3 \r
+       devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Output_Mode(3);\r
+       \r
+       //Gating Mode=1\r
+       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Gating_Mode(1);//TIM 4/24/01 was 2\r
+       \r
+       // Trigger_Mode_For_Edge_Gate=2\r
+       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);//TIM 4/24/01 was 0\r
+\r
+\r
+       devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;//TIM 4/24/01 was 1\r
+       devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;//TIM 4/24/01 was 0\r
+\r
+       devpriv->gpct_mode[chan] &= ~G_Loading_On_TC;\r
+       devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;\r
+\r
+       // Stop_Mode = 0\r
+       devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Stop_Mode(0);\r
+       \r
+       // Counting_Once = 2 \r
+       devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Counting_Once(2);\r
+\r
+       // Up_Down = 1 \r
+       devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));\r
+       devpriv->gpct_command[chan] |= G_Up_Down(1);\r
+\r
+       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));\r
+       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));\r
+\r
+       //printk("exit GPCT_Pulse_Width_Meas\n");\r
+}\r
+\r
+/* GPCT_Gen_Single_Pulse() creates pulse of length pulsewidth which starts after the Arm\r
+signal is sent.  The pulse is delayed by the value already in the counter.  This function could\r
+be modified to send a pulse in response to a trigger event at its gate.*/\r
+void GPCT_Gen_Single_Pulse(comedi_device *dev, int chan, unsigned int length)\r
+{\r
+       //printk("GPCT_Gen_Cont...");\r
+\r
+       devpriv->gpct_cur_operation[chan] = GPCT_SINGLE_PULSE_OUT;\r
+\r
+       // Set length of the pulse\r
+       GPCT_Load_B(dev,chan, length-1);\r
+\r
+       //Load next time using B, This is reset by GPCT_Load_Using_A()\r
+       devpriv->gpct_mode[chan] |= G_Load_Source_Select;\r
+       \r
+       devpriv->gpct_mode[chan] &= ~G_OR_Gate;\r
+       devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;\r
+\r
+       // Output_Mode = 3 \r
+       devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Output_Mode(2); //TIM 4/26/01 was 3\r
+       \r
+       //Gating Mode=0 for untriggered single pulse\r
+       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Gating_Mode(0); //TIM 4/25/01 was 1\r
+       \r
+       // Trigger_Mode_For_Edge_Gate=0\r
+       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);\r
+\r
+\r
+       devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;\r
+       devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;\r
+       devpriv->gpct_mode[chan] |= G_Loading_On_TC; //TIM 4/25/01\r
+       devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;\r
+\r
+       // Stop_Mode = 2\r
+       devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Stop_Mode(2); //TIM 4/25/01\r
+       \r
+       // Counting_Once = 2 \r
+       devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Counting_Once(1); //TIM 4/25/01\r
+\r
+       // Up_Down = 1 \r
+       devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));\r
+       devpriv->gpct_command[chan] |= G_Up_Down(0); //TIM 4/25/01 was 1\r
+\r
+       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));\r
+       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));\r
+\r
+       //printk("exit GPCT_Gen_Cont\n");\r
+}\r
+\r
+void GPCT_Gen_Cont_Pulse(comedi_device *dev, int chan, unsigned int length)\r
+{\r
+       //printk("GPCT_Gen_Cont...");\r
+\r
+       devpriv->gpct_cur_operation[chan] = GPCT_CONT_PULSE_OUT;\r
+\r
+       // Set length of the pulse\r
+       GPCT_Load_B(dev,chan, length-1);\r
+\r
+       //Load next time using B, This is reset by GPCT_Load_Using_A()\r
+       devpriv->gpct_mode[chan] |= G_Load_Source_Select;\r
+       \r
+       devpriv->gpct_mode[chan] &= ~G_OR_Gate;\r
+       devpriv->gpct_mode[chan] &= ~G_Gate_Select_Load_Source;\r
+\r
+       // Output_Mode = 3 \r
+       devpriv->gpct_mode[chan] &= ~(G_Output_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Output_Mode(2); //TIM 4/26/01 was 3\r
+       \r
+       //Gating Mode=0 for untriggered single pulse\r
+       devpriv->gpct_mode[chan] &= ~(G_Gating_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Gating_Mode(0); //TIM 4/26/01 was 0\r
+       \r
+       // Trigger_Mode_For_Edge_Gate=0\r
+       devpriv->gpct_mode[chan] &= ~(G_Trigger_Mode_For_Edge_Gate(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Trigger_Mode_For_Edge_Gate(2);\r
+\r
+\r
+       devpriv->gpct_mode[chan] |= G_Reload_Source_Switching;\r
+       devpriv->gpct_mode[chan] &= ~G_Loading_On_Gate;\r
+       devpriv->gpct_mode[chan] |= G_Loading_On_TC; \r
+       devpriv->gpct_mode[chan] &= ~G_Gate_On_Both_Edges;\r
+\r
+       // Stop_Mode = 2\r
+       devpriv->gpct_mode[chan] &= ~(G_Stop_Mode(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Stop_Mode(0); //TIM 4/26/01\r
+       \r
+       // Counting_Once = 2 \r
+       devpriv->gpct_mode[chan] &= ~(G_Counting_Once(0x3));\r
+       devpriv->gpct_mode[chan] |= G_Counting_Once(0); //TIM 4/26/01\r
+\r
+       // Up_Down = 1 \r
+       devpriv->gpct_command[chan] &= ~(G_Up_Down(0x3));\r
+       devpriv->gpct_command[chan] |= G_Up_Down(0); \r
+\r
+       //TIM 4/26/01\r
+       //This seems pretty unsafe since I don't think it is cleared anywhere.\r
+       //I don't think this is working\r
+       //devpriv->gpct_command[chan] &= ~G_Bank_Switch_Enable;\r
+       //devpriv->gpct_command[chan] &= ~G_Bank_Switch_Mode;\r
+       \r
+\r
+       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));\r
+       win_out( devpriv->gpct_command[chan],G_Command_Register(chan));\r
+\r
+       //printk("exit GPCT_Gen_Cont\n");\r
+}\r
+\r
+void GPCT_Reset(comedi_device *dev, int chan)\r
+{\r
+       unsigned long irqflags;\r
+       int temp_ack_reg=0;\r
+       \r
+       //printk("GPCT_Reset...");\r
+       devpriv->gpct_cur_operation[chan] = GPCT_RESET;\r
+\r
+       switch (chan) {\r
+               case 0:\r
+                       //note: I need to share the soft copies of the Enable Register with the ISRs.\r
+                       // so I'm using comedi_spin_lock_irqsave() to guard this section of code\r
+                       win_out(G0_Reset,Joint_Reset_Register);\r
+                       comedi_spin_lock_irqsave(&dev->spinlock, irqflags);\r
+                       ni_set_bits(dev,Interrupt_A_Enable_Register,G0_TC_Interrupt_Enable,  0);\r
+                       ni_set_bits(dev,Interrupt_A_Enable_Register,G0_Gate_Interrupt_Enable,0);\r
+                       comedi_spin_unlock_irqrestore(&dev->spinlock, irqflags);\r
+                       temp_ack_reg |= G0_Gate_Error_Confirm;\r
+                       temp_ack_reg |= G0_TC_Error_Confirm;\r
+                       temp_ack_reg |= G0_TC_Interrupt_Ack;\r
+                       temp_ack_reg |= G0_Gate_Interrupt_Ack;\r
+                       win_out(temp_ack_reg,Interrupt_A_Ack_Register);\r
+               \r
+                       //problem...this interferes with the other ctr...\r
+                       devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;\r
+                       win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);\r
+                       break;\r
+               case 1:\r
+                       win_out(G1_Reset,Joint_Reset_Register);\r
+                       comedi_spin_lock_irqsave(&dev->spinlock, irqflags);\r
+                       ni_set_bits(dev,Interrupt_B_Enable_Register,G1_TC_Interrupt_Enable,  0);\r
+                       ni_set_bits(dev,Interrupt_B_Enable_Register,G0_Gate_Interrupt_Enable,0);\r
+                       comedi_spin_unlock_irqrestore(&dev->spinlock, irqflags);\r
+                       temp_ack_reg |= G1_Gate_Error_Confirm;\r
+                       temp_ack_reg |= G1_TC_Error_Confirm;\r
+                       temp_ack_reg |= G1_TC_Interrupt_Ack;\r
+                       temp_ack_reg |= G1_Gate_Interrupt_Ack;\r
+                       win_out(temp_ack_reg,Interrupt_B_Ack_Register);\r
+               \r
+                       devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;\r
+                       win_out(devpriv->an_trig_etc_reg, Analog_Trigger_Etc_Register);\r
+                       break;\r
+       };\r
+       \r
+       devpriv->gpct_mode[chan] = 0;\r
+       devpriv->gpct_input_select[chan] = 0;\r
+       devpriv->gpct_command[chan] = 0;\r
+       \r
+       devpriv->gpct_command[chan] |= G_Synchronized_Gate;\r
+       \r
+       win_out( devpriv->gpct_mode[chan],G_Mode_Register(chan));\r
+       win_out( devpriv->gpct_input_select[chan],G_Input_Select_Register(chan));\r
+       win_out( 0,G_Autoincrement_Register(chan)); \r
+               \r
+       //printk("exit GPCT_Reset\n");\r
+}\r
+\r
+static int ni_gpct_insn_config(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data)\r
+{\r
+       int retval=0;\r
+       //printk("data[0] is 0x%08x, data[1] is 0x%08x\n",data[0],data[1]);\r
+       switch(data[0]){\r
+       case GPCT_RESET:\r
+               if(insn->n!=1)return -EINVAL;\r
+               GPCT_Reset(dev,insn->chanspec);\r
+               break;\r
+       case GPCT_SET_SOURCE:\r
+               if(insn->n!=2)return -EINVAL;\r
+               retval=GPCT_Set_Source(dev,insn->chanspec,data[1]);\r
+               break;\r
+       case GPCT_SET_GATE:\r
+               if(insn->n!=2)return -EINVAL;\r
+               retval=GPCT_Set_Gate(dev,insn->chanspec,data[1]);\r
+               break;\r
+       case GPCT_SET_DIRECTION:\r
+               if(insn->n!=2) return -EINVAL;\r
+               retval=GPCT_Set_Direction(dev,insn->chanspec,data[1]);\r
+               break;\r
+       case GPCT_GET_INT_CLK_FRQ:\r
+               if(insn->n!=2) return -EINVAL;\r
+               //There are actually 2 internal clocks on the STC, we always\r
+               //use the fast 20MHz one at this time.  Tim  Ousley 5/1/01\r
+               //NOTE: This is not the final interface, ideally the user\r
+               //will never need to know the int. clk. freq.\r
+               data[1]=50;//50ns = 20MHz = internal timebase of STC\r
+               break;\r
+       case GPCT_SET_OPERATION:\r
+               //TIM 5/1/01 if((insn->n<2)||(insn->n>3))return -EINVAL;\r
+               switch(data[1]){\r
+                       case GPCT_SIMPLE_EVENT:\r
+                               GPCT_Event_Counting(dev,insn->chanspec);\r
+                               break;\r
+                       case GPCT_SINGLE_PERIOD:\r
+                               GPCT_Period_Meas(dev,insn->chanspec);\r
+                               break;\r
+                       case GPCT_SINGLE_PW:\r
+                               GPCT_Pulse_Width_Meas(dev,insn->chanspec);\r
+                               break;\r
+                       case GPCT_SINGLE_PULSE_OUT:\r
+                               GPCT_Gen_Single_Pulse(dev,insn->chanspec,data[2]);\r
+                               break;\r
+                       case GPCT_CONT_PULSE_OUT:\r
+                               GPCT_Gen_Cont_Pulse(dev,insn->chanspec,data[2]);\r
+                               break;\r
+                       default:\r
+                               printk("unsupported GPCT operation!\n");\r
+                               return -EINVAL;\r
+               }\r
+               break;\r
+       case GPCT_ARM:\r
+               if(insn->n!=1)return -EINVAL;\r
+               retval=GPCT_Arm(dev,insn->chanspec);\r
+               break;\r
+       case GPCT_DISARM:\r
+               if(insn->n!=1)return -EINVAL;\r
+               retval=GPCT_Disarm(dev,insn->chanspec);\r
+               break;\r
+       default:\r
+               return -EINVAL;\r
+       }\r
+\r
+       //catch any errors from return values\r
+       if(retval==0){\r
+               return insn->n;\r
+       }else{\r
+               if(data[0]!=GPCT_ARM){ \r
+                       printk("error: retval was %d\n",retval);\r
+                       printk("data[0] is 0x%08x, data[1] is 0x%08x\n",data[0],data[1]);\r
+               }\r
+\r
+               return retval;\r
+       }\r
+}\r
+\r
+static int ni_gpct_insn_read(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data) {\r
+\r
+       int chan=insn->chanspec;\r
+       int cur_op = devpriv->gpct_cur_operation[chan];\r
+               \r
+       //printk("in ni_gpct_insn_read, n=%d, data[0]=%d\n",insn->chanspec,data[0]);\r
+       if(insn->n!=1)return -EINVAL;\r
+               \r
+       data[0] = GPCT_G_Watch(dev,insn->chanspec);\r
+               \r
+       /* for certain modes (period and pulse width measurment), the value\r
+       in the counter is not valid until the counter stops.  If the value is \r
+       invalid, return a 0 */\r
+       if((cur_op == GPCT_SINGLE_PERIOD) || (cur_op == GPCT_SINGLE_PW)){\r
+               /* is the counter still running? */\r
+               if(win_in(G_Status_Register) & (chan?G1_Counting_St:G0_Counting_St))\r
+                       data[0]=0;\r
+       }\r
+       return 1;\r
+}\r
+\r
+static int ni_gpct_insn_write(comedi_device *dev,comedi_subdevice *s,\r
+       comedi_insn *insn,lsampl_t *data) {\r
+\r
+       //printk("in ni_gpct_insn_write");\r
+       if(insn->n!=1)return -EINVAL;\r
+       GPCT_Load_Using_A(dev,insn->chanspec,data[0]);\r
+       return 1;\r
+}\r
+\r
+\r
+static int ni_8255_callback(int dir,int port,int data,void *arg)\r
+{\r
+       comedi_device *dev=arg;\r
+\r
+       if(dir){\r
+               ni_writeb(data,Port_A+2*port);\r
+               return 0;\r
+       }else{\r
+               return ni_readb(Port_A+2*port);\r
+       }\r
+}\r
index 911b25fb02b90eb569caa8fae12727642a9f487e..e69e1e1b1f05b54b00457efb9605ec162688ed5d 100644 (file)
@@ -44,8 +44,8 @@
 #include <linux/rtl.h>
 #endif
 #include <linux/comedidev.h>
-#include <ni_stc.h>
-#include <8255.h>
+#include "ni_stc.h"
+#include "8255.h"
 
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
index c449efc629f1791bb84dca6be06c682b0f290395..c55b7e3744a7e63dd04548708ce06083001abb82 100644 (file)
@@ -46,8 +46,8 @@
 #include <linux/malloc.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
-#include <mite.h>
-#include <8255.h>
+#include "mite.h"
+#include "8255.h"
 
 /* general debugging messages */
 #define DEBUG
index a60cdea5477afeb5a4c016282ab0a49d7e3129a6..ea4da016e354c989b6e41820bd017eadd8cd7968 100644 (file)
@@ -73,8 +73,8 @@
 #include <asm/io.h>
 #include <linux/malloc.h>
 #include <linux/comedidev.h>
-#include <ni_stc.h>
-#include <mite.h>
+#include "ni_stc.h"
+#include "mite.h"
 
 #undef DEBUG
 #define PCI_DEBUG
index 409f8dfdbfccfe6719e0403323bfc58612fa81b2..1e04cf87f26f8849a43225e87a0527aa8c74595c 100644 (file)
@@ -59,7 +59,7 @@
 #include <linux/timer.h>
 #include <asm/io.h>
 #include <linux/comedidev.h>
-#include <8253.h>
+#include "8253.h"
 
 
 
index 8374fd0621703cd1e2a197cea2274350a522d9fd..804ccf962bcfbc8904a805952587741825d11a08 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/timer.h>
 #include <asm/io.h>
 #include <linux/comedidev.h>
-#include <8255.h>
+#include "8255.h"
 
 #define PCL722_SIZE    32
 #define PCL722_96_SIZE 16
index 38cc8d73dd1663e34a2b60b6580674048f44486d..069d2863c448bb92ee7d371af068ceafb8b6c534 100644 (file)
@@ -42,7 +42,7 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <linux/comedidev.h>
-#include <8253.h>
+#include "8253.h"
 
 /* #define MD_DEBUG */
 
index 82ff78291c7286bf4a0f8d6e5f740440225bb8b6..9704ab2dcdc8a0500f02e5c86886999037bef821 100644 (file)
@@ -71,7 +71,7 @@
 #include <linux/delay.h>
 #include <asm/dma.h>
 #include <linux/comedidev.h>
-#include <8253.h>
+#include "8253.h"
 
 // #define PCL818_MODE13_AO 1
 
index ae2b1a4dad7251c4e9c6ae43ecd8ab6e1a5bb4ea..7b0ce8066092c776523dbe9de03e5a1805ece322 100644 (file)
@@ -75,7 +75,7 @@
 #define Am9513_input_data()            inb(dev->iobase+RTI800_9513A_DATA)
 #define Am9513_input_status()          inb(dev->iobase+RTI800_9513A_STATUS)
 
-#include <am9513.h>
+#include "am9513.h"
 
 static comedi_lrange range_rti800_ai_10_bipolar = { 4, {
        BIP_RANGE( 10 ),