]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/0009-Staging-add-me4000-pci-data-collection-driver.patch
Imported linux-2.6.27.39 suse/xen patches.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / 0009-Staging-add-me4000-pci-data-collection-driver.patch
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/0009-Staging-add-me4000-pci-data-collection-driver.patch b/src/patches/suse-2.6.27.31/patches.drivers/0009-Staging-add-me4000-pci-data-collection-driver.patch
deleted file mode 100644 (file)
index 08ad39e..0000000
+++ /dev/null
@@ -1,7198 +0,0 @@
-From c0f005888c6663898a040cd922947dd8caa55160 Mon Sep 17 00:00:00 2001
-From: Greg Kroah-Hartman <gregkh@suse.de>
-Date: Fri, 21 Mar 2008 14:12:51 -0700
-Subject: [PATCH 09/23] Staging: add me4000 pci data collection driver
-Patch-mainline: 2.6.28
-
-Originally written by Guenter Gebhardt <g.gebhardt@meilhaus.de>
-
-TODO:
-       - checkpatch.pl cleanups
-       - sparse cleanups
-       - possible /proc interaction cleanups
-       - more info needed for Kconfig entry
-       - real device id?
-       - module parameter cleanup
-
-Cc: Wolfgang Beiter <w.beiter@aon.at>
-Cc: Guenter Gebhardt <g.gebhardt@meilhaus.de>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
----
- drivers/staging/Kconfig         |    2 +
- drivers/staging/Makefile        |    1 +
- drivers/staging/me4000/Kconfig  |   10 +
- drivers/staging/me4000/Makefile |    1 +
- drivers/staging/me4000/README   |   13 +
- drivers/staging/me4000/me4000.c | 6133 +++++++++++++++++++++++++++++++++++++++
- drivers/staging/me4000/me4000.h |  954 ++++++
- 7 files changed, 7114 insertions(+), 0 deletions(-)
- create mode 100644 drivers/staging/me4000/Kconfig
- create mode 100644 drivers/staging/me4000/Makefile
- create mode 100644 drivers/staging/me4000/README
- create mode 100644 drivers/staging/me4000/me4000.c
- create mode 100644 drivers/staging/me4000/me4000.h
-
-diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
-index 6da7662..56c73bc 100644
---- a/drivers/staging/Kconfig
-+++ b/drivers/staging/Kconfig
-@@ -29,4 +29,6 @@ source "drivers/staging/slicoss/Kconfig"
- source "drivers/staging/sxg/Kconfig"
-+source "drivers/staging/me4000/Kconfig"
-+
- endif # STAGING
-diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
-index cd6d6a5..97df19b 100644
---- a/drivers/staging/Makefile
-+++ b/drivers/staging/Makefile
-@@ -3,3 +3,4 @@
- obj-$(CONFIG_ET131X)          += et131x/
- obj-$(CONFIG_SLICOSS)         += slicoss/
- obj-$(CONFIG_SXG)             += sxg/
-+obj-$(CONFIG_ME4000)          += me4000/
-diff --git a/drivers/staging/me4000/Kconfig b/drivers/staging/me4000/Kconfig
-new file mode 100644
-index 0000000..5e6c9de
---- /dev/null
-+++ b/drivers/staging/me4000/Kconfig
-@@ -0,0 +1,10 @@
-+config ME4000
-+      tristate "Meilhaus ME-4000 support"
-+      default n
-+      depends on PCI
-+      help
-+        This driver supports the Meilhaus ME-4000 family of boards
-+        that do data collection and multipurpose I/O.
-+
-+        To compile this driver as a module, choose M here: the module
-+        will be called me4000.
-diff --git a/drivers/staging/me4000/Makefile b/drivers/staging/me4000/Makefile
-new file mode 100644
-index 0000000..74487cd
---- /dev/null
-+++ b/drivers/staging/me4000/Makefile
-@@ -0,0 +1 @@
-+obj-$(CONFIG_ME4000)          += me4000.o
-diff --git a/drivers/staging/me4000/README b/drivers/staging/me4000/README
-new file mode 100644
-index 0000000..bbb8386
---- /dev/null
-+++ b/drivers/staging/me4000/README
-@@ -0,0 +1,13 @@
-+
-+TODO:
-+      - checkpatch.pl cleanups
-+      - sparse cleanups
-+      - possible /proc interaction cleanups
-+      - more info needed for Kconfig entry
-+      - real device id?
-+      - module parameter cleanup
-+
-+Please send patches to Greg Kroah-Hartman <gregkh@suse.de>
-+and Cc: Wolfgang Beiter <w.beiter@aon.at> and
-+Guenter Gebhardt <g.gebhardt@meilhaus.de>
-+
-diff --git a/drivers/staging/me4000/me4000.c b/drivers/staging/me4000/me4000.c
-new file mode 100644
-index 0000000..862dd7f
---- /dev/null
-+++ b/drivers/staging/me4000/me4000.c
-@@ -0,0 +1,6133 @@
-+/* Device driver for Meilhaus ME-4000 board family.
-+ * ================================================
-+ *
-+ *  Copyright (C) 2003 Meilhaus Electronic GmbH (support@meilhaus.de)
-+ *
-+ *  This file 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.
-+ *
-+ *  Author:   Guenter Gebhardt        <g.gebhardt@meilhaus.de>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/pci.h>
-+#include <asm/io.h>
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h>
-+#include <linux/fs.h>
-+#include <linux/mm.h>
-+#include <linux/unistd.h>
-+#include <linux/list.h>
-+#include <linux/proc_fs.h>
-+
-+#include <linux/poll.h>
-+#include <linux/vmalloc.h>
-+#include <asm/pgtable.h>
-+#include <asm/uaccess.h>
-+#include <linux/types.h>
-+
-+#include <linux/slab.h>
-+
-+/* Include-File for the Meilhaus ME-4000 I/O board */
-+#include "me4000.h"
-+#include "me4000_firmware.h"
-+#include "me4610_firmware.h"
-+
-+/* Administrative stuff for modinfo */
-+MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
-+MODULE_DESCRIPTION
-+    ("Device Driver Module for Meilhaus ME-4000 boards version 1.0.5");
-+MODULE_SUPPORTED_DEVICE("Meilhaus ME-4000 Multi I/O boards");
-+MODULE_LICENSE("GPL");
-+
-+/* Board specific data are kept in a global list */
-+LIST_HEAD(me4000_board_info_list);
-+
-+/* Major Device Numbers. 0 means to get it automatically from the System */
-+static int me4000_ao_major_driver_no = 0;
-+static int me4000_ai_major_driver_no = 0;
-+static int me4000_dio_major_driver_no = 0;
-+static int me4000_cnt_major_driver_no = 0;
-+static int me4000_ext_int_major_driver_no = 0;
-+
-+/* Let the user specify a custom major driver number */
-+module_param(me4000_ao_major_driver_no, int, 0);
-+MODULE_PARM_DESC(me4000_ao_major_driver_no,
-+               "Major driver number for analog output (default 0)");
-+
-+module_param(me4000_ai_major_driver_no, int, 0);
-+MODULE_PARM_DESC(me4000_ai_major_driver_no,
-+               "Major driver number for analog input (default 0)");
-+
-+module_param(me4000_dio_major_driver_no, int, 0);
-+MODULE_PARM_DESC(me4000_dio_major_driver_no,
-+               "Major driver number digital I/O (default 0)");
-+
-+module_param(me4000_cnt_major_driver_no, int, 0);
-+MODULE_PARM_DESC(me4000_cnt_major_driver_no,
-+               "Major driver number for counter (default 0)");
-+
-+module_param(me4000_ext_int_major_driver_no, int, 0);
-+MODULE_PARM_DESC(me4000_ext_int_major_driver_no,
-+               "Major driver number for external interrupt (default 0)");
-+
-+/*-----------------------------------------------------------------------------
-+  Module stuff
-+  ---------------------------------------------------------------------------*/
-+int init_module(void);
-+void cleanup_module(void);
-+
-+/*-----------------------------------------------------------------------------
-+  Board detection and initialization
-+  ---------------------------------------------------------------------------*/
-+static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id);
-+static int me4000_xilinx_download(me4000_info_t *);
-+static int me4000_reset_board(me4000_info_t *);
-+
-+static void clear_board_info_list(void);
-+static int get_registers(struct pci_dev *dev, me4000_info_t * info);
-+static int init_board_info(struct pci_dev *dev, me4000_info_t * board_info);
-+static int alloc_ao_contexts(me4000_info_t * info);
-+static void release_ao_contexts(me4000_info_t * board_info);
-+static int alloc_ai_context(me4000_info_t * info);
-+static int alloc_dio_context(me4000_info_t * info);
-+static int alloc_cnt_context(me4000_info_t * info);
-+static int alloc_ext_int_context(me4000_info_t * info);
-+
-+/*-----------------------------------------------------------------------------
-+  Stuff used by all device parts
-+  ---------------------------------------------------------------------------*/
-+static int me4000_open(struct inode *, struct file *);
-+static int me4000_release(struct inode *, struct file *);
-+
-+static int me4000_get_user_info(me4000_user_info_t *,
-+                              me4000_info_t * board_info);
-+static int me4000_read_procmem(char *, char **, off_t, int, int *, void *);
-+
-+/*-----------------------------------------------------------------------------
-+  Analog output stuff
-+  ---------------------------------------------------------------------------*/
-+static ssize_t me4000_ao_write_sing(struct file *, const char *, size_t,
-+                                  loff_t *);
-+static ssize_t me4000_ao_write_wrap(struct file *, const char *, size_t,
-+                                  loff_t *);
-+static ssize_t me4000_ao_write_cont(struct file *, const char *, size_t,
-+                                  loff_t *);
-+
-+static int me4000_ao_ioctl_sing(struct inode *, struct file *, unsigned int,
-+                              unsigned long);
-+static int me4000_ao_ioctl_wrap(struct inode *, struct file *, unsigned int,
-+                              unsigned long);
-+static int me4000_ao_ioctl_cont(struct inode *, struct file *, unsigned int,
-+                              unsigned long);
-+
-+static unsigned int me4000_ao_poll_cont(struct file *, poll_table *);
-+static int me4000_ao_fsync_cont(struct file *, struct dentry *, int);
-+
-+static int me4000_ao_start(unsigned long *, me4000_ao_context_t *);
-+static int me4000_ao_stop(me4000_ao_context_t *);
-+static int me4000_ao_immediate_stop(me4000_ao_context_t *);
-+static int me4000_ao_timer_set_divisor(u32 *, me4000_ao_context_t *);
-+static int me4000_ao_preload(me4000_ao_context_t *);
-+static int me4000_ao_preload_update(me4000_ao_context_t *);
-+static int me4000_ao_ex_trig_set_edge(int *, me4000_ao_context_t *);
-+static int me4000_ao_ex_trig_enable(me4000_ao_context_t *);
-+static int me4000_ao_ex_trig_disable(me4000_ao_context_t *);
-+static int me4000_ao_prepare(me4000_ao_context_t * ao_info);
-+static int me4000_ao_reset(me4000_ao_context_t * ao_info);
-+static int me4000_ao_enable_do(me4000_ao_context_t *);
-+static int me4000_ao_disable_do(me4000_ao_context_t *);
-+static int me4000_ao_fsm_state(int *, me4000_ao_context_t *);
-+
-+static int me4000_ao_simultaneous_ex_trig(me4000_ao_context_t * ao_context);
-+static int me4000_ao_simultaneous_sw(me4000_ao_context_t * ao_context);
-+static int me4000_ao_simultaneous_disable(me4000_ao_context_t * ao_context);
-+static int me4000_ao_simultaneous_update(me4000_ao_channel_list_t * channels,
-+                                       me4000_ao_context_t * ao_context);
-+
-+static int me4000_ao_synchronous_ex_trig(me4000_ao_context_t * ao_context);
-+static int me4000_ao_synchronous_sw(me4000_ao_context_t * ao_context);
-+static int me4000_ao_synchronous_disable(me4000_ao_context_t * ao_context);
-+
-+static int me4000_ao_ex_trig_timeout(unsigned long *arg,
-+                                   me4000_ao_context_t * ao_context);
-+static int me4000_ao_get_free_buffer(unsigned long *arg,
-+                                   me4000_ao_context_t * ao_context);
-+
-+/*-----------------------------------------------------------------------------
-+  Analog input stuff
-+  ---------------------------------------------------------------------------*/
-+static int me4000_ai_single(me4000_ai_single_t *, me4000_ai_context_t *);
-+static int me4000_ai_ioctl_sing(struct inode *, struct file *, unsigned int,
-+                              unsigned long);
-+
-+static ssize_t me4000_ai_read(struct file *, char *, size_t, loff_t *);
-+static int me4000_ai_ioctl_sw(struct inode *, struct file *, unsigned int,
-+                            unsigned long);
-+static unsigned int me4000_ai_poll(struct file *, poll_table *);
-+static int me4000_ai_fasync(int fd, struct file *file_p, int mode);
-+
-+static int me4000_ai_ioctl_ext(struct inode *, struct file *, unsigned int,
-+                             unsigned long);
-+
-+static int me4000_ai_prepare(me4000_ai_context_t * ai_context);
-+static int me4000_ai_reset(me4000_ai_context_t * ai_context);
-+static int me4000_ai_config(me4000_ai_config_t *, me4000_ai_context_t *);
-+static int me4000_ai_start(me4000_ai_context_t *);
-+static int me4000_ai_start_ex(unsigned long *, me4000_ai_context_t *);
-+static int me4000_ai_stop(me4000_ai_context_t *);
-+static int me4000_ai_immediate_stop(me4000_ai_context_t *);
-+static int me4000_ai_ex_trig_enable(me4000_ai_context_t *);
-+static int me4000_ai_ex_trig_disable(me4000_ai_context_t *);
-+static int me4000_ai_ex_trig_setup(me4000_ai_trigger_t *,
-+                                 me4000_ai_context_t *);
-+static int me4000_ai_sc_setup(me4000_ai_sc_t * arg,
-+                            me4000_ai_context_t * ai_context);
-+static int me4000_ai_offset_enable(me4000_ai_context_t * ai_context);
-+static int me4000_ai_offset_disable(me4000_ai_context_t * ai_context);
-+static int me4000_ai_fullscale_enable(me4000_ai_context_t * ai_context);
-+static int me4000_ai_fullscale_disable(me4000_ai_context_t * ai_context);
-+static int me4000_ai_fsm_state(int *arg, me4000_ai_context_t * ai_context);
-+static int me4000_ai_get_count_buffer(unsigned long *arg,
-+                                    me4000_ai_context_t * ai_context);
-+
-+/*-----------------------------------------------------------------------------
-+  EEPROM stuff
-+  ---------------------------------------------------------------------------*/
-+static int me4000_eeprom_read(me4000_eeprom_t * arg,
-+                            me4000_ai_context_t * ai_context);
-+static int me4000_eeprom_write(me4000_eeprom_t * arg,
-+                             me4000_ai_context_t * ai_context);
-+static unsigned short eeprom_read_cmd(me4000_ai_context_t * ai_context,
-+                                    unsigned long cmd, int length);
-+static int eeprom_write_cmd(me4000_ai_context_t * ai_context, unsigned long cmd,
-+                          int length);
-+
-+/*-----------------------------------------------------------------------------
-+  Digital I/O stuff
-+  ---------------------------------------------------------------------------*/
-+static int me4000_dio_ioctl(struct inode *, struct file *, unsigned int,
-+                          unsigned long);
-+static int me4000_dio_config(me4000_dio_config_t *, me4000_dio_context_t *);
-+static int me4000_dio_get_byte(me4000_dio_byte_t *, me4000_dio_context_t *);
-+static int me4000_dio_set_byte(me4000_dio_byte_t *, me4000_dio_context_t *);
-+static int me4000_dio_reset(me4000_dio_context_t *);
-+
-+/*-----------------------------------------------------------------------------
-+  Counter stuff
-+  ---------------------------------------------------------------------------*/
-+static int me4000_cnt_ioctl(struct inode *, struct file *, unsigned int,
-+                          unsigned long);
-+static int me4000_cnt_config(me4000_cnt_config_t *, me4000_cnt_context_t *);
-+static int me4000_cnt_read(me4000_cnt_t *, me4000_cnt_context_t *);
-+static int me4000_cnt_write(me4000_cnt_t *, me4000_cnt_context_t *);
-+static int me4000_cnt_reset(me4000_cnt_context_t *);
-+
-+/*-----------------------------------------------------------------------------
-+  External interrupt routines
-+  ---------------------------------------------------------------------------*/
-+static int me4000_ext_int_ioctl(struct inode *, struct file *, unsigned int,
-+                              unsigned long);
-+static int me4000_ext_int_enable(me4000_ext_int_context_t *);
-+static int me4000_ext_int_disable(me4000_ext_int_context_t *);
-+static int me4000_ext_int_count(unsigned long *arg,
-+                              me4000_ext_int_context_t * ext_int_context);
-+static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode);
-+
-+/*-----------------------------------------------------------------------------
-+  The interrupt service routines
-+  ---------------------------------------------------------------------------*/
-+static irqreturn_t me4000_ao_isr(int, void *);
-+static irqreturn_t me4000_ai_isr(int, void *);
-+static irqreturn_t me4000_ext_int_isr(int, void *);
-+
-+/*-----------------------------------------------------------------------------
-+  Inline functions
-+  ---------------------------------------------------------------------------*/
-+static int inline me4000_buf_count(me4000_circ_buf_t, int);
-+static int inline me4000_buf_space(me4000_circ_buf_t, int);
-+static int inline me4000_space_to_end(me4000_circ_buf_t, int);
-+static int inline me4000_values_to_end(me4000_circ_buf_t, int);
-+
-+static void inline me4000_outb(unsigned char value, unsigned long port);
-+static void inline me4000_outl(unsigned long value, unsigned long port);
-+static unsigned long inline me4000_inl(unsigned long port);
-+static unsigned char inline me4000_inb(unsigned long port);
-+
-+static int me4000_buf_count(me4000_circ_buf_t buf, int size)
-+{
-+      return ((buf.head - buf.tail) & (size - 1));
-+}
-+
-+static int me4000_buf_space(me4000_circ_buf_t buf, int size)
-+{
-+      return ((buf.tail - (buf.head + 1)) & (size - 1));
-+}
-+
-+static int me4000_values_to_end(me4000_circ_buf_t buf, int size)
-+{
-+      int end;
-+      int n;
-+      end = size - buf.tail;
-+      n = (buf.head + end) & (size - 1);
-+      return (n < end) ? n : end;
-+}
-+
-+static int me4000_space_to_end(me4000_circ_buf_t buf, int size)
-+{
-+      int end;
-+      int n;
-+
-+      end = size - 1 - buf.head;
-+      n = (end + buf.tail) & (size - 1);
-+      return (n <= end) ? n : (end + 1);
-+}
-+
-+static void me4000_outb(unsigned char value, unsigned long port)
-+{
-+      PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
-+      outb(value, port);
-+}
-+
-+static void me4000_outl(unsigned long value, unsigned long port)
-+{
-+      PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
-+      outl(value, port);
-+}
-+
-+static unsigned long me4000_inl(unsigned long port)
-+{
-+      unsigned long value;
-+      value = inl(port);
-+      PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port);
-+      return value;
-+}
-+
-+static unsigned char me4000_inb(unsigned long port)
-+{
-+      unsigned char value;
-+      value = inb(port);
-+      PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port);
-+      return value;
-+}
-+
-+struct pci_driver me4000_driver = {
-+      .name = ME4000_NAME,
-+      .id_table = me4000_pci_table,
-+      .probe = me4000_probe
-+};
-+
-+static struct file_operations me4000_ao_fops_sing = {
-+      owner:THIS_MODULE,
-+      write:me4000_ao_write_sing,
-+      ioctl:me4000_ao_ioctl_sing,
-+      open:me4000_open,
-+      release:me4000_release,
-+};
-+
-+static struct file_operations me4000_ao_fops_wrap = {
-+      owner:THIS_MODULE,
-+      write:me4000_ao_write_wrap,
-+      ioctl:me4000_ao_ioctl_wrap,
-+      open:me4000_open,
-+      release:me4000_release,
-+};
-+
-+static struct file_operations me4000_ao_fops_cont = {
-+      owner:THIS_MODULE,
-+      write:me4000_ao_write_cont,
-+      poll:me4000_ao_poll_cont,
-+      ioctl:me4000_ao_ioctl_cont,
-+      open:me4000_open,
-+      release:me4000_release,
-+      fsync:me4000_ao_fsync_cont,
-+};
-+
-+static struct file_operations me4000_ai_fops_sing = {
-+      owner:THIS_MODULE,
-+      ioctl:me4000_ai_ioctl_sing,
-+      open:me4000_open,
-+      release:me4000_release,
-+};
-+
-+static struct file_operations me4000_ai_fops_cont_sw = {
-+      owner:THIS_MODULE,
-+      read:me4000_ai_read,
-+      poll:me4000_ai_poll,
-+      ioctl:me4000_ai_ioctl_sw,
-+      open:me4000_open,
-+      release:me4000_release,
-+      fasync:me4000_ai_fasync,
-+};
-+
-+static struct file_operations me4000_ai_fops_cont_et = {
-+      owner:THIS_MODULE,
-+      read:me4000_ai_read,
-+      poll:me4000_ai_poll,
-+      ioctl:me4000_ai_ioctl_ext,
-+      open:me4000_open,
-+      release:me4000_release,
-+};
-+
-+static struct file_operations me4000_ai_fops_cont_et_value = {
-+      owner:THIS_MODULE,
-+      read:me4000_ai_read,
-+      poll:me4000_ai_poll,
-+      ioctl:me4000_ai_ioctl_ext,
-+      open:me4000_open,
-+      release:me4000_release,
-+};
-+
-+static struct file_operations me4000_ai_fops_cont_et_chanlist = {
-+      owner:THIS_MODULE,
-+      read:me4000_ai_read,
-+      poll:me4000_ai_poll,
-+      ioctl:me4000_ai_ioctl_ext,
-+      open:me4000_open,
-+      release:me4000_release,
-+};
-+
-+static struct file_operations me4000_dio_fops = {
-+      owner:THIS_MODULE,
-+      ioctl:me4000_dio_ioctl,
-+      open:me4000_open,
-+      release:me4000_release,
-+};
-+
-+static struct file_operations me4000_cnt_fops = {
-+      owner:THIS_MODULE,
-+      ioctl:me4000_cnt_ioctl,
-+      open:me4000_open,
-+      release:me4000_release,
-+};
-+
-+static struct file_operations me4000_ext_int_fops = {
-+      owner:THIS_MODULE,
-+      ioctl:me4000_ext_int_ioctl,
-+      open:me4000_open,
-+      release:me4000_release,
-+      fasync:me4000_ext_int_fasync,
-+};
-+
-+static struct file_operations *me4000_ao_fops_array[] = {
-+      &me4000_ao_fops_sing,   // single operations
-+      &me4000_ao_fops_wrap,   // wraparound operations
-+      &me4000_ao_fops_cont,   // continous operations
-+};
-+
-+static struct file_operations *me4000_ai_fops_array[] = {
-+      &me4000_ai_fops_sing,   // single operations
-+      &me4000_ai_fops_cont_sw,        // continuous operations with software start
-+      &me4000_ai_fops_cont_et,        // continous operations with external trigger
-+      &me4000_ai_fops_cont_et_value,  // sample values by external trigger
-+      &me4000_ai_fops_cont_et_chanlist,       // work through one channel list by external trigger
-+};
-+
-+int __init me4000_init_module(void)
-+{
-+      int result = 0;
-+
-+      CALL_PDEBUG("init_module() is executed\n");
-+
-+      /* Register driver capabilities */
-+      result = pci_register_driver(&me4000_driver);
-+      PDEBUG("init_module():%d devices detected\n", result);
-+      if (result < 0) {
-+              printk(KERN_ERR "ME4000:init_module():Can't register driver\n");
-+              goto INIT_ERROR_1;
-+      }
-+
-+      /* Allocate major number for analog output */
-+      result =
-+          register_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME,
-+                          &me4000_ao_fops_sing);
-+      if (result < 0) {
-+              printk(KERN_ERR "ME4000:init_module():Can't get AO major no\n");
-+              goto INIT_ERROR_2;
-+      } else {
-+              me4000_ao_major_driver_no = result;
-+      }
-+      PDEBUG("init_module():Major driver number for AO = %ld\n",
-+             me4000_ao_major_driver_no);
-+
-+      /* Allocate major number for analog input  */
-+      result =
-+          register_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME,
-+                          &me4000_ai_fops_sing);
-+      if (result < 0) {
-+              printk(KERN_ERR "ME4000:init_module():Can't get AI major no\n");
-+              goto INIT_ERROR_3;
-+      } else {
-+              me4000_ai_major_driver_no = result;
-+      }
-+      PDEBUG("init_module():Major driver number for AI = %ld\n",
-+             me4000_ai_major_driver_no);
-+
-+      /* Allocate major number for digital I/O */
-+      result =
-+          register_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME,
-+                          &me4000_dio_fops);
-+      if (result < 0) {
-+              printk(KERN_ERR
-+                     "ME4000:init_module():Can't get DIO major no\n");
-+              goto INIT_ERROR_4;
-+      } else {
-+              me4000_dio_major_driver_no = result;
-+      }
-+      PDEBUG("init_module():Major driver number for DIO = %ld\n",
-+             me4000_dio_major_driver_no);
-+
-+      /* Allocate major number for counter */
-+      result =
-+          register_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME,
-+                          &me4000_cnt_fops);
-+      if (result < 0) {
-+              printk(KERN_ERR
-+                     "ME4000:init_module():Can't get CNT major no\n");
-+              goto INIT_ERROR_5;
-+      } else {
-+              me4000_cnt_major_driver_no = result;
-+      }
-+      PDEBUG("init_module():Major driver number for CNT = %ld\n",
-+             me4000_cnt_major_driver_no);
-+
-+      /* Allocate major number for external interrupt */
-+      result =
-+          register_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME,
-+                          &me4000_ext_int_fops);
-+      if (result < 0) {
-+              printk(KERN_ERR
-+                     "ME4000:init_module():Can't get major no for external interrupt\n");
-+              goto INIT_ERROR_6;
-+      } else {
-+              me4000_ext_int_major_driver_no = result;
-+      }
-+      PDEBUG
-+          ("init_module():Major driver number for external interrupt = %ld\n",
-+           me4000_ext_int_major_driver_no);
-+
-+      /* Create the /proc/me4000 entry */
-+      if (!create_proc_read_entry
-+          ("me4000", 0, NULL, me4000_read_procmem, NULL)) {
-+              result = -ENODEV;
-+              printk(KERN_ERR
-+                     "ME4000:init_module():Can't create proc entry\n");
-+              goto INIT_ERROR_7;
-+      }
-+
-+      return 0;
-+
-+      INIT_ERROR_7:
-+      unregister_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME);
-+
-+      INIT_ERROR_6:
-+      unregister_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME);
-+
-+      INIT_ERROR_5:
-+      unregister_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME);
-+
-+      INIT_ERROR_4:
-+      unregister_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME);
-+
-+      INIT_ERROR_3:
-+      unregister_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME);
-+
-+      INIT_ERROR_2:
-+      pci_unregister_driver(&me4000_driver);
-+      clear_board_info_list();
-+
-+      INIT_ERROR_1:
-+      return result;
-+}
-+
-+module_init(me4000_init_module);
-+
-+static void clear_board_info_list(void)
-+{
-+      struct list_head *board_p;
-+      struct list_head *dac_p;
-+      me4000_info_t *board_info;
-+      me4000_ao_context_t *ao_context;
-+
-+      /* Clear context lists */
-+      for (board_p = me4000_board_info_list.next;
-+           board_p != &me4000_board_info_list; board_p = board_p->next) {
-+              board_info = list_entry(board_p, me4000_info_t, list);
-+              /* Clear analog output context list */
-+              while (!list_empty(&board_info->ao_context_list)) {
-+                      dac_p = board_info->ao_context_list.next;
-+                      ao_context =
-+                          list_entry(dac_p, me4000_ao_context_t, list);
-+                      me4000_ao_reset(ao_context);
-+                      free_irq(ao_context->irq, ao_context);
-+                      if (ao_context->circ_buf.buf)
-+                              kfree(ao_context->circ_buf.buf);
-+                      list_del(dac_p);
-+                      kfree(ao_context);
-+              }
-+
-+              /* Clear analog input context */
-+              if (board_info->ai_context->circ_buf.buf)
-+                      kfree(board_info->ai_context->circ_buf.buf);
-+              kfree(board_info->ai_context);
-+
-+              /* Clear digital I/O context */
-+              kfree(board_info->dio_context);
-+
-+              /* Clear counter context */
-+              kfree(board_info->cnt_context);
-+
-+              /* Clear external interrupt context */
-+              kfree(board_info->ext_int_context);
-+      }
-+
-+      /* Clear the board info list */
-+      while (!list_empty(&me4000_board_info_list)) {
-+              board_p = me4000_board_info_list.next;
-+              board_info = list_entry(board_p, me4000_info_t, list);
-+              pci_release_regions(board_info->pci_dev_p);
-+              list_del(board_p);
-+              kfree(board_info);
-+      }
-+}
-+
-+static int get_registers(struct pci_dev *dev, me4000_info_t * board_info)
-+{
-+
-+      /*--------------------------- plx regbase ---------------------------------*/
-+
-+      board_info->plx_regbase = pci_resource_start(dev, 1);
-+      if (board_info->plx_regbase == 0) {
-+              printk(KERN_ERR
-+                     "ME4000:get_registers():PCI base address 1 is not available\n");
-+              return -ENODEV;
-+      }
-+      board_info->plx_regbase_size = pci_resource_len(dev, 1);
-+
-+      PDEBUG
-+          ("get_registers():PLX configuration registers at address 0x%4lX [0x%4lX]\n",
-+           board_info->plx_regbase, board_info->plx_regbase_size);
-+
-+      /*--------------------------- me4000 regbase ------------------------------*/
-+
-+      board_info->me4000_regbase = pci_resource_start(dev, 2);
-+      if (board_info->me4000_regbase == 0) {
-+              printk(KERN_ERR
-+                     "ME4000:get_registers():PCI base address 2 is not available\n");
-+              return -ENODEV;
-+      }
-+      board_info->me4000_regbase_size = pci_resource_len(dev, 2);
-+
-+      PDEBUG("get_registers():ME4000 registers at address 0x%4lX [0x%4lX]\n",
-+             board_info->me4000_regbase, board_info->me4000_regbase_size);
-+
-+      /*--------------------------- timer regbase ------------------------------*/
-+
-+      board_info->timer_regbase = pci_resource_start(dev, 3);
-+      if (board_info->timer_regbase == 0) {
-+              printk(KERN_ERR
-+                     "ME4000:get_registers():PCI base address 3 is not available\n");
-+              return -ENODEV;
-+      }
-+      board_info->timer_regbase_size = pci_resource_len(dev, 3);
-+
-+      PDEBUG("get_registers():Timer registers at address 0x%4lX [0x%4lX]\n",
-+             board_info->timer_regbase, board_info->timer_regbase_size);
-+
-+      /*--------------------------- program regbase ------------------------------*/
-+
-+      board_info->program_regbase = pci_resource_start(dev, 5);
-+      if (board_info->program_regbase == 0) {
-+              printk(KERN_ERR
-+                     "get_registers():ME4000:PCI base address 5 is not available\n");
-+              return -ENODEV;
-+      }
-+      board_info->program_regbase_size = pci_resource_len(dev, 5);
-+
-+      PDEBUG("get_registers():Program registers at address 0x%4lX [0x%4lX]\n",
-+             board_info->program_regbase, board_info->program_regbase_size);
-+
-+      return 0;
-+}
-+
-+static int init_board_info(struct pci_dev *pci_dev_p,
-+                         me4000_info_t * board_info)
-+{
-+      int i;
-+      int result;
-+      struct list_head *board_p;
-+      board_info->pci_dev_p = pci_dev_p;
-+
-+      for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
-+              if (me4000_boards[i].device_id == pci_dev_p->device) {
-+                      board_info->board_p = &me4000_boards[i];
-+                      break;
-+              }
-+      }
-+      if (i == ME4000_BOARD_VERSIONS) {
-+              printk(KERN_ERR
-+                     "ME4000:init_board_info():Device ID not valid\n");
-+              return -ENODEV;
-+      }
-+
-+      /* Get the index of the board in the global list */
-+      for (board_p = me4000_board_info_list.next, i = 0;
-+           board_p != &me4000_board_info_list; board_p = board_p->next, i++) {
-+              if (board_p == &board_info->list) {
-+                      board_info->board_count = i;
-+                      break;
-+              }
-+      }
-+      if (board_p == &me4000_board_info_list) {
-+              printk(KERN_ERR
-+                     "ME4000:init_board_info():Cannot get index of baord\n");
-+              return -ENODEV;
-+      }
-+
-+      /* Init list head for analog output contexts */
-+      INIT_LIST_HEAD(&board_info->ao_context_list);
-+
-+      /* Init spin locks */
-+      spin_lock_init(&board_info->preload_lock);
-+      spin_lock_init(&board_info->ai_ctrl_lock);
-+
-+      /* Get the serial number */
-+      result = pci_read_config_dword(pci_dev_p, 0x2C, &board_info->serial_no);
-+      if (result != PCIBIOS_SUCCESSFUL) {
-+              printk(KERN_WARNING
-+                     "ME4000:init_board_info: Can't get serial_no\n");
-+              return result;
-+      }
-+      PDEBUG("init_board_info():serial_no = 0x%x\n", board_info->serial_no);
-+
-+      /* Get the hardware revision */
-+      result =
-+          pci_read_config_byte(pci_dev_p, 0x08, &board_info->hw_revision);
-+      if (result != PCIBIOS_SUCCESSFUL) {
-+              printk(KERN_WARNING
-+                     "ME4000:init_board_info():Can't get hw_revision\n");
-+              return result;
-+      }
-+      PDEBUG("init_board_info():hw_revision = 0x%x\n",
-+             board_info->hw_revision);
-+
-+      /* Get the vendor id */
-+      board_info->vendor_id = pci_dev_p->vendor;
-+      PDEBUG("init_board_info():vendor_id = 0x%x\n", board_info->vendor_id);
-+
-+      /* Get the device id */
-+      board_info->device_id = pci_dev_p->device;
-+      PDEBUG("init_board_info():device_id = 0x%x\n", board_info->device_id);
-+
-+      /* Get the pci device number */
-+      board_info->pci_dev_no = PCI_FUNC(pci_dev_p->devfn);
-+      PDEBUG("init_board_info():pci_func_no = 0x%x\n",
-+             board_info->pci_func_no);
-+
-+      /* Get the pci slot number */
-+      board_info->pci_dev_no = PCI_SLOT(pci_dev_p->devfn);
-+      PDEBUG("init_board_info():pci_dev_no = 0x%x\n", board_info->pci_dev_no);
-+
-+      /* Get the pci bus number */
-+      board_info->pci_bus_no = pci_dev_p->bus->number;
-+      PDEBUG("init_board_info():pci_bus_no = 0x%x\n", board_info->pci_bus_no);
-+
-+      /* Get the irq assigned to the board */
-+      board_info->irq = pci_dev_p->irq;
-+      PDEBUG("init_board_info():irq = %d\n", board_info->irq);
-+
-+      return 0;
-+}
-+
-+static int alloc_ao_contexts(me4000_info_t * info)
-+{
-+      int i;
-+      int err;
-+      me4000_ao_context_t *ao_context;
-+
-+      for (i = 0; i < info->board_p->ao.count; i++) {
-+              ao_context = kmalloc(sizeof(me4000_ao_context_t), GFP_KERNEL);
-+              if (!ao_context) {
-+                      printk(KERN_ERR
-+                             "alloc_ao_contexts():Can't get memory for ao context\n");
-+                      release_ao_contexts(info);
-+                      return -ENOMEM;
-+              }
-+              memset(ao_context, 0, sizeof(me4000_ao_context_t));
-+
-+              spin_lock_init(&ao_context->use_lock);
-+              spin_lock_init(&ao_context->int_lock);
-+              ao_context->irq = info->irq;
-+              init_waitqueue_head(&ao_context->wait_queue);
-+              ao_context->board_info = info;
-+
-+              if (info->board_p->ao.fifo_count) {
-+                      /* Allocate circular buffer */
-+                      ao_context->circ_buf.buf =
-+                          kmalloc(ME4000_AO_BUFFER_SIZE, GFP_KERNEL);
-+                      if (!ao_context->circ_buf.buf) {
-+                              printk(KERN_ERR
-+                                     "alloc_ao_contexts():Can't get circular buffer\n");
-+                              release_ao_contexts(info);
-+                              return -ENOMEM;
-+                      }
-+                      memset(ao_context->circ_buf.buf, 0,
-+                             ME4000_AO_BUFFER_SIZE);
-+
-+                      /* Clear the circular buffer */
-+                      ao_context->circ_buf.head = 0;
-+                      ao_context->circ_buf.tail = 0;
-+              }
-+
-+              switch (i) {
-+              case 0:
-+                      ao_context->ctrl_reg =
-+                          info->me4000_regbase + ME4000_AO_00_CTRL_REG;
-+                      ao_context->status_reg =
-+                          info->me4000_regbase + ME4000_AO_00_STATUS_REG;
-+                      ao_context->fifo_reg =
-+                          info->me4000_regbase + ME4000_AO_00_FIFO_REG;
-+                      ao_context->single_reg =
-+                          info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
-+                      ao_context->timer_reg =
-+                          info->me4000_regbase + ME4000_AO_00_TIMER_REG;
-+                      ao_context->irq_status_reg =
-+                          info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-+                      ao_context->preload_reg =
-+                          info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
-+                      break;
-+              case 1:
-+                      ao_context->ctrl_reg =
-+                          info->me4000_regbase + ME4000_AO_01_CTRL_REG;
-+                      ao_context->status_reg =
-+                          info->me4000_regbase + ME4000_AO_01_STATUS_REG;
-+                      ao_context->fifo_reg =
-+                          info->me4000_regbase + ME4000_AO_01_FIFO_REG;
-+                      ao_context->single_reg =
-+                          info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
-+                      ao_context->timer_reg =
-+                          info->me4000_regbase + ME4000_AO_01_TIMER_REG;
-+                      ao_context->irq_status_reg =
-+                          info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-+                      ao_context->preload_reg =
-+                          info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
-+                      break;
-+              case 2:
-+                      ao_context->ctrl_reg =
-+                          info->me4000_regbase + ME4000_AO_02_CTRL_REG;
-+                      ao_context->status_reg =
-+                          info->me4000_regbase + ME4000_AO_02_STATUS_REG;
-+                      ao_context->fifo_reg =
-+                          info->me4000_regbase + ME4000_AO_02_FIFO_REG;
-+                      ao_context->single_reg =
-+                          info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
-+                      ao_context->timer_reg =
-+                          info->me4000_regbase + ME4000_AO_02_TIMER_REG;
-+                      ao_context->irq_status_reg =
-+                          info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-+                      ao_context->preload_reg =
-+                          info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
-+                      break;
-+              case 3:
-+                      ao_context->ctrl_reg =
-+                          info->me4000_regbase + ME4000_AO_03_CTRL_REG;
-+                      ao_context->status_reg =
-+                          info->me4000_regbase + ME4000_AO_03_STATUS_REG;
-+                      ao_context->fifo_reg =
-+                          info->me4000_regbase + ME4000_AO_03_FIFO_REG;
-+                      ao_context->single_reg =
-+                          info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
-+                      ao_context->timer_reg =
-+                          info->me4000_regbase + ME4000_AO_03_TIMER_REG;
-+                      ao_context->irq_status_reg =
-+                          info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-+                      ao_context->preload_reg =
-+                          info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
-+                      break;
-+              default:
-+                      break;
-+              }
-+
-+              if (info->board_p->ao.fifo_count) {
-+                      /* Request the interrupt line */
-+                      err =
-+                          request_irq(ao_context->irq, me4000_ao_isr,
-+                                      IRQF_DISABLED | IRQF_SHARED,
-+                                      ME4000_NAME, ao_context);
-+                      if (err) {
-+                              printk(KERN_ERR
-+                                     "alloc_ao_contexts():Can't get interrupt line");
-+                              if (ao_context->circ_buf.buf)
-+                                      kfree(ao_context->circ_buf.buf);
-+                              kfree(ao_context);
-+                              release_ao_contexts(info);
-+                              return -ENODEV;
-+                      }
-+              }
-+
-+              list_add_tail(&ao_context->list, &info->ao_context_list);
-+              ao_context->index = i;
-+      }
-+
-+      return 0;
-+}
-+
-+static void release_ao_contexts(me4000_info_t * board_info)
-+{
-+      struct list_head *dac_p;
-+      me4000_ao_context_t *ao_context;
-+
-+      /* Clear analog output context list */
-+      while (!list_empty(&board_info->ao_context_list)) {
-+              dac_p = board_info->ao_context_list.next;
-+              ao_context = list_entry(dac_p, me4000_ao_context_t, list);
-+              free_irq(ao_context->irq, ao_context);
-+              if (ao_context->circ_buf.buf)
-+                      kfree(ao_context->circ_buf.buf);
-+              list_del(dac_p);
-+              kfree(ao_context);
-+      }
-+}
-+
-+static int alloc_ai_context(me4000_info_t * info)
-+{
-+      me4000_ai_context_t *ai_context;
-+
-+      if (info->board_p->ai.count) {
-+              ai_context = kmalloc(sizeof(me4000_ai_context_t), GFP_KERNEL);
-+              if (!ai_context) {
-+                      printk(KERN_ERR
-+                             "ME4000:alloc_ai_context():Can't get memory for ai context\n");
-+                      return -ENOMEM;
-+              }
-+              memset(ai_context, 0, sizeof(me4000_ai_context_t));
-+
-+              info->ai_context = ai_context;
-+
-+              spin_lock_init(&ai_context->use_lock);
-+              spin_lock_init(&ai_context->int_lock);
-+              ai_context->number = 0;
-+              ai_context->irq = info->irq;
-+              init_waitqueue_head(&ai_context->wait_queue);
-+              ai_context->board_info = info;
-+
-+              ai_context->ctrl_reg =
-+                  info->me4000_regbase + ME4000_AI_CTRL_REG;
-+              ai_context->status_reg =
-+                  info->me4000_regbase + ME4000_AI_STATUS_REG;
-+              ai_context->channel_list_reg =
-+                  info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
-+              ai_context->data_reg =
-+                  info->me4000_regbase + ME4000_AI_DATA_REG;
-+              ai_context->chan_timer_reg =
-+                  info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
-+              ai_context->chan_pre_timer_reg =
-+                  info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
-+              ai_context->scan_timer_low_reg =
-+                  info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
-+              ai_context->scan_timer_high_reg =
-+                  info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
-+              ai_context->scan_pre_timer_low_reg =
-+                  info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
-+              ai_context->scan_pre_timer_high_reg =
-+                  info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
-+              ai_context->start_reg =
-+                  info->me4000_regbase + ME4000_AI_START_REG;
-+              ai_context->irq_status_reg =
-+                  info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-+              ai_context->sample_counter_reg =
-+                  info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
-+      }
-+
-+      return 0;
-+}
-+
-+static int alloc_dio_context(me4000_info_t * info)
-+{
-+      me4000_dio_context_t *dio_context;
-+
-+      if (info->board_p->dio.count) {
-+              dio_context = kmalloc(sizeof(me4000_dio_context_t), GFP_KERNEL);
-+              if (!dio_context) {
-+                      printk(KERN_ERR
-+                             "ME4000:alloc_dio_context():Can't get memory for dio context\n");
-+                      return -ENOMEM;
-+              }
-+              memset(dio_context, 0, sizeof(me4000_dio_context_t));
-+
-+              info->dio_context = dio_context;
-+
-+              spin_lock_init(&dio_context->use_lock);
-+              dio_context->board_info = info;
-+
-+              dio_context->dio_count = info->board_p->dio.count;
-+
-+              dio_context->dir_reg =
-+                  info->me4000_regbase + ME4000_DIO_DIR_REG;
-+              dio_context->ctrl_reg =
-+                  info->me4000_regbase + ME4000_DIO_CTRL_REG;
-+              dio_context->port_0_reg =
-+                  info->me4000_regbase + ME4000_DIO_PORT_0_REG;
-+              dio_context->port_1_reg =
-+                  info->me4000_regbase + ME4000_DIO_PORT_1_REG;
-+              dio_context->port_2_reg =
-+                  info->me4000_regbase + ME4000_DIO_PORT_2_REG;
-+              dio_context->port_3_reg =
-+                  info->me4000_regbase + ME4000_DIO_PORT_3_REG;
-+      }
-+
-+      return 0;
-+}
-+
-+static int alloc_cnt_context(me4000_info_t * info)
-+{
-+      me4000_cnt_context_t *cnt_context;
-+
-+      if (info->board_p->cnt.count) {
-+              cnt_context = kmalloc(sizeof(me4000_cnt_context_t), GFP_KERNEL);
-+              if (!cnt_context) {
-+                      printk(KERN_ERR
-+                             "ME4000:alloc_cnt_context():Can't get memory for cnt context\n");
-+                      return -ENOMEM;
-+              }
-+              memset(cnt_context, 0, sizeof(me4000_cnt_context_t));
-+
-+              info->cnt_context = cnt_context;
-+
-+              spin_lock_init(&cnt_context->use_lock);
-+              cnt_context->board_info = info;
-+
-+              cnt_context->ctrl_reg =
-+                  info->timer_regbase + ME4000_CNT_CTRL_REG;
-+              cnt_context->counter_0_reg =
-+                  info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
-+              cnt_context->counter_1_reg =
-+                  info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
-+              cnt_context->counter_2_reg =
-+                  info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
-+      }
-+
-+      return 0;
-+}
-+
-+static int alloc_ext_int_context(me4000_info_t * info)
-+{
-+      me4000_ext_int_context_t *ext_int_context;
-+
-+      if (info->board_p->cnt.count) {
-+              ext_int_context =
-+                  kmalloc(sizeof(me4000_ext_int_context_t), GFP_KERNEL);
-+              if (!ext_int_context) {
-+                      printk(KERN_ERR
-+                             "ME4000:alloc_ext_int_context():Can't get memory for cnt context\n");
-+                      return -ENOMEM;
-+              }
-+              memset(ext_int_context, 0, sizeof(me4000_ext_int_context_t));
-+
-+              info->ext_int_context = ext_int_context;
-+
-+              spin_lock_init(&ext_int_context->use_lock);
-+              ext_int_context->board_info = info;
-+
-+              ext_int_context->fasync_ptr = NULL;
-+              ext_int_context->irq = info->irq;
-+
-+              ext_int_context->ctrl_reg =
-+                  info->me4000_regbase + ME4000_AI_CTRL_REG;
-+              ext_int_context->irq_status_reg =
-+                  info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id)
-+{
-+      int result = 0;
-+      me4000_info_t *board_info;
-+
-+      CALL_PDEBUG("me4000_probe() is executed\n");
-+
-+      /* Allocate structure for board context */
-+      board_info = kmalloc(sizeof(me4000_info_t), GFP_KERNEL);
-+      if (!board_info) {
-+              printk(KERN_ERR
-+                     "ME4000:Can't get memory for board info structure\n");
-+              result = -ENOMEM;
-+              goto PROBE_ERROR_1;
-+      }
-+      memset(board_info, 0, sizeof(me4000_info_t));
-+
-+      /* Add to global linked list */
-+      list_add_tail(&board_info->list, &me4000_board_info_list);
-+
-+      /* Get the PCI base registers */
-+      result = get_registers(dev, board_info);
-+      if (result) {
-+              printk(KERN_ERR "me4000_probe():Cannot get registers\n");
-+              goto PROBE_ERROR_2;
-+      }
-+
-+      /* Enable the device */
-+      result = pci_enable_device(dev);
-+      if (result < 0) {
-+              printk(KERN_ERR "me4000_probe():Cannot enable PCI device\n");
-+              goto PROBE_ERROR_2;
-+      }
-+
-+      /* Request the PCI register regions */
-+      result = pci_request_regions(dev, ME4000_NAME);
-+      if (result < 0) {
-+              printk(KERN_ERR "me4000_probe():Cannot request I/O regions\n");
-+              goto PROBE_ERROR_2;
-+      }
-+
-+      /* Initialize board info */
-+      result = init_board_info(dev, board_info);
-+      if (result) {
-+              printk(KERN_ERR "me4000_probe():Cannot init baord info\n");
-+              goto PROBE_ERROR_3;
-+      }
-+
-+      /* Download the xilinx firmware */
-+      result = me4000_xilinx_download(board_info);
-+      if (result) {
-+              printk(KERN_ERR "me4000_probe:Can't download firmware\n");
-+              goto PROBE_ERROR_3;
-+      }
-+
-+      /* Make a hardware reset */
-+      result = me4000_reset_board(board_info);
-+      if (result) {
-+              printk(KERN_ERR "me4000_probe:Can't reset board\n");
-+              goto PROBE_ERROR_3;
-+      }
-+
-+      /* Allocate analog output context structures */
-+      result = alloc_ao_contexts(board_info);
-+      if (result) {
-+              printk(KERN_ERR "me4000_probe():Cannot allocate ao contexts\n");
-+              goto PROBE_ERROR_3;
-+      }
-+
-+      /* Allocate analog input context */
-+      result = alloc_ai_context(board_info);
-+      if (result) {
-+              printk(KERN_ERR "me4000_probe():Cannot allocate ai context\n");
-+              goto PROBE_ERROR_4;
-+      }
-+
-+      /* Allocate digital I/O context */
-+      result = alloc_dio_context(board_info);
-+      if (result) {
-+              printk(KERN_ERR "me4000_probe():Cannot allocate dio context\n");
-+              goto PROBE_ERROR_5;
-+      }
-+
-+      /* Allocate counter context */
-+      result = alloc_cnt_context(board_info);
-+      if (result) {
-+              printk(KERN_ERR "me4000_probe():Cannot allocate cnt context\n");
-+              goto PROBE_ERROR_6;
-+      }
-+
-+      /* Allocate external interrupt context */
-+      result = alloc_ext_int_context(board_info);
-+      if (result) {
-+              printk(KERN_ERR
-+                     "me4000_probe():Cannot allocate ext_int context\n");
-+              goto PROBE_ERROR_7;
-+      }
-+
-+      return 0;
-+
-+      PROBE_ERROR_7:
-+      kfree(board_info->cnt_context);
-+
-+      PROBE_ERROR_6:
-+      kfree(board_info->dio_context);
-+
-+      PROBE_ERROR_5:
-+      kfree(board_info->ai_context);
-+
-+      PROBE_ERROR_4:
-+      release_ao_contexts(board_info);
-+
-+      PROBE_ERROR_3:
-+      pci_release_regions(dev);
-+
-+      PROBE_ERROR_2:
-+      list_del(&board_info->list);
-+      kfree(board_info);
-+
-+      PROBE_ERROR_1:
-+      return result;
-+}
-+
-+static int me4000_xilinx_download(me4000_info_t * info)
-+{
-+      int size = 0;
-+      u32 value = 0;
-+      int idx = 0;
-+      unsigned char *firm;
-+      wait_queue_head_t queue;
-+
-+      CALL_PDEBUG("me4000_xilinx_download() is executed\n");
-+
-+      init_waitqueue_head(&queue);
-+
-+      firm = (info->device_id == 0x4610) ? xilinx_firm_4610 : xilinx_firm;
-+
-+      /*
-+       * Set PLX local interrupt 2 polarity to high.
-+       * Interrupt is thrown by init pin of xilinx.
-+       */
-+      outl(0x10, info->plx_regbase + PLX_INTCSR);
-+
-+      /* Set /CS and /WRITE of the Xilinx */
-+      value = inl(info->plx_regbase + PLX_ICR);
-+      value |= 0x100;
-+      outl(value, info->plx_regbase + PLX_ICR);
-+
-+      /* Init Xilinx with CS1 */
-+      inb(info->program_regbase + 0xC8);
-+
-+      /* Wait until /INIT pin is set */
-+      udelay(20);
-+      if (!inl(info->plx_regbase + PLX_INTCSR) & 0x20) {
-+              printk(KERN_ERR "me4000_xilinx_download():Can't init Xilinx\n");
-+              return -EIO;
-+      }
-+
-+      /* Reset /CS and /WRITE of the Xilinx */
-+      value = inl(info->plx_regbase + PLX_ICR);
-+      value &= ~0x100;
-+      outl(value, info->plx_regbase + PLX_ICR);
-+
-+      /* Download Xilinx firmware */
-+      size = (firm[0] << 24) + (firm[1] << 16) + (firm[2] << 8) + firm[3];
-+      udelay(10);
-+
-+      for (idx = 0; idx < size; idx++) {
-+              outb(firm[16 + idx], info->program_regbase);
-+
-+              udelay(10);
-+
-+              /* Check if BUSY flag is low */
-+              if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
-+                      printk(KERN_ERR
-+                             "me4000_xilinx_download():Xilinx is still busy (idx = %d)\n",
-+                             idx);
-+                      return -EIO;
-+              }
-+      }
-+
-+      PDEBUG("me4000_xilinx_download():%d bytes written\n", idx);
-+
-+      /* If done flag is high download was successful */
-+      if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
-+              PDEBUG("me4000_xilinx_download():Done flag is set\n");
-+              PDEBUG("me4000_xilinx_download():Download was successful\n");
-+      } else {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_xilinx_download():DONE flag is not set\n");
-+              printk(KERN_ERR
-+                     "ME4000:me4000_xilinx_download():Download not succesful\n");
-+              return -EIO;
-+      }
-+
-+      /* Set /CS and /WRITE */
-+      value = inl(info->plx_regbase + PLX_ICR);
-+      value |= 0x100;
-+      outl(value, info->plx_regbase + PLX_ICR);
-+
-+      return 0;
-+}
-+
-+static int me4000_reset_board(me4000_info_t * info)
-+{
-+      unsigned long icr;
-+
-+      CALL_PDEBUG("me4000_reset_board() is executed\n");
-+
-+      /* Make a hardware reset */
-+      icr = me4000_inl(info->plx_regbase + PLX_ICR);
-+      icr |= 0x40000000;
-+      me4000_outl(icr, info->plx_regbase + PLX_ICR);
-+      icr &= ~0x40000000;
-+      me4000_outl(icr, info->plx_regbase + PLX_ICR);
-+
-+      /* Set both stop bits in the analog input control register */
-+      me4000_outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
-+                  info->me4000_regbase + ME4000_AI_CTRL_REG);
-+
-+      /* Set both stop bits in the analog output control register */
-+      me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-+                  info->me4000_regbase + ME4000_AO_00_CTRL_REG);
-+      me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-+                  info->me4000_regbase + ME4000_AO_01_CTRL_REG);
-+      me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-+                  info->me4000_regbase + ME4000_AO_02_CTRL_REG);
-+      me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-+                  info->me4000_regbase + ME4000_AO_03_CTRL_REG);
-+
-+      /* 0x8000 to the DACs means an output voltage of 0V */
-+      me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
-+      me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
-+      me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
-+      me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
-+
-+      /* Enable interrupts on the PLX */
-+      me4000_outl(0x43, info->plx_regbase + PLX_INTCSR);
-+
-+      /* Set the adustment register for AO demux */
-+      me4000_outl(ME4000_AO_DEMUX_ADJUST_VALUE,
-+                  info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
-+
-+      /* Set digital I/O direction for port 0 to output on isolated versions */
-+      if (!(me4000_inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
-+              me4000_outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG);
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_open(struct inode *inode_p, struct file *file_p)
-+{
-+      int board, dev, mode;
-+      int err = 0;
-+      int i;
-+      struct list_head *ptr;
-+      me4000_info_t *board_info = NULL;
-+      me4000_ao_context_t *ao_context = NULL;
-+      me4000_ai_context_t *ai_context = NULL;
-+      me4000_dio_context_t *dio_context = NULL;
-+      me4000_cnt_context_t *cnt_context = NULL;
-+      me4000_ext_int_context_t *ext_int_context = NULL;
-+
-+      CALL_PDEBUG("me4000_open() is executed\n");
-+
-+      /* Analog output */
-+      if (MAJOR(inode_p->i_rdev) == me4000_ao_major_driver_no) {
-+              board = AO_BOARD(inode_p->i_rdev);
-+              dev = AO_PORT(inode_p->i_rdev);
-+              mode = AO_MODE(inode_p->i_rdev);
-+
-+              PDEBUG("me4000_open():board = %d ao = %d mode = %d\n", board,
-+                     dev, mode);
-+
-+              /* Search for the board context */
-+              for (ptr = me4000_board_info_list.next, i = 0;
-+                   ptr != &me4000_board_info_list; ptr = ptr->next, i++) {
-+                      board_info = list_entry(ptr, me4000_info_t, list);
-+                      if (i == board)
-+                              break;
-+              }
-+
-+              if (ptr == &me4000_board_info_list) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():Board %d not in device list\n",
-+                             board);
-+                      return -ENODEV;
-+              }
-+
-+              /* Search for the dac context */
-+              for (ptr = board_info->ao_context_list.next, i = 0;
-+                   ptr != &board_info->ao_context_list;
-+                   ptr = ptr->next, i++) {
-+                      ao_context = list_entry(ptr, me4000_ao_context_t, list);
-+                      if (i == dev)
-+                              break;
-+              }
-+
-+              if (ptr == &board_info->ao_context_list) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():Device %d not in device list\n",
-+                             dev);
-+                      return -ENODEV;
-+              }
-+
-+              /* Check if mode is valid */
-+              if (mode > 2) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():Mode is not valid\n");
-+                      return -ENODEV;
-+              }
-+
-+              /* Check if mode is valid for this AO */
-+              if ((mode != ME4000_AO_CONV_MODE_SINGLE)
-+                  && (dev >= board_info->board_p->ao.fifo_count)) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():AO %d only in single mode available\n",
-+                             dev);
-+                      return -ENODEV;
-+              }
-+
-+              /* Check if already opened */
-+              spin_lock(&ao_context->use_lock);
-+              if (ao_context->dac_in_use) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():AO %d already in use\n",
-+                             dev);
-+                      spin_unlock(&ao_context->use_lock);
-+                      return -EBUSY;
-+              }
-+              ao_context->dac_in_use = 1;
-+              spin_unlock(&ao_context->use_lock);
-+
-+              ao_context->mode = mode;
-+
-+              /* Hold the context in private data */
-+              file_p->private_data = ao_context;
-+
-+              /* Set file operations pointer */
-+              file_p->f_op = me4000_ao_fops_array[mode];
-+
-+              err = me4000_ao_prepare(ao_context);
-+              if (err) {
-+                      ao_context->dac_in_use = 0;
-+                      return 1;
-+              }
-+      }
-+      /* Analog input */
-+      else if (MAJOR(inode_p->i_rdev) == me4000_ai_major_driver_no) {
-+              board = AI_BOARD(inode_p->i_rdev);
-+              mode = AI_MODE(inode_p->i_rdev);
-+
-+              PDEBUG("me4000_open():ai board = %d mode = %d\n", board, mode);
-+
-+              /* Search for the board context */
-+              for (ptr = me4000_board_info_list.next, i = 0;
-+                   ptr != &me4000_board_info_list; ptr = ptr->next, i++) {
-+                      board_info = list_entry(ptr, me4000_info_t, list);
-+                      if (i == board)
-+                              break;
-+              }
-+
-+              if (ptr == &me4000_board_info_list) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():Board %d not in device list\n",
-+                             board);
-+                      return -ENODEV;
-+              }
-+
-+              ai_context = board_info->ai_context;
-+
-+              /* Check if mode is valid */
-+              if (mode > 5) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():Mode is not valid\n");
-+                      return -EINVAL;
-+              }
-+
-+              /* Check if already opened */
-+              spin_lock(&ai_context->use_lock);
-+              if (ai_context->in_use) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():AI already in use\n");
-+                      spin_unlock(&ai_context->use_lock);
-+                      return -EBUSY;
-+              }
-+              ai_context->in_use = 1;
-+              spin_unlock(&ai_context->use_lock);
-+
-+              ai_context->mode = mode;
-+
-+              /* Hold the context in private data */
-+              file_p->private_data = ai_context;
-+
-+              /* Set file operations pointer */
-+              file_p->f_op = me4000_ai_fops_array[mode];
-+
-+              /* Prepare analog input */
-+              me4000_ai_prepare(ai_context);
-+      }
-+      /* Digital I/O */
-+      else if (MAJOR(inode_p->i_rdev) == me4000_dio_major_driver_no) {
-+              board = DIO_BOARD(inode_p->i_rdev);
-+              dev = 0;
-+              mode = 0;
-+
-+              PDEBUG("me4000_open():board = %d\n", board);
-+
-+              /* Search for the board context */
-+              for (ptr = me4000_board_info_list.next;
-+                   ptr != &me4000_board_info_list; ptr = ptr->next) {
-+                      board_info = list_entry(ptr, me4000_info_t, list);
-+                      if (board_info->board_count == board)
-+                              break;
-+              }
-+
-+              if (ptr == &me4000_board_info_list) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():Board %d not in device list\n",
-+                             board);
-+                      return -ENODEV;
-+              }
-+
-+              /* Search for the dio context */
-+              dio_context = board_info->dio_context;
-+
-+              /* Check if already opened */
-+              spin_lock(&dio_context->use_lock);
-+              if (dio_context->in_use) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():DIO already in use\n");
-+                      spin_unlock(&dio_context->use_lock);
-+                      return -EBUSY;
-+              }
-+              dio_context->in_use = 1;
-+              spin_unlock(&dio_context->use_lock);
-+
-+              /* Hold the context in private data */
-+              file_p->private_data = dio_context;
-+
-+              /* Set file operations pointer to single functions */
-+              file_p->f_op = &me4000_dio_fops;
-+
-+              //me4000_dio_reset(dio_context);
-+      }
-+      /* Counters */
-+      else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) {
-+              board = CNT_BOARD(inode_p->i_rdev);
-+              dev = 0;
-+              mode = 0;
-+
-+              PDEBUG("me4000_open():board = %d\n", board);
-+
-+              /* Search for the board context */
-+              for (ptr = me4000_board_info_list.next;
-+                   ptr != &me4000_board_info_list; ptr = ptr->next) {
-+                      board_info = list_entry(ptr, me4000_info_t, list);
-+                      if (board_info->board_count == board)
-+                              break;
-+              }
-+
-+              if (ptr == &me4000_board_info_list) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():Board %d not in device list\n",
-+                             board);
-+                      return -ENODEV;
-+              }
-+
-+              /* Get the cnt context */
-+              cnt_context = board_info->cnt_context;
-+
-+              /* Check if already opened */
-+              spin_lock(&cnt_context->use_lock);
-+              if (cnt_context->in_use) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():CNT already in use\n");
-+                      spin_unlock(&cnt_context->use_lock);
-+                      return -EBUSY;
-+              }
-+              cnt_context->in_use = 1;
-+              spin_unlock(&cnt_context->use_lock);
-+
-+              /* Hold the context in private data */
-+              file_p->private_data = cnt_context;
-+
-+              /* Set file operations pointer to single functions */
-+              file_p->f_op = &me4000_cnt_fops;
-+      }
-+      /* External Interrupt */
-+      else if (MAJOR(inode_p->i_rdev) == me4000_ext_int_major_driver_no) {
-+              board = EXT_INT_BOARD(inode_p->i_rdev);
-+              dev = 0;
-+              mode = 0;
-+
-+              PDEBUG("me4000_open():board = %d\n", board);
-+
-+              /* Search for the board context */
-+              for (ptr = me4000_board_info_list.next;
-+                   ptr != &me4000_board_info_list; ptr = ptr->next) {
-+                      board_info = list_entry(ptr, me4000_info_t, list);
-+                      if (board_info->board_count == board)
-+                              break;
-+              }
-+
-+              if (ptr == &me4000_board_info_list) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():Board %d not in device list\n",
-+                             board);
-+                      return -ENODEV;
-+              }
-+
-+              /* Get the external interrupt context */
-+              ext_int_context = board_info->ext_int_context;
-+
-+              /* Check if already opened */
-+              spin_lock(&cnt_context->use_lock);
-+              if (ext_int_context->in_use) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():External interrupt already in use\n");
-+                      spin_unlock(&ext_int_context->use_lock);
-+                      return -EBUSY;
-+              }
-+              ext_int_context->in_use = 1;
-+              spin_unlock(&ext_int_context->use_lock);
-+
-+              /* Hold the context in private data */
-+              file_p->private_data = ext_int_context;
-+
-+              /* Set file operations pointer to single functions */
-+              file_p->f_op = &me4000_ext_int_fops;
-+
-+              /* Request the interrupt line */
-+              err =
-+                  request_irq(ext_int_context->irq, me4000_ext_int_isr,
-+                              IRQF_DISABLED | IRQF_SHARED, ME4000_NAME,
-+                              ext_int_context);
-+              if (err) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_open():Can't get interrupt line");
-+                      ext_int_context->in_use = 0;
-+                      return -ENODEV;
-+              }
-+
-+              /* Reset the counter */
-+              me4000_ext_int_disable(ext_int_context);
-+      } else {
-+              printk(KERN_ERR "ME4000:me4000_open():Major number unknown\n");
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_release(struct inode *inode_p, struct file *file_p)
-+{
-+      me4000_ao_context_t *ao_context;
-+      me4000_ai_context_t *ai_context;
-+      me4000_dio_context_t *dio_context;
-+      me4000_cnt_context_t *cnt_context;
-+      me4000_ext_int_context_t *ext_int_context;
-+
-+      CALL_PDEBUG("me4000_release() is executed\n");
-+
-+      if (MAJOR(inode_p->i_rdev) == me4000_ao_major_driver_no) {
-+              ao_context = file_p->private_data;
-+
-+              /* Mark DAC as unused */
-+              ao_context->dac_in_use = 0;
-+      } else if (MAJOR(inode_p->i_rdev) == me4000_ai_major_driver_no) {
-+              ai_context = file_p->private_data;
-+
-+              /* Reset the analog input */
-+              me4000_ai_reset(ai_context);
-+
-+              /* Free the interrupt and the circular buffer */
-+              if (ai_context->mode) {
-+                      free_irq(ai_context->irq, ai_context);
-+                      kfree(ai_context->circ_buf.buf);
-+                      ai_context->circ_buf.buf = NULL;
-+                      ai_context->circ_buf.head = 0;
-+                      ai_context->circ_buf.tail = 0;
-+              }
-+
-+              /* Mark AI as unused */
-+              ai_context->in_use = 0;
-+      } else if (MAJOR(inode_p->i_rdev) == me4000_dio_major_driver_no) {
-+              dio_context = file_p->private_data;
-+
-+              /* Mark digital I/O as unused */
-+              dio_context->in_use = 0;
-+      } else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) {
-+              cnt_context = file_p->private_data;
-+
-+              /* Mark counters as unused */
-+              cnt_context->in_use = 0;
-+      } else if (MAJOR(inode_p->i_rdev) == me4000_ext_int_major_driver_no) {
-+              ext_int_context = file_p->private_data;
-+
-+              /* Disable the externel interrupt */
-+              me4000_ext_int_disable(ext_int_context);
-+
-+              free_irq(ext_int_context->irq, ext_int_context);
-+
-+              /* Delete the fasync structure and free memory */
-+              me4000_ext_int_fasync(0, file_p, 0);
-+
-+              /* Mark as unused */
-+              ext_int_context->in_use = 0;
-+      } else {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_release():Major number unknown\n");
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+/*------------------------------- Analog output stuff --------------------------------------*/
-+
-+static int me4000_ao_prepare(me4000_ao_context_t * ao_context)
-+{
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_prepare() is executed\n");
-+
-+      if (ao_context->mode == ME4000_AO_CONV_MODE_CONTINUOUS) {
-+              /* Only do anything if not already in the correct mode */
-+              unsigned long mode = me4000_inl(ao_context->ctrl_reg);
-+              if ((mode & ME4000_AO_CONV_MODE_CONTINUOUS)
-+                  && (mode & ME4000_AO_CTRL_BIT_ENABLE_FIFO)) {
-+                      return 0;
-+              }
-+
-+              /* Stop any conversion */
-+              me4000_ao_immediate_stop(ao_context);
-+
-+              /* Set the control register to default state  */
-+              spin_lock_irqsave(&ao_context->int_lock, flags);
-+              me4000_outl(ME4000_AO_CONV_MODE_CONTINUOUS |
-+                          ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-+                          ME4000_AO_CTRL_BIT_STOP |
-+                          ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
-+                          ao_context->ctrl_reg);
-+              spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+              /* Set to fastest sample rate */
-+              me4000_outl(65, ao_context->timer_reg);
-+      } else if (ao_context->mode == ME4000_AO_CONV_MODE_WRAPAROUND) {
-+              /* Only do anything if not already in the correct mode */
-+              unsigned long mode = me4000_inl(ao_context->ctrl_reg);
-+              if ((mode & ME4000_AO_CONV_MODE_WRAPAROUND)
-+                  && (mode & ME4000_AO_CTRL_BIT_ENABLE_FIFO)) {
-+                      return 0;
-+              }
-+
-+              /* Stop any conversion */
-+              me4000_ao_immediate_stop(ao_context);
-+
-+              /* Set the control register to default state  */
-+              spin_lock_irqsave(&ao_context->int_lock, flags);
-+              me4000_outl(ME4000_AO_CONV_MODE_WRAPAROUND |
-+                          ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-+                          ME4000_AO_CTRL_BIT_STOP |
-+                          ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
-+                          ao_context->ctrl_reg);
-+              spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+              /* Set to fastest sample rate */
-+              me4000_outl(65, ao_context->timer_reg);
-+      } else if (ao_context->mode == ME4000_AO_CONV_MODE_SINGLE) {
-+              /* Only do anything if not already in the correct mode */
-+              unsigned long mode = me4000_inl(ao_context->ctrl_reg);
-+              if (!
-+                  (mode &
-+                   (ME4000_AO_CONV_MODE_WRAPAROUND |
-+                    ME4000_AO_CONV_MODE_CONTINUOUS))) {
-+                      return 0;
-+              }
-+
-+              /* Stop any conversion */
-+              me4000_ao_immediate_stop(ao_context);
-+
-+              /* Clear the control register */
-+              spin_lock_irqsave(&ao_context->int_lock, flags);
-+              me4000_outl(0x0, ao_context->ctrl_reg);
-+              spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+              /* Set voltage to 0V */
-+              me4000_outl(0x8000, ao_context->single_reg);
-+      } else {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ao_prepare():Invalid mode specified\n");
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_reset(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      wait_queue_head_t queue;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_reset() is executed\n");
-+
-+      init_waitqueue_head(&queue);
-+
-+      if (ao_context->mode == ME4000_AO_CONV_MODE_WRAPAROUND) {
-+              /*
-+               * First stop conversion of the DAC before reconfigure.
-+               * This is essantial, cause of the state machine.
-+               * If not stopped before configuring mode, it could
-+               * walk in a undefined state.
-+               */
-+              tmp = me4000_inl(ao_context->ctrl_reg);
-+              tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+
-+              while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-+                      sleep_on_timeout(&queue, 1);
-+              }
-+
-+              /* Set to transparent mode */
-+              me4000_ao_simultaneous_disable(ao_context);
-+
-+              /* Set to single mode in order to set default voltage */
-+              me4000_outl(0x0, ao_context->ctrl_reg);
-+
-+              /* Set voltage to 0V */
-+              me4000_outl(0x8000, ao_context->single_reg);
-+
-+              /* Set to fastest sample rate */
-+              me4000_outl(65, ao_context->timer_reg);
-+
-+              /* Set the original mode and enable FIFO */
-+              me4000_outl(ME4000_AO_CONV_MODE_WRAPAROUND |
-+                          ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-+                          ME4000_AO_CTRL_BIT_STOP |
-+                          ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
-+                          ao_context->ctrl_reg);
-+      } else if (ao_context->mode == ME4000_AO_CONV_MODE_CONTINUOUS) {
-+              /*
-+               * First stop conversion of the DAC before reconfigure.
-+               * This is essantial, cause of the state machine.
-+               * If not stopped before configuring mode, it could
-+               * walk in a undefined state.
-+               */
-+              spin_lock_irqsave(&ao_context->int_lock, flags);
-+              tmp = me4000_inl(ao_context->ctrl_reg);
-+              tmp |= ME4000_AO_CTRL_BIT_STOP;
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+              spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+              while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-+                      sleep_on_timeout(&queue, 1);
-+              }
-+
-+              /* Clear the circular buffer */
-+              ao_context->circ_buf.head = 0;
-+              ao_context->circ_buf.tail = 0;
-+
-+              /* Set to transparent mode */
-+              me4000_ao_simultaneous_disable(ao_context);
-+
-+              /* Set to single mode in order to set default voltage */
-+              spin_lock_irqsave(&ao_context->int_lock, flags);
-+              tmp = me4000_inl(ao_context->ctrl_reg);
-+              me4000_outl(0x0, ao_context->ctrl_reg);
-+
-+              /* Set voltage to 0V */
-+              me4000_outl(0x8000, ao_context->single_reg);
-+
-+              /* Set to fastest sample rate */
-+              me4000_outl(65, ao_context->timer_reg);
-+
-+              /* Set the original mode and enable FIFO */
-+              me4000_outl(ME4000_AO_CONV_MODE_CONTINUOUS |
-+                          ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-+                          ME4000_AO_CTRL_BIT_STOP |
-+                          ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
-+                          ao_context->ctrl_reg);
-+              spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+      } else {
-+              /* Set to transparent mode */
-+              me4000_ao_simultaneous_disable(ao_context);
-+
-+              /* Set voltage to 0V */
-+              me4000_outl(0x8000, ao_context->single_reg);
-+      }
-+
-+      return 0;
-+}
-+
-+static ssize_t me4000_ao_write_sing(struct file *filep, const char *buff,
-+                                  size_t cnt, loff_t * offp)
-+{
-+      me4000_ao_context_t *ao_context = filep->private_data;
-+      u32 value;
-+      const u16 *buffer = (const u16 *)buff;
-+
-+      CALL_PDEBUG("me4000_ao_write_sing() is executed\n");
-+
-+      if (cnt != 2) {
-+              printk(KERN_ERR
-+                     "me4000_ao_write_sing():Write count is not 2\n");
-+              return -EINVAL;
-+      }
-+
-+      if (get_user(value, buffer)) {
-+              printk(KERN_ERR
-+                     "me4000_ao_write_sing():Cannot copy data from user\n");
-+              return -EFAULT;
-+      }
-+
-+      me4000_outl(value, ao_context->single_reg);
-+
-+      return 2;
-+}
-+
-+static ssize_t me4000_ao_write_wrap(struct file *filep, const char *buff,
-+                                  size_t cnt, loff_t * offp)
-+{
-+      me4000_ao_context_t *ao_context = filep->private_data;
-+      size_t i;
-+      u32 value;
-+      u32 tmp;
-+      const u16 *buffer = (const u16 *)buff;
-+      size_t count = cnt / 2;
-+
-+      CALL_PDEBUG("me4000_ao_write_wrap() is executed\n");
-+
-+      /* Check if a conversion is already running */
-+      if (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ao_write_wrap():There is already a conversion running\n");
-+              return -EBUSY;
-+      }
-+
-+      if (count > ME4000_AO_FIFO_COUNT) {
-+              printk(KERN_ERR
-+                     "me4000_ao_write_wrap():Can't load more than %d values\n",
-+                     ME4000_AO_FIFO_COUNT);
-+              return -ENOSPC;
-+      }
-+
-+      /* Reset the FIFO */
-+      tmp = inl(ao_context->ctrl_reg);
-+      tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_FIFO;
-+      outl(tmp, ao_context->ctrl_reg);
-+      tmp |= ME4000_AO_CTRL_BIT_ENABLE_FIFO;
-+      outl(tmp, ao_context->ctrl_reg);
-+
-+      for (i = 0; i < count; i++) {
-+              if (get_user(value, buffer + i)) {
-+                      printk(KERN_ERR
-+                             "me4000_ao_write_single():Cannot copy data from user\n");
-+                      return -EFAULT;
-+              }
-+              if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG)
-+                  || ((ao_context->fifo_reg & 0xFF) == ME4000_AO_03_FIFO_REG))
-+                      value = value << 16;
-+              outl(value, ao_context->fifo_reg);
-+      }
-+      CALL_PDEBUG("me4000_ao_write_wrap() is leaved with %d\n", i * 2);
-+
-+      return i * 2;
-+}
-+
-+static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff,
-+                                  size_t cnt, loff_t * offp)
-+{
-+      me4000_ao_context_t *ao_context = filep->private_data;
-+      const u16 *buffer = (const u16 *)buff;
-+      size_t count = cnt / 2;
-+      unsigned long flags;
-+      u32 tmp;
-+      int c = 0;
-+      int k = 0;
-+      int ret = 0;
-+      u16 svalue;
-+      u32 lvalue;
-+      int i;
-+      wait_queue_head_t queue;
-+
-+      CALL_PDEBUG("me4000_ao_write_cont() is executed\n");
-+
-+      init_waitqueue_head(&queue);
-+
-+      /* Check count */
-+      if (count <= 0) {
-+              PDEBUG("me4000_ao_write_cont():Count is 0\n");
-+              return 0;
-+      }
-+
-+      if (filep->f_flags & O_APPEND) {
-+              PDEBUG("me4000_ao_write_cont():Append data to data stream\n");
-+              while (count > 0) {
-+                      if (filep->f_flags & O_NONBLOCK) {
-+                              if (ao_context->pipe_flag) {
-+                                      printk(KERN_ERR
-+                                             "ME4000:me4000_ao_write_cont():Broken pipe in nonblocking write\n");
-+                                      return -EPIPE;
-+                              }
-+                              c = me4000_space_to_end(ao_context->circ_buf,
-+                                                      ME4000_AO_BUFFER_COUNT);
-+                              if (!c) {
-+                                      PDEBUG
-+                                          ("me4000_ao_write_cont():Returning from nonblocking write\n");
-+                                      break;
-+                              }
-+                      } else {
-+                              wait_event_interruptible(ao_context->wait_queue,
-+                                                       (c =
-+                                                        me4000_space_to_end
-+                                                        (ao_context->circ_buf,
-+                                                         ME4000_AO_BUFFER_COUNT)));
-+                              if (ao_context->pipe_flag) {
-+                                      printk(KERN_ERR
-+                                             "me4000_ao_write_cont():Broken pipe in blocking write\n");
-+                                      return -EPIPE;
-+                              }
-+                              if (signal_pending(current)) {
-+                                      printk(KERN_ERR
-+                                             "me4000_ao_write_cont():Wait for free buffer interrupted from signal\n");
-+                                      return -EINTR;
-+                              }
-+                      }
-+
-+                      PDEBUG("me4000_ao_write_cont():Space to end = %d\n", c);
-+
-+                      /* Only able to write size of free buffer or size of count */
-+                      if (count < c)
-+                              c = count;
-+
-+                      k = 2 * c;
-+                      k -= copy_from_user(ao_context->circ_buf.buf +
-+                                          ao_context->circ_buf.head, buffer,
-+                                          k);
-+                      c = k / 2;
-+                      PDEBUG
-+                          ("me4000_ao_write_cont():Copy %d values from user space\n",
-+                           c);
-+
-+                      if (!c)
-+                              return -EFAULT;
-+
-+                      ao_context->circ_buf.head =
-+                          (ao_context->circ_buf.head +
-+                           c) & (ME4000_AO_BUFFER_COUNT - 1);
-+                      buffer += c;
-+                      count -= c;
-+                      ret += c;
-+
-+                      /* Values are now available so enable interrupts */
-+                      spin_lock_irqsave(&ao_context->int_lock, flags);
-+                      if (me4000_buf_count
-+                          (ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) {
-+                              tmp = me4000_inl(ao_context->ctrl_reg);
-+                              tmp |= ME4000_AO_CTRL_BIT_ENABLE_IRQ;
-+                              me4000_outl(tmp, ao_context->ctrl_reg);
-+                      }
-+                      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+              }
-+
-+              /* Wait until the state machine is stopped if O_SYNC is set */
-+              if (filep->f_flags & O_SYNC) {
-+                      while (inl(ao_context->status_reg) &
-+                             ME4000_AO_STATUS_BIT_FSM) {
-+                              interruptible_sleep_on_timeout(&queue, 1);
-+                              if (ao_context->pipe_flag) {
-+                                      PDEBUG
-+                                          ("me4000_ao_write_cont():Broken pipe detected after sync\n");
-+                                      return -EPIPE;
-+                              }
-+                              if (signal_pending(current)) {
-+                                      printk(KERN_ERR
-+                                             "me4000_ao_write_cont():Wait on state machine after sync interrupted\n");
-+                                      return -EINTR;
-+                              }
-+                      }
-+              }
-+      } else {
-+              PDEBUG("me4000_ao_write_cont():Preload DAC FIFO\n");
-+              if ((me4000_inl(ao_context->status_reg) &
-+                   ME4000_AO_STATUS_BIT_FSM)) {
-+                      printk(KERN_ERR
-+                             "me4000_ao_write_cont():Can't Preload DAC FIFO while conversion is running\n");
-+                      return -EBUSY;
-+              }
-+
-+              /* Clear the FIFO */
-+              spin_lock_irqsave(&ao_context->int_lock, flags);
-+              tmp = me4000_inl(ao_context->ctrl_reg);
-+              tmp &=
-+                  ~(ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-+                    ME4000_AO_CTRL_BIT_ENABLE_IRQ);
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+              tmp |= ME4000_AO_CTRL_BIT_ENABLE_FIFO;
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+              spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+              /* Clear the circular buffer */
-+              ao_context->circ_buf.head = 0;
-+              ao_context->circ_buf.tail = 0;
-+
-+              /* Reset the broken pipe flag */
-+              ao_context->pipe_flag = 0;
-+
-+              /* Only able to write size of fifo or count */
-+              c = ME4000_AO_FIFO_COUNT;
-+              if (count < c)
-+                      c = count;
-+
-+              PDEBUG
-+                  ("me4000_ao_write_cont():Write %d values to DAC on 0x%lX\n",
-+                   c, ao_context->fifo_reg);
-+
-+              /* Write values to the fifo */
-+              for (i = 0; i < c; i++) {
-+                      if (get_user(svalue, buffer))
-+                              return -EFAULT;
-+
-+                      if (((ao_context->fifo_reg & 0xFF) ==
-+                           ME4000_AO_01_FIFO_REG)
-+                          || ((ao_context->fifo_reg & 0xFF) ==
-+                              ME4000_AO_03_FIFO_REG)) {
-+                              lvalue = ((u32) svalue) << 16;
-+                      } else
-+                              lvalue = (u32) svalue;
-+
-+                      outl(lvalue, ao_context->fifo_reg);
-+                      buffer++;
-+              }
-+              count -= c;
-+              ret += c;
-+
-+              while (1) {
-+                      /* Get free buffer */
-+                      c = me4000_space_to_end(ao_context->circ_buf,
-+                                              ME4000_AO_BUFFER_COUNT);
-+
-+                      if (c == 0)
-+                              return (2 * ret);
-+
-+                      /* Only able to write size of free buffer or size of count */
-+                      if (count < c)
-+                              c = count;
-+
-+                      /* If count = 0 return to user */
-+                      if (c <= 0) {
-+                              PDEBUG
-+                                  ("me4000_ao_write_cont():Count reached 0\n");
-+                              break;
-+                      }
-+
-+                      k = 2 * c;
-+                      k -= copy_from_user(ao_context->circ_buf.buf +
-+                                          ao_context->circ_buf.head, buffer,
-+                                          k);
-+                      c = k / 2;
-+                      PDEBUG
-+                          ("me4000_ao_write_cont():Wrote %d values to buffer\n",
-+                           c);
-+
-+                      if (!c)
-+                              return -EFAULT;
-+
-+                      ao_context->circ_buf.head =
-+                          (ao_context->circ_buf.head +
-+                           c) & (ME4000_AO_BUFFER_COUNT - 1);
-+                      buffer += c;
-+                      count -= c;
-+                      ret += c;
-+
-+                      /* If values in the buffer are available so enable interrupts */
-+                      spin_lock_irqsave(&ao_context->int_lock, flags);
-+                      if (me4000_buf_count
-+                          (ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) {
-+                              PDEBUG
-+                                  ("me4000_ao_write_cont():Enable Interrupts\n");
-+                              tmp = me4000_inl(ao_context->ctrl_reg);
-+                              tmp |= ME4000_AO_CTRL_BIT_ENABLE_IRQ;
-+                              me4000_outl(tmp, ao_context->ctrl_reg);
-+                      }
-+                      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+              }
-+      }
-+
-+      if (filep->f_flags & O_NONBLOCK) {
-+              return (ret == 0) ? -EAGAIN : 2 * ret;
-+      }
-+
-+      return 2 * ret;
-+}
-+
-+static unsigned int me4000_ao_poll_cont(struct file *file_p, poll_table * wait)
-+{
-+      me4000_ao_context_t *ao_context;
-+      unsigned long mask = 0;
-+
-+      CALL_PDEBUG("me4000_ao_poll_cont() is executed\n");
-+
-+      ao_context = file_p->private_data;
-+
-+      poll_wait(file_p, &ao_context->wait_queue, wait);
-+
-+      /* Get free buffer */
-+      if (me4000_space_to_end(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT))
-+              mask |= POLLOUT | POLLWRNORM;
-+
-+      CALL_PDEBUG("me4000_ao_poll_cont():Return mask %lX\n", mask);
-+
-+      return mask;
-+}
-+
-+static int me4000_ao_fsync_cont(struct file *file_p, struct dentry *dentry_p,
-+                              int datasync)
-+{
-+      me4000_ao_context_t *ao_context;
-+      wait_queue_head_t queue;
-+
-+      CALL_PDEBUG("me4000_ao_fsync_cont() is executed\n");
-+
-+      ao_context = file_p->private_data;
-+      init_waitqueue_head(&queue);
-+
-+      while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-+              interruptible_sleep_on_timeout(&queue, 1);
-+              if (ao_context->pipe_flag) {
-+                      printk(KERN_ERR
-+                             "me4000_ao_fsync_cont():Broken pipe detected\n");
-+                      return -EPIPE;
-+              }
-+
-+              if (signal_pending(current)) {
-+                      printk(KERN_ERR
-+                             "me4000_ao_fsync_cont():Wait on state machine interrupted\n");
-+                      return -EINTR;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p,
-+                              unsigned int service, unsigned long arg)
-+{
-+      me4000_ao_context_t *ao_context;
-+
-+      CALL_PDEBUG("me4000_ao_ioctl_sing() is executed\n");
-+
-+      ao_context = file_p->private_data;
-+
-+      if (_IOC_TYPE(service) != ME4000_MAGIC) {
-+              return -ENOTTY;
-+              PDEBUG("me4000_ao_ioctl_sing():Wrong magic number\n");
-+      }
-+
-+      switch (service) {
-+      case ME4000_AO_EX_TRIG_SETUP:
-+              return me4000_ao_ex_trig_set_edge((int *)arg, ao_context);
-+      case ME4000_AO_EX_TRIG_ENABLE:
-+              return me4000_ao_ex_trig_enable(ao_context);
-+      case ME4000_AO_EX_TRIG_DISABLE:
-+              return me4000_ao_ex_trig_disable(ao_context);
-+      case ME4000_AO_PRELOAD:
-+              return me4000_ao_preload(ao_context);
-+      case ME4000_AO_PRELOAD_UPDATE:
-+              return me4000_ao_preload_update(ao_context);
-+      case ME4000_GET_USER_INFO:
-+              return me4000_get_user_info((me4000_user_info_t *) arg,
-+                                          ao_context->board_info);
-+      case ME4000_AO_SIMULTANEOUS_EX_TRIG:
-+              return me4000_ao_simultaneous_ex_trig(ao_context);
-+      case ME4000_AO_SIMULTANEOUS_SW:
-+              return me4000_ao_simultaneous_sw(ao_context);
-+      case ME4000_AO_SIMULTANEOUS_DISABLE:
-+              return me4000_ao_simultaneous_disable(ao_context);
-+      case ME4000_AO_SIMULTANEOUS_UPDATE:
-+              return
-+                  me4000_ao_simultaneous_update((me4000_ao_channel_list_t *)
-+                                                arg, ao_context);
-+      case ME4000_AO_EX_TRIG_TIMEOUT:
-+              return me4000_ao_ex_trig_timeout((unsigned long *)arg,
-+                                               ao_context);
-+      case ME4000_AO_DISABLE_DO:
-+              return me4000_ao_disable_do(ao_context);
-+      default:
-+              printk(KERN_ERR
-+                     "me4000_ao_ioctl_sing():Service number invalid\n");
-+              return -ENOTTY;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_ioctl_wrap(struct inode *inode_p, struct file *file_p,
-+                              unsigned int service, unsigned long arg)
-+{
-+      me4000_ao_context_t *ao_context;
-+
-+      CALL_PDEBUG("me4000_ao_ioctl_wrap() is executed\n");
-+
-+      ao_context = file_p->private_data;
-+
-+      if (_IOC_TYPE(service) != ME4000_MAGIC) {
-+              return -ENOTTY;
-+              PDEBUG("me4000_ao_ioctl_wrap():Wrong magic number\n");
-+      }
-+
-+      switch (service) {
-+      case ME4000_AO_START:
-+              return me4000_ao_start((unsigned long *)arg, ao_context);
-+      case ME4000_AO_STOP:
-+              return me4000_ao_stop(ao_context);
-+      case ME4000_AO_IMMEDIATE_STOP:
-+              return me4000_ao_immediate_stop(ao_context);
-+      case ME4000_AO_RESET:
-+              return me4000_ao_reset(ao_context);
-+      case ME4000_AO_TIMER_SET_DIVISOR:
-+              return me4000_ao_timer_set_divisor((u32 *) arg, ao_context);
-+      case ME4000_AO_EX_TRIG_SETUP:
-+              return me4000_ao_ex_trig_set_edge((int *)arg, ao_context);
-+      case ME4000_AO_EX_TRIG_ENABLE:
-+              return me4000_ao_ex_trig_enable(ao_context);
-+      case ME4000_AO_EX_TRIG_DISABLE:
-+              return me4000_ao_ex_trig_disable(ao_context);
-+      case ME4000_GET_USER_INFO:
-+              return me4000_get_user_info((me4000_user_info_t *) arg,
-+                                          ao_context->board_info);
-+      case ME4000_AO_FSM_STATE:
-+              return me4000_ao_fsm_state((int *)arg, ao_context);
-+      case ME4000_AO_ENABLE_DO:
-+              return me4000_ao_enable_do(ao_context);
-+      case ME4000_AO_DISABLE_DO:
-+              return me4000_ao_disable_do(ao_context);
-+      case ME4000_AO_SYNCHRONOUS_EX_TRIG:
-+              return me4000_ao_synchronous_ex_trig(ao_context);
-+      case ME4000_AO_SYNCHRONOUS_SW:
-+              return me4000_ao_synchronous_sw(ao_context);
-+      case ME4000_AO_SYNCHRONOUS_DISABLE:
-+              return me4000_ao_synchronous_disable(ao_context);
-+      default:
-+              return -ENOTTY;
-+      }
-+      return 0;
-+}
-+
-+static int me4000_ao_ioctl_cont(struct inode *inode_p, struct file *file_p,
-+                              unsigned int service, unsigned long arg)
-+{
-+      me4000_ao_context_t *ao_context;
-+
-+      CALL_PDEBUG("me4000_ao_ioctl_cont() is executed\n");
-+
-+      ao_context = file_p->private_data;
-+
-+      if (_IOC_TYPE(service) != ME4000_MAGIC) {
-+              return -ENOTTY;
-+              PDEBUG("me4000_ao_ioctl_cont():Wrong magic number\n");
-+      }
-+
-+      switch (service) {
-+      case ME4000_AO_START:
-+              return me4000_ao_start((unsigned long *)arg, ao_context);
-+      case ME4000_AO_STOP:
-+              return me4000_ao_stop(ao_context);
-+      case ME4000_AO_IMMEDIATE_STOP:
-+              return me4000_ao_immediate_stop(ao_context);
-+      case ME4000_AO_RESET:
-+              return me4000_ao_reset(ao_context);
-+      case ME4000_AO_TIMER_SET_DIVISOR:
-+              return me4000_ao_timer_set_divisor((u32 *) arg, ao_context);
-+      case ME4000_AO_EX_TRIG_SETUP:
-+              return me4000_ao_ex_trig_set_edge((int *)arg, ao_context);
-+      case ME4000_AO_EX_TRIG_ENABLE:
-+              return me4000_ao_ex_trig_enable(ao_context);
-+      case ME4000_AO_EX_TRIG_DISABLE:
-+              return me4000_ao_ex_trig_disable(ao_context);
-+      case ME4000_AO_ENABLE_DO:
-+              return me4000_ao_enable_do(ao_context);
-+      case ME4000_AO_DISABLE_DO:
-+              return me4000_ao_disable_do(ao_context);
-+      case ME4000_AO_FSM_STATE:
-+              return me4000_ao_fsm_state((int *)arg, ao_context);
-+      case ME4000_GET_USER_INFO:
-+              return me4000_get_user_info((me4000_user_info_t *) arg,
-+                                          ao_context->board_info);
-+      case ME4000_AO_SYNCHRONOUS_EX_TRIG:
-+              return me4000_ao_synchronous_ex_trig(ao_context);
-+      case ME4000_AO_SYNCHRONOUS_SW:
-+              return me4000_ao_synchronous_sw(ao_context);
-+      case ME4000_AO_SYNCHRONOUS_DISABLE:
-+              return me4000_ao_synchronous_disable(ao_context);
-+      case ME4000_AO_GET_FREE_BUFFER:
-+              return me4000_ao_get_free_buffer((unsigned long *)arg,
-+                                               ao_context);
-+      default:
-+              return -ENOTTY;
-+      }
-+      return 0;
-+}
-+
-+static int me4000_ao_start(unsigned long *arg, me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      wait_queue_head_t queue;
-+      unsigned long ref;
-+      unsigned long timeout;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_start() is executed\n");
-+
-+      if (get_user(timeout, arg)) {
-+              printk(KERN_ERR
-+                     "me4000_ao_start():Cannot copy data from user\n");
-+              return -EFAULT;
-+      }
-+
-+      init_waitqueue_head(&queue);
-+
-+      spin_lock_irqsave(&ao_context->int_lock, flags);
-+      tmp = inl(ao_context->ctrl_reg);
-+      tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+      if ((tmp & ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG)) {
-+              if (timeout) {
-+                      ref = jiffies;
-+                      while (!
-+                             (inl(ao_context->status_reg) &
-+                              ME4000_AO_STATUS_BIT_FSM)) {
-+                              interruptible_sleep_on_timeout(&queue, 1);
-+                              if (signal_pending(current)) {
-+                                      printk(KERN_ERR
-+                                             "ME4000:me4000_ao_start():Wait on start of state machine interrupted\n");
-+                                      return -EINTR;
-+                              }
-+                              if (((jiffies - ref) > (timeout * HZ / USER_HZ))) {     // 2.6 has diffrent definitions for HZ in user and kernel space
-+                                      printk(KERN_ERR
-+                                             "ME4000:me4000_ao_start():Timeout reached\n");
-+                                      return -EIO;
-+                              }
-+                      }
-+              }
-+      } else {
-+              me4000_outl(0x8000, ao_context->single_reg);
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_stop(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      wait_queue_head_t queue;
-+      unsigned long flags;
-+
-+      init_waitqueue_head(&queue);
-+
-+      CALL_PDEBUG("me4000_ao_stop() is executed\n");
-+
-+      /* Set the stop bit */
-+      spin_lock_irqsave(&ao_context->int_lock, flags);
-+      tmp = inl(ao_context->ctrl_reg);
-+      tmp |= ME4000_AO_CTRL_BIT_STOP;
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+      while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-+              interruptible_sleep_on_timeout(&queue, 1);
-+              if (signal_pending(current)) {
-+                      printk(KERN_ERR
-+                             "me4000_ao_stop():Wait on state machine after stop interrupted\n");
-+                      return -EINTR;
-+              }
-+      }
-+
-+      /* Clear the stop bit */
-+      //tmp &= ~ME4000_AO_CTRL_BIT_STOP;
-+      //me4000_outl(tmp, ao_context->ctrl_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_immediate_stop(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      wait_queue_head_t queue;
-+      unsigned long flags;
-+
-+      init_waitqueue_head(&queue);
-+
-+      CALL_PDEBUG("me4000_ao_immediate_stop() is executed\n");
-+
-+      spin_lock_irqsave(&ao_context->int_lock, flags);
-+      tmp = inl(ao_context->ctrl_reg);
-+      tmp |= ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+      while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-+              interruptible_sleep_on_timeout(&queue, 1);
-+              if (signal_pending(current)) {
-+                      printk(KERN_ERR
-+                             "me4000_ao_immediate_stop():Wait on state machine after stop interrupted\n");
-+                      return -EINTR;
-+              }
-+      }
-+
-+      /* Clear the stop bits */
-+      //tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
-+      //me4000_outl(tmp, ao_context->ctrl_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_timer_set_divisor(u32 * arg,
-+                                     me4000_ao_context_t * ao_context)
-+{
-+      u32 divisor;
-+      u32 tmp;
-+
-+      CALL_PDEBUG("me4000_ao_timer set_divisor() is executed\n");
-+
-+      if (get_user(divisor, arg))
-+              return -EFAULT;
-+
-+      /* Check if the state machine is stopped */
-+      tmp = me4000_inl(ao_context->status_reg);
-+      if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR
-+                     "me4000_ao_timer_set_divisor():Can't set timer while DAC is running\n");
-+              return -EBUSY;
-+      }
-+
-+      PDEBUG("me4000_ao_timer set_divisor():Divisor from user = %d\n",
-+             divisor);
-+
-+      /* Check if the divisor is right. ME4000_AO_MIN_TICKS is the lowest */
-+      if (divisor < ME4000_AO_MIN_TICKS) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ao_timer set_divisor():Divisor to low\n");
-+              return -EINVAL;
-+      }
-+
-+      /* Fix bug in Firmware */
-+      divisor -= 2;
-+
-+      PDEBUG("me4000_ao_timer set_divisor():Divisor to HW = %d\n", divisor);
-+
-+      /* Write the divisor */
-+      me4000_outl(divisor, ao_context->timer_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_ex_trig_set_edge(int *arg,
-+                                    me4000_ao_context_t * ao_context)
-+{
-+      int mode;
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_ex_trig_set_edge() is executed\n");
-+
-+      if (get_user(mode, arg))
-+              return -EFAULT;
-+
-+      /* Check if the state machine is stopped */
-+      tmp = me4000_inl(ao_context->status_reg);
-+      if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR
-+                     "me4000_ao_ex_trig_set_edge():Can't set trigger while DAC is running\n");
-+              return -EBUSY;
-+      }
-+
-+      if (mode == ME4000_AO_TRIGGER_EXT_EDGE_RISING) {
-+              spin_lock_irqsave(&ao_context->int_lock, flags);
-+              tmp = me4000_inl(ao_context->ctrl_reg);
-+              tmp &=
-+                  ~(ME4000_AO_CTRL_BIT_EX_TRIG_EDGE |
-+                    ME4000_AO_CTRL_BIT_EX_TRIG_BOTH);
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+              spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+      } else if (mode == ME4000_AO_TRIGGER_EXT_EDGE_FALLING) {
-+              spin_lock_irqsave(&ao_context->int_lock, flags);
-+              tmp = me4000_inl(ao_context->ctrl_reg);
-+              tmp &= ~ME4000_AO_CTRL_BIT_EX_TRIG_BOTH;
-+              tmp |= ME4000_AO_CTRL_BIT_EX_TRIG_EDGE;
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+              spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+      } else if (mode == ME4000_AO_TRIGGER_EXT_EDGE_BOTH) {
-+              spin_lock_irqsave(&ao_context->int_lock, flags);
-+              tmp = me4000_inl(ao_context->ctrl_reg);
-+              tmp |=
-+                  ME4000_AO_CTRL_BIT_EX_TRIG_EDGE |
-+                  ME4000_AO_CTRL_BIT_EX_TRIG_BOTH;
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+              spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+      } else {
-+              printk(KERN_ERR
-+                     "me4000_ao_ex_trig_set_edge():Invalid trigger mode\n");
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_ex_trig_enable(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_ex_trig_enable() is executed\n");
-+
-+      /* Check if the state machine is stopped */
-+      tmp = me4000_inl(ao_context->status_reg);
-+      if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR
-+                     "me4000_ao_ex_trig_enable():Can't enable trigger while DAC is running\n");
-+              return -EBUSY;
-+      }
-+
-+      spin_lock_irqsave(&ao_context->int_lock, flags);
-+      tmp = me4000_inl(ao_context->ctrl_reg);
-+      tmp |= ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_ex_trig_disable(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_ex_trig_disable() is executed\n");
-+
-+      /* Check if the state machine is stopped */
-+      tmp = me4000_inl(ao_context->status_reg);
-+      if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR
-+                     "me4000_ao_ex_trig_disable():Can't disable trigger while DAC is running\n");
-+              return -EBUSY;
-+      }
-+
-+      spin_lock_irqsave(&ao_context->int_lock, flags);
-+      tmp = me4000_inl(ao_context->ctrl_reg);
-+      tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_simultaneous_disable(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+
-+      CALL_PDEBUG("me4000_ao_simultaneous_disable() is executed\n");
-+
-+      /* Check if the state machine is stopped */
-+      /* Be careful here because this function is called from
-+         me4000_ao_synchronous disable */
-+      tmp = me4000_inl(ao_context->status_reg);
-+      if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR
-+                     "me4000_ao_simultaneous_disable():Can't disable while DAC is running\n");
-+              return -EBUSY;
-+      }
-+
-+      spin_lock(&ao_context->board_info->preload_lock);
-+      tmp = me4000_inl(ao_context->preload_reg);
-+      tmp &= ~(0x1 << ao_context->index);     // Disable preload bit
-+      tmp &= ~(0x1 << (ao_context->index + 16));      // Disable hw simultaneous bit
-+      me4000_outl(tmp, ao_context->preload_reg);
-+      spin_unlock(&ao_context->board_info->preload_lock);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_simultaneous_ex_trig(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+
-+      CALL_PDEBUG("me4000_ao_simultaneous_ex_trig() is executed\n");
-+
-+      spin_lock(&ao_context->board_info->preload_lock);
-+      tmp = me4000_inl(ao_context->preload_reg);
-+      tmp |= (0x1 << ao_context->index);      // Enable preload bit
-+      tmp |= (0x1 << (ao_context->index + 16));       // Enable hw simultaneous bit
-+      me4000_outl(tmp, ao_context->preload_reg);
-+      spin_unlock(&ao_context->board_info->preload_lock);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_simultaneous_sw(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+
-+      CALL_PDEBUG("me4000_ao_simultaneous_sw() is executed\n");
-+
-+      spin_lock(&ao_context->board_info->preload_lock);
-+      tmp = me4000_inl(ao_context->preload_reg);
-+      tmp |= (0x1 << ao_context->index);      // Enable preload bit
-+      tmp &= ~(0x1 << (ao_context->index + 16));      // Disable hw simultaneous bit
-+      me4000_outl(tmp, ao_context->preload_reg);
-+      spin_unlock(&ao_context->board_info->preload_lock);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_preload(me4000_ao_context_t * ao_context)
-+{
-+      CALL_PDEBUG("me4000_ao_preload() is executed\n");
-+      return me4000_ao_simultaneous_sw(ao_context);
-+}
-+
-+static int me4000_ao_preload_update(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      u32 ctrl;
-+      struct list_head *entry;
-+
-+      CALL_PDEBUG("me4000_ao_preload_update() is executed\n");
-+
-+      spin_lock(&ao_context->board_info->preload_lock);
-+      tmp = me4000_inl(ao_context->preload_reg);
-+      list_for_each(entry, &ao_context->board_info->ao_context_list) {
-+              /* The channels we update must be in the following state :
-+                 - Mode A
-+                 - Hardware trigger is disabled
-+                 - Corresponding simultaneous bit is reset
-+               */
-+              ctrl = me4000_inl(ao_context->ctrl_reg);
-+              if (!
-+                  (ctrl &
-+                   (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1 |
-+                    ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG))) {
-+                      if (!
-+                          (tmp &
-+                           (0x1 <<
-+                            (((me4000_ao_context_t *) entry)->index + 16)))) {
-+                              tmp &=
-+                                  ~(0x1 <<
-+                                    (((me4000_ao_context_t *) entry)->index));
-+                      }
-+              }
-+      }
-+      me4000_outl(tmp, ao_context->preload_reg);
-+      spin_unlock(&ao_context->board_info->preload_lock);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_simultaneous_update(me4000_ao_channel_list_t * arg,
-+                                       me4000_ao_context_t * ao_context)
-+{
-+      int err;
-+      int i;
-+      u32 tmp;
-+      me4000_ao_channel_list_t channels;
-+
-+      CALL_PDEBUG("me4000_ao_simultaneous_update() is executed\n");
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&channels, arg, sizeof(me4000_ao_channel_list_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ao_simultaneous_update():Can't copy command\n");
-+              return -EFAULT;
-+      }
-+
-+      channels.list =
-+          kmalloc(sizeof(unsigned long) * channels.count, GFP_KERNEL);
-+      if (!channels.list) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ao_simultaneous_update():Can't get buffer\n");
-+              return -ENOMEM;
-+      }
-+      memset(channels.list, 0, sizeof(unsigned long) * channels.count);
-+
-+      /* Copy channel list from user */
-+      err =
-+          copy_from_user(channels.list, arg->list,
-+                         sizeof(unsigned long) * channels.count);
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ao_simultaneous_update():Can't copy list\n");
-+              kfree(channels.list);
-+              return -EFAULT;
-+      }
-+
-+      spin_lock(&ao_context->board_info->preload_lock);
-+      tmp = me4000_inl(ao_context->preload_reg);
-+      for (i = 0; i < channels.count; i++) {
-+              if (channels.list[i] >
-+                  ao_context->board_info->board_p->ao.count) {
-+                      spin_unlock(&ao_context->board_info->preload_lock);
-+                      kfree(channels.list);
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ao_simultaneous_update():Invalid board number specified\n");
-+                      return -EFAULT;
-+              }
-+              tmp &= ~(0x1 << channels.list[i]);      // Clear the preload bit
-+              tmp &= ~(0x1 << (channels.list[i] + 16));       // Clear the hw simultaneous bit
-+      }
-+      me4000_outl(tmp, ao_context->preload_reg);
-+      spin_unlock(&ao_context->board_info->preload_lock);
-+      kfree(channels.list);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_synchronous_ex_trig(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_synchronous_ex_trig() is executed\n");
-+
-+      /* Check if the state machine is stopped */
-+      tmp = me4000_inl(ao_context->status_reg);
-+      if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR
-+                     "me4000_ao_synchronous_ex_trig(): DAC is running\n");
-+              return -EBUSY;
-+      }
-+
-+      spin_lock(&ao_context->board_info->preload_lock);
-+      tmp = me4000_inl(ao_context->preload_reg);
-+      tmp &= ~(0x1 << ao_context->index);     // Disable synchronous sw bit
-+      tmp |= 0x1 << (ao_context->index + 16); // Enable synchronous hw bit
-+      me4000_outl(tmp, ao_context->preload_reg);
-+      spin_unlock(&ao_context->board_info->preload_lock);
-+
-+      /* Make runnable */
-+      spin_lock_irqsave(&ao_context->int_lock, flags);
-+      tmp = me4000_inl(ao_context->ctrl_reg);
-+      if (tmp & (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1)) {
-+              tmp &=
-+                  ~(ME4000_AO_CTRL_BIT_STOP |
-+                    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+      }
-+      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_synchronous_sw(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_synchronous_sw() is executed\n");
-+
-+      /* Check if the state machine is stopped */
-+      tmp = me4000_inl(ao_context->status_reg);
-+      if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR "me4000_ao_synchronous_sw(): DAC is running\n");
-+              return -EBUSY;
-+      }
-+
-+      spin_lock(&ao_context->board_info->preload_lock);
-+      tmp = me4000_inl(ao_context->preload_reg);
-+      tmp |= 0x1 << ao_context->index;        // Enable synchronous sw bit
-+      tmp &= ~(0x1 << (ao_context->index + 16));      // Disable synchronous hw bit
-+      me4000_outl(tmp, ao_context->preload_reg);
-+      spin_unlock(&ao_context->board_info->preload_lock);
-+
-+      /* Make runnable */
-+      spin_lock_irqsave(&ao_context->int_lock, flags);
-+      tmp = me4000_inl(ao_context->ctrl_reg);
-+      if (tmp & (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1)) {
-+              tmp &=
-+                  ~(ME4000_AO_CTRL_BIT_STOP |
-+                    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+      }
-+      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_synchronous_disable(me4000_ao_context_t * ao_context)
-+{
-+      return me4000_ao_simultaneous_disable(ao_context);
-+}
-+
-+static int me4000_ao_get_free_buffer(unsigned long *arg,
-+                                   me4000_ao_context_t * ao_context)
-+{
-+      unsigned long c;
-+      int err;
-+
-+      c = me4000_buf_space(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT);
-+
-+      err = copy_to_user(arg, &c, sizeof(unsigned long));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ao_get_free_buffer():Can't copy to user space\n");
-+              return -EFAULT;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_ex_trig_timeout(unsigned long *arg,
-+                                   me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      wait_queue_head_t queue;
-+      unsigned long ref;
-+      unsigned long timeout;
-+
-+      CALL_PDEBUG("me4000_ao_ex_trig_timeout() is executed\n");
-+
-+      if (get_user(timeout, arg)) {
-+              printk(KERN_ERR
-+                     "me4000_ao_ex_trig_timeout():Cannot copy data from user\n");
-+              return -EFAULT;
-+      }
-+
-+      init_waitqueue_head(&queue);
-+
-+      tmp = inl(ao_context->ctrl_reg);
-+
-+      if ((tmp & ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG)) {
-+              if (timeout) {
-+                      ref = jiffies;
-+                      while ((inl(ao_context->status_reg) &
-+                              ME4000_AO_STATUS_BIT_FSM)) {
-+                              interruptible_sleep_on_timeout(&queue, 1);
-+                              if (signal_pending(current)) {
-+                                      printk(KERN_ERR
-+                                             "ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n");
-+                                      return -EINTR;
-+                              }
-+                              if (((jiffies - ref) > (timeout * HZ / USER_HZ))) {     // 2.6 has diffrent definitions for HZ in user and kernel space
-+                                      printk(KERN_ERR
-+                                             "ME4000:me4000_ao_ex_trig_timeout():Timeout reached\n");
-+                                      return -EIO;
-+                              }
-+                      }
-+              } else {
-+                      while ((inl(ao_context->status_reg) &
-+                              ME4000_AO_STATUS_BIT_FSM)) {
-+                              interruptible_sleep_on_timeout(&queue, 1);
-+                              if (signal_pending(current)) {
-+                                      printk(KERN_ERR
-+                                             "ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n");
-+                                      return -EINTR;
-+                              }
-+                      }
-+              }
-+      } else {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ao_ex_trig_timeout():External Trigger is not enabled\n");
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_enable_do(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_enable_do() is executed\n");
-+
-+      /* Only available for analog output 3 */
-+      if (ao_context->index != 3) {
-+              printk(KERN_ERR
-+                     "me4000_ao_enable_do():Only available for analog output 3\n");
-+              return -ENOTTY;
-+      }
-+
-+      /* Check if the state machine is stopped */
-+      tmp = me4000_inl(ao_context->status_reg);
-+      if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR "me4000_ao_enable_do(): DAC is running\n");
-+              return -EBUSY;
-+      }
-+
-+      /* Set the stop bit */
-+      spin_lock_irqsave(&ao_context->int_lock, flags);
-+      tmp = inl(ao_context->ctrl_reg);
-+      tmp |= ME4000_AO_CTRL_BIT_ENABLE_DO;
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_disable_do(me4000_ao_context_t * ao_context)
-+{
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ao_disable_do() is executed\n");
-+
-+      /* Only available for analog output 3 */
-+      if (ao_context->index != 3) {
-+              printk(KERN_ERR
-+                     "me4000_ao_disable():Only available for analog output 3\n");
-+              return -ENOTTY;
-+      }
-+
-+      /* Check if the state machine is stopped */
-+      tmp = me4000_inl(ao_context->status_reg);
-+      if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-+              printk(KERN_ERR "me4000_ao_disable_do(): DAC is running\n");
-+              return -EBUSY;
-+      }
-+
-+      spin_lock_irqsave(&ao_context->int_lock, flags);
-+      tmp = inl(ao_context->ctrl_reg);
-+      tmp &= ~(ME4000_AO_CTRL_BIT_ENABLE_DO);
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ao_context->int_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int me4000_ao_fsm_state(int *arg, me4000_ao_context_t * ao_context)
-+{
-+      unsigned long tmp;
-+
-+      CALL_PDEBUG("me4000_ao_fsm_state() is executed\n");
-+
-+      tmp =
-+          (me4000_inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) ? 1
-+          : 0;
-+
-+      if (ao_context->pipe_flag) {
-+              printk(KERN_ERR "me4000_ao_fsm_state():Broken pipe detected\n");
-+              return -EPIPE;
-+      }
-+
-+      if (put_user(tmp, arg)) {
-+              printk(KERN_ERR "me4000_ao_fsm_state():Cannot copy to user\n");
-+              return -EFAULT;
-+      }
-+
-+      return 0;
-+}
-+
-+/*------------------------------- Analog input stuff --------------------------------------*/
-+
-+static int me4000_ai_prepare(me4000_ai_context_t * ai_context)
-+{
-+      wait_queue_head_t queue;
-+      int err;
-+
-+      CALL_PDEBUG("me4000_ai_prepare() is executed\n");
-+
-+      init_waitqueue_head(&queue);
-+
-+      /* Set the new mode and stop bits */
-+      me4000_outl(ai_context->
-+                  mode | ME4000_AI_CTRL_BIT_STOP |
-+                  ME4000_AI_CTRL_BIT_IMMEDIATE_STOP, ai_context->ctrl_reg);
-+
-+      /* Set the timer registers */
-+      ai_context->chan_timer = 66;
-+      ai_context->chan_pre_timer = 66;
-+      ai_context->scan_timer_low = 0;
-+      ai_context->scan_timer_high = 0;
-+
-+      me4000_outl(65, ai_context->chan_timer_reg);
-+      me4000_outl(65, ai_context->chan_pre_timer_reg);
-+      me4000_outl(0, ai_context->scan_timer_low_reg);
-+      me4000_outl(0, ai_context->scan_timer_high_reg);
-+      me4000_outl(0, ai_context->scan_pre_timer_low_reg);
-+      me4000_outl(0, ai_context->scan_pre_timer_high_reg);
-+
-+      ai_context->channel_list_count = 0;
-+
-+      if (ai_context->mode) {
-+              /* Request the interrupt line */
-+              err =
-+                  request_irq(ai_context->irq, me4000_ai_isr,
-+                              IRQF_DISABLED | IRQF_SHARED, ME4000_NAME,
-+                              ai_context);
-+              if (err) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_prepare():Can't get interrupt line");
-+                      return -ENODEV;
-+              }
-+
-+              /* Allocate circular buffer */
-+              ai_context->circ_buf.buf =
-+                  kmalloc(ME4000_AI_BUFFER_SIZE, GFP_KERNEL);
-+              if (!ai_context->circ_buf.buf) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_prepare():Can't get circular buffer\n");
-+                      free_irq(ai_context->irq, ai_context);
-+                      return -ENOMEM;
-+              }
-+              memset(ai_context->circ_buf.buf, 0, ME4000_AI_BUFFER_SIZE);
-+
-+              /* Clear the circular buffer */
-+              ai_context->circ_buf.head = 0;
-+              ai_context->circ_buf.tail = 0;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_reset(me4000_ai_context_t * ai_context)
-+{
-+      wait_queue_head_t queue;
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ai_reset() is executed\n");
-+
-+      init_waitqueue_head(&queue);
-+
-+      /*
-+       * First stop conversion of the state machine before reconfigure.
-+       * If not stopped before configuring mode, it could
-+       * walk in a undefined state.
-+       */
-+      spin_lock_irqsave(&ai_context->int_lock, flags);
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+
-+      while (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) {
-+              interruptible_sleep_on_timeout(&queue, 1);
-+              if (signal_pending(current)) {
-+                      printk(KERN_ERR
-+                             "me4000_ai_reset():Wait on state machine after stop interrupted\n");
-+                      return -EINTR;
-+              }
-+      }
-+
-+      /* Clear the control register and set the stop bits */
-+      spin_lock_irqsave(&ai_context->int_lock, flags);
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      me4000_outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
-+                  ai_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+
-+      /* Reset timer registers */
-+      ai_context->chan_timer = 66;
-+      ai_context->chan_pre_timer = 66;
-+      ai_context->scan_timer_low = 0;
-+      ai_context->scan_timer_high = 0;
-+      ai_context->sample_counter = 0;
-+      ai_context->sample_counter_reload = 0;
-+
-+      me4000_outl(65, ai_context->chan_timer_reg);
-+      me4000_outl(65, ai_context->chan_pre_timer_reg);
-+      me4000_outl(0, ai_context->scan_timer_low_reg);
-+      me4000_outl(0, ai_context->scan_timer_high_reg);
-+      me4000_outl(0, ai_context->scan_pre_timer_low_reg);
-+      me4000_outl(0, ai_context->scan_pre_timer_high_reg);
-+      me4000_outl(0, ai_context->sample_counter_reg);
-+
-+      ai_context->channel_list_count = 0;
-+
-+      /* Clear the circular buffer */
-+      ai_context->circ_buf.head = 0;
-+      ai_context->circ_buf.tail = 0;
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_ioctl_sing(struct inode *inode_p, struct file *file_p,
-+                              unsigned int service, unsigned long arg)
-+{
-+      me4000_ai_context_t *ai_context;
-+
-+      CALL_PDEBUG("me4000_ai_ioctl_sing() is executed\n");
-+
-+      ai_context = file_p->private_data;
-+
-+      if (_IOC_TYPE(service) != ME4000_MAGIC) {
-+              printk(KERN_ERR "me4000_ai_ioctl_sing():Wrong magic number\n");
-+              return -ENOTTY;
-+      }
-+      if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-+              printk(KERN_ERR
-+                     "me4000_ai_ioctl_sing():Service number to high\n");
-+              return -ENOTTY;
-+      }
-+
-+      switch (service) {
-+      case ME4000_AI_SINGLE:
-+              return me4000_ai_single((me4000_ai_single_t *) arg, ai_context);
-+      case ME4000_AI_EX_TRIG_ENABLE:
-+              return me4000_ai_ex_trig_enable(ai_context);
-+      case ME4000_AI_EX_TRIG_DISABLE:
-+              return me4000_ai_ex_trig_disable(ai_context);
-+      case ME4000_AI_EX_TRIG_SETUP:
-+              return me4000_ai_ex_trig_setup((me4000_ai_trigger_t *) arg,
-+                                             ai_context);
-+      case ME4000_GET_USER_INFO:
-+              return me4000_get_user_info((me4000_user_info_t *) arg,
-+                                          ai_context->board_info);
-+      case ME4000_AI_OFFSET_ENABLE:
-+              return me4000_ai_offset_enable(ai_context);
-+      case ME4000_AI_OFFSET_DISABLE:
-+              return me4000_ai_offset_disable(ai_context);
-+      case ME4000_AI_FULLSCALE_ENABLE:
-+              return me4000_ai_fullscale_enable(ai_context);
-+      case ME4000_AI_FULLSCALE_DISABLE:
-+              return me4000_ai_fullscale_disable(ai_context);
-+      case ME4000_AI_EEPROM_READ:
-+              return me4000_eeprom_read((me4000_eeprom_t *) arg, ai_context);
-+      case ME4000_AI_EEPROM_WRITE:
-+              return me4000_eeprom_write((me4000_eeprom_t *) arg, ai_context);
-+      default:
-+              printk(KERN_ERR
-+                     "me4000_ai_ioctl_sing():Invalid service number\n");
-+              return -ENOTTY;
-+      }
-+      return 0;
-+}
-+
-+static int me4000_ai_single(me4000_ai_single_t * arg,
-+                          me4000_ai_context_t * ai_context)
-+{
-+      me4000_ai_single_t cmd;
-+      int err;
-+      u32 tmp;
-+      wait_queue_head_t queue;
-+      unsigned long jiffy;
-+
-+      CALL_PDEBUG("me4000_ai_single() is executed\n");
-+
-+      init_waitqueue_head(&queue);
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_ai_single_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_single():Can't copy from user space\n");
-+              return -EFAULT;
-+      }
-+
-+      /* Check range parameter */
-+      switch (cmd.range) {
-+      case ME4000_AI_LIST_RANGE_BIPOLAR_10:
-+      case ME4000_AI_LIST_RANGE_BIPOLAR_2_5:
-+      case ME4000_AI_LIST_RANGE_UNIPOLAR_10:
-+      case ME4000_AI_LIST_RANGE_UNIPOLAR_2_5:
-+              break;
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_single():Invalid range specified\n");
-+              return -EINVAL;
-+      }
-+
-+      /* Check mode and channel number */
-+      switch (cmd.mode) {
-+      case ME4000_AI_LIST_INPUT_SINGLE_ENDED:
-+              if (cmd.channel >= ai_context->board_info->board_p->ai.count) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_single():Analog input is not available\n");
-+                      return -EINVAL;
-+              }
-+              break;
-+      case ME4000_AI_LIST_INPUT_DIFFERENTIAL:
-+              if (cmd.channel >=
-+                  ai_context->board_info->board_p->ai.diff_count) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_single():Analog input is not available in differential mode\n");
-+                      return -EINVAL;
-+              }
-+              break;
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_single():Invalid mode specified\n");
-+              return -EINVAL;
-+      }
-+
-+      /* Clear channel list, data fifo and both stop bits */
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp &=
-+          ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO |
-+            ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+
-+      /* Enable channel list and data fifo */
-+      tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+
-+      /* Generate channel list entry */
-+      me4000_outl(cmd.channel | cmd.range | cmd.
-+                  mode | ME4000_AI_LIST_LAST_ENTRY,
-+                  ai_context->channel_list_reg);
-+
-+      /* Set the timer to maximum */
-+      me4000_outl(66, ai_context->chan_timer_reg);
-+      me4000_outl(66, ai_context->chan_pre_timer_reg);
-+
-+      if (tmp & ME4000_AI_CTRL_BIT_EX_TRIG) {
-+              jiffy = jiffies;
-+              while (!
-+                     (me4000_inl(ai_context->status_reg) &
-+                      ME4000_AI_STATUS_BIT_EF_DATA)) {
-+                      interruptible_sleep_on_timeout(&queue, 1);
-+                      if (signal_pending(current)) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_single():Wait on start of state machine interrupted\n");
-+                              return -EINTR;
-+                      }
-+                      if (((jiffies - jiffy) > (cmd.timeout * HZ / USER_HZ)) && cmd.timeout) {        // 2.6 has diffrent definitions for HZ in user and kernel space
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_single():Timeout reached\n");
-+                              return -EIO;
-+                      }
-+              }
-+      } else {
-+              /* Start conversion */
-+              me4000_inl(ai_context->start_reg);
-+
-+              /* Wait until ready */
-+              udelay(10);
-+              if (!
-+                  (me4000_inl(ai_context->status_reg) &
-+                   ME4000_AI_STATUS_BIT_EF_DATA)) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_single():Value not available after wait\n");
-+                      return -EIO;
-+              }
-+      }
-+
-+      /* Read value from data fifo */
-+      cmd.value = me4000_inl(ai_context->data_reg) & 0xFFFF;
-+
-+      /* Copy result back to user */
-+      err = copy_to_user(arg, &cmd, sizeof(me4000_ai_single_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_single():Can't copy to user space\n");
-+              return -EFAULT;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_ioctl_sw(struct inode *inode_p, struct file *file_p,
-+                            unsigned int service, unsigned long arg)
-+{
-+      me4000_ai_context_t *ai_context;
-+
-+      CALL_PDEBUG("me4000_ai_ioctl_sw() is executed\n");
-+
-+      ai_context = file_p->private_data;
-+
-+      if (_IOC_TYPE(service) != ME4000_MAGIC) {
-+              printk(KERN_ERR "me4000_ai_ioctl_sw():Wrong magic number\n");
-+              return -ENOTTY;
-+      }
-+      if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-+              printk(KERN_ERR
-+                     "me4000_ai_ioctl_sw():Service number to high\n");
-+              return -ENOTTY;
-+      }
-+
-+      switch (service) {
-+      case ME4000_AI_SC_SETUP:
-+              return me4000_ai_sc_setup((me4000_ai_sc_t *) arg, ai_context);
-+      case ME4000_AI_CONFIG:
-+              return me4000_ai_config((me4000_ai_config_t *) arg, ai_context);
-+      case ME4000_AI_START:
-+              return me4000_ai_start(ai_context);
-+      case ME4000_AI_STOP:
-+              return me4000_ai_stop(ai_context);
-+      case ME4000_AI_IMMEDIATE_STOP:
-+              return me4000_ai_immediate_stop(ai_context);
-+      case ME4000_AI_FSM_STATE:
-+              return me4000_ai_fsm_state((int *)arg, ai_context);
-+      case ME4000_GET_USER_INFO:
-+              return me4000_get_user_info((me4000_user_info_t *) arg,
-+                                          ai_context->board_info);
-+      case ME4000_AI_EEPROM_READ:
-+              return me4000_eeprom_read((me4000_eeprom_t *) arg, ai_context);
-+      case ME4000_AI_EEPROM_WRITE:
-+              return me4000_eeprom_write((me4000_eeprom_t *) arg, ai_context);
-+      case ME4000_AI_GET_COUNT_BUFFER:
-+              return me4000_ai_get_count_buffer((unsigned long *)arg,
-+                                                ai_context);
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_ioctl_sw():Invalid service number %d\n",
-+                     service);
-+              return -ENOTTY;
-+      }
-+      return 0;
-+}
-+
-+static int me4000_ai_ioctl_ext(struct inode *inode_p, struct file *file_p,
-+                             unsigned int service, unsigned long arg)
-+{
-+      me4000_ai_context_t *ai_context;
-+
-+      CALL_PDEBUG("me4000_ai_ioctl_ext() is executed\n");
-+
-+      ai_context = file_p->private_data;
-+
-+      if (_IOC_TYPE(service) != ME4000_MAGIC) {
-+              printk(KERN_ERR "me4000_ai_ioctl_ext():Wrong magic number\n");
-+              return -ENOTTY;
-+      }
-+      if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-+              printk(KERN_ERR
-+                     "me4000_ai_ioctl_ext():Service number to high\n");
-+              return -ENOTTY;
-+      }
-+
-+      switch (service) {
-+      case ME4000_AI_SC_SETUP:
-+              return me4000_ai_sc_setup((me4000_ai_sc_t *) arg, ai_context);
-+      case ME4000_AI_CONFIG:
-+              return me4000_ai_config((me4000_ai_config_t *) arg, ai_context);
-+      case ME4000_AI_START:
-+              return me4000_ai_start_ex((unsigned long *)arg, ai_context);
-+      case ME4000_AI_STOP:
-+              return me4000_ai_stop(ai_context);
-+      case ME4000_AI_IMMEDIATE_STOP:
-+              return me4000_ai_immediate_stop(ai_context);
-+      case ME4000_AI_EX_TRIG_ENABLE:
-+              return me4000_ai_ex_trig_enable(ai_context);
-+      case ME4000_AI_EX_TRIG_DISABLE:
-+              return me4000_ai_ex_trig_disable(ai_context);
-+      case ME4000_AI_EX_TRIG_SETUP:
-+              return me4000_ai_ex_trig_setup((me4000_ai_trigger_t *) arg,
-+                                             ai_context);
-+      case ME4000_AI_FSM_STATE:
-+              return me4000_ai_fsm_state((int *)arg, ai_context);
-+      case ME4000_GET_USER_INFO:
-+              return me4000_get_user_info((me4000_user_info_t *) arg,
-+                                          ai_context->board_info);
-+      case ME4000_AI_GET_COUNT_BUFFER:
-+              return me4000_ai_get_count_buffer((unsigned long *)arg,
-+                                                ai_context);
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_ioctl_ext():Invalid service number %d\n",
-+                     service);
-+              return -ENOTTY;
-+      }
-+      return 0;
-+}
-+
-+static int me4000_ai_fasync(int fd, struct file *file_p, int mode)
-+{
-+      me4000_ai_context_t *ai_context;
-+
-+      CALL_PDEBUG("me4000_ao_fasync_cont() is executed\n");
-+
-+      ai_context = file_p->private_data;
-+      return fasync_helper(fd, file_p, mode, &ai_context->fasync_p);
-+}
-+
-+static int me4000_ai_config(me4000_ai_config_t * arg,
-+                          me4000_ai_context_t * ai_context)
-+{
-+      me4000_ai_config_t cmd;
-+      u32 *list = NULL;
-+      u32 mode;
-+      int i;
-+      int err;
-+      wait_queue_head_t queue;
-+      u64 scan;
-+      u32 tmp;
-+
-+      CALL_PDEBUG("me4000_ai_config() is executed\n");
-+
-+      init_waitqueue_head(&queue);
-+
-+      /* Check if conversion is stopped */
-+      if (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_FSM) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_config():Conversion is not stopped\n");
-+              err = -EBUSY;
-+              goto AI_CONFIG_ERR;
-+      }
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_ai_config_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_config():Can't copy from user space\n");
-+              err = -EFAULT;
-+              goto AI_CONFIG_ERR;
-+      }
-+
-+      PDEBUG
-+          ("me4000_ai_config():chan = %ld, pre_chan = %ld, scan_low = %ld, scan_high = %ld, count = %ld\n",
-+           cmd.timer.chan, cmd.timer.pre_chan, cmd.timer.scan_low,
-+           cmd.timer.scan_high, cmd.channel_list.count);
-+
-+      /* Check whether sample and hold is available for this board */
-+      if (cmd.sh) {
-+              if (!ai_context->board_info->board_p->ai.sh_count) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_config():Sample and Hold is not available for this board\n");
-+                      err = -ENODEV;
-+                      goto AI_CONFIG_ERR;
-+              }
-+      }
-+
-+      /* Check the channel list size */
-+      if (cmd.channel_list.count > ME4000_AI_CHANNEL_LIST_COUNT) {
-+              printk(KERN_ERR
-+                     "me4000_ai_config():Channel list is to large\n");
-+              err = -EINVAL;
-+              goto AI_CONFIG_ERR;
-+      }
-+
-+      /* Copy channel list from user */
-+      list = kmalloc(sizeof(u32) * cmd.channel_list.count, GFP_KERNEL);
-+      if (!list) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_config():Can't get memory for channel list\n");
-+              err = -ENOMEM;
-+              goto AI_CONFIG_ERR;
-+      }
-+      err =
-+          copy_from_user(list, cmd.channel_list.list,
-+                         sizeof(u32) * cmd.channel_list.count);
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_config():Can't copy from user space\n");
-+              err = -EFAULT;
-+              goto AI_CONFIG_ERR;
-+      }
-+
-+      /* Check if last entry bit is set */
-+      if (!(list[cmd.channel_list.count - 1] & ME4000_AI_LIST_LAST_ENTRY)) {
-+              printk(KERN_WARNING
-+                     "me4000_ai_config():Last entry bit is not set\n");
-+              list[cmd.channel_list.count - 1] |= ME4000_AI_LIST_LAST_ENTRY;
-+      }
-+
-+      /* Check whether mode is equal for all entries */
-+      mode = list[0] & 0x20;
-+      for (i = 0; i < cmd.channel_list.count; i++) {
-+              if ((list[i] & 0x20) != mode) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_config():Mode is not equal for all entries\n");
-+                      err = -EINVAL;
-+                      goto AI_CONFIG_ERR;
-+              }
-+      }
-+
-+      /* Check whether channels are available for this mode */
-+      if (mode == ME4000_AI_LIST_INPUT_SINGLE_ENDED) {
-+              for (i = 0; i < cmd.channel_list.count; i++) {
-+                      if ((list[i] & 0x1F) >=
-+                          ai_context->board_info->board_p->ai.count) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_config():Channel is not available for single ended\n");
-+                              err = -EINVAL;
-+                              goto AI_CONFIG_ERR;
-+                      }
-+              }
-+      } else if (mode == ME4000_AI_LIST_INPUT_DIFFERENTIAL) {
-+              for (i = 0; i < cmd.channel_list.count; i++) {
-+                      if ((list[i] & 0x1F) >=
-+                          ai_context->board_info->board_p->ai.diff_count) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_config():Channel is not available for differential\n");
-+                              err = -EINVAL;
-+                              goto AI_CONFIG_ERR;
-+                      }
-+              }
-+      }
-+
-+      /* Check if bipolar is set for all entries when in differential mode */
-+      if (mode == ME4000_AI_LIST_INPUT_DIFFERENTIAL) {
-+              for (i = 0; i < cmd.channel_list.count; i++) {
-+                      if ((list[i] & 0xC0) != ME4000_AI_LIST_RANGE_BIPOLAR_10
-+                          && (list[i] & 0xC0) !=
-+                          ME4000_AI_LIST_RANGE_BIPOLAR_2_5) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_config():Bipolar is not selected in differential mode\n");
-+                              err = -EINVAL;
-+                              goto AI_CONFIG_ERR;
-+                      }
-+              }
-+      }
-+
-+      if (ai_context->mode != ME4000_AI_ACQ_MODE_EXT_SINGLE_VALUE) {
-+              /* Check for minimum channel divisor */
-+              if (cmd.timer.chan < ME4000_AI_MIN_TICKS) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_config():Channel timer divisor is to low\n");
-+                      err = -EINVAL;
-+                      goto AI_CONFIG_ERR;
-+              }
-+
-+              /* Check if minimum channel divisor is adjusted when sample and hold is activated */
-+              if ((cmd.sh) && (cmd.timer.chan != ME4000_AI_MIN_TICKS)) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_config():Channel timer divisor must be at minimum when sample and hold is activated\n");
-+                      err = -EINVAL;
-+                      goto AI_CONFIG_ERR;
-+              }
-+
-+              /* Check for minimum channel pre divisor */
-+              if (cmd.timer.pre_chan < ME4000_AI_MIN_TICKS) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_config():Channel pre timer divisor is to low\n");
-+                      err = -EINVAL;
-+                      goto AI_CONFIG_ERR;
-+              }
-+
-+              /* Write the channel timers */
-+              me4000_outl(cmd.timer.chan - 1, ai_context->chan_timer_reg);
-+              me4000_outl(cmd.timer.pre_chan - 1,
-+                          ai_context->chan_pre_timer_reg);
-+
-+              /* Save the timer values in the board context */
-+              ai_context->chan_timer = cmd.timer.chan;
-+              ai_context->chan_pre_timer = cmd.timer.pre_chan;
-+
-+              if (ai_context->mode != ME4000_AI_ACQ_MODE_EXT_SINGLE_CHANLIST) {
-+                      /* Check for scan timer divisor */
-+                      scan =
-+                          (u64) cmd.timer.scan_low | ((u64) cmd.timer.
-+                                                      scan_high << 32);
-+                      if (scan != 0) {
-+                              if (scan <
-+                                  cmd.channel_list.count * cmd.timer.chan +
-+                                  1) {
-+                                      printk(KERN_ERR
-+                                             "ME4000:me4000_ai_config():Scan timer divisor is to low\n");
-+                                      err = -EINVAL;
-+                                      goto AI_CONFIG_ERR;
-+                              }
-+                      }
-+
-+                      /* Write the scan timers */
-+                      if (scan != 0) {
-+                              scan--;
-+                              tmp = (u32) (scan & 0xFFFFFFFF);
-+                              me4000_outl(tmp,
-+                                          ai_context->scan_timer_low_reg);
-+                              tmp = (u32) ((scan >> 32) & 0xFFFFFFFF);
-+                              me4000_outl(tmp,
-+                                          ai_context->scan_timer_high_reg);
-+
-+                              scan =
-+                                  scan - (cmd.timer.chan - 1) +
-+                                  (cmd.timer.pre_chan - 1);
-+                              tmp = (u32) (scan & 0xFFFFFFFF);
-+                              me4000_outl(tmp,
-+                                          ai_context->scan_pre_timer_low_reg);
-+                              tmp = (u32) ((scan >> 32) & 0xFFFFFFFF);
-+                              me4000_outl(tmp,
-+                                          ai_context->
-+                                          scan_pre_timer_high_reg);
-+                      } else {
-+                              me4000_outl(0x0,
-+                                          ai_context->scan_timer_low_reg);
-+                              me4000_outl(0x0,
-+                                          ai_context->scan_timer_high_reg);
-+
-+                              me4000_outl(0x0,
-+                                          ai_context->scan_pre_timer_low_reg);
-+                              me4000_outl(0x0,
-+                                          ai_context->
-+                                          scan_pre_timer_high_reg);
-+                      }
-+
-+                      ai_context->scan_timer_low = cmd.timer.scan_low;
-+                      ai_context->scan_timer_high = cmd.timer.scan_high;
-+              }
-+      }
-+
-+      /* Clear the channel list */
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp &= ~ME4000_AI_CTRL_BIT_CHANNEL_FIFO;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+      tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+
-+      /* Write the channel list */
-+      for (i = 0; i < cmd.channel_list.count; i++) {
-+              me4000_outl(list[i], ai_context->channel_list_reg);
-+      }
-+
-+      /* Setup sample and hold */
-+      if (cmd.sh) {
-+              tmp |= ME4000_AI_CTRL_BIT_SAMPLE_HOLD;
-+              me4000_outl(tmp, ai_context->ctrl_reg);
-+      } else {
-+              tmp &= ~ME4000_AI_CTRL_BIT_SAMPLE_HOLD;
-+              me4000_outl(tmp, ai_context->ctrl_reg);
-+      }
-+
-+      /* Save the channel list size in the board context */
-+      ai_context->channel_list_count = cmd.channel_list.count;
-+
-+      kfree(list);
-+
-+      return 0;
-+
-+      AI_CONFIG_ERR:
-+
-+      /* Reset the timers */
-+      ai_context->chan_timer = 66;
-+      ai_context->chan_pre_timer = 66;
-+      ai_context->scan_timer_low = 0;
-+      ai_context->scan_timer_high = 0;
-+
-+      me4000_outl(65, ai_context->chan_timer_reg);
-+      me4000_outl(65, ai_context->chan_pre_timer_reg);
-+      me4000_outl(0, ai_context->scan_timer_high_reg);
-+      me4000_outl(0, ai_context->scan_timer_low_reg);
-+      me4000_outl(0, ai_context->scan_pre_timer_high_reg);
-+      me4000_outl(0, ai_context->scan_pre_timer_low_reg);
-+
-+      ai_context->channel_list_count = 0;
-+
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp &=
-+          ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_SAMPLE_HOLD);
-+
-+      if (list)
-+              kfree(list);
-+
-+      return err;
-+
-+}
-+
-+static int ai_common_start(me4000_ai_context_t * ai_context)
-+{
-+      u32 tmp;
-+      CALL_PDEBUG("ai_common_start() is executed\n");
-+
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+
-+      /* Check if conversion is stopped */
-+      if (tmp & ME4000_AI_STATUS_BIT_FSM) {
-+              printk(KERN_ERR
-+                     "ME4000:ai_common_start():Conversion is not stopped\n");
-+              return -EBUSY;
-+      }
-+
-+      /* Clear data fifo, disable all interrupts, clear sample counter reload */
-+      tmp &= ~(ME4000_AI_CTRL_BIT_DATA_FIFO | ME4000_AI_CTRL_BIT_LE_IRQ |
-+               ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ |
-+               ME4000_AI_CTRL_BIT_SC_RELOAD);
-+
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+
-+      /* Clear circular buffer */
-+      ai_context->circ_buf.head = 0;
-+      ai_context->circ_buf.tail = 0;
-+
-+      /* Enable data fifo */
-+      tmp |= ME4000_AI_CTRL_BIT_DATA_FIFO;
-+
-+      /* Determine interrupt setup */
-+      if (ai_context->sample_counter && !ai_context->sample_counter_reload) {
-+              /* Enable Half Full Interrupt and Sample Counter Interrupt */
-+              tmp |= ME4000_AI_CTRL_BIT_SC_IRQ | ME4000_AI_CTRL_BIT_HF_IRQ;
-+      } else if (ai_context->sample_counter
-+                 && ai_context->sample_counter_reload) {
-+              if (ai_context->sample_counter <= ME4000_AI_FIFO_COUNT / 2) {
-+                      /* Enable only Sample Counter Interrupt */
-+                      tmp |=
-+                          ME4000_AI_CTRL_BIT_SC_IRQ |
-+                          ME4000_AI_CTRL_BIT_SC_RELOAD;
-+              } else {
-+                      /* Enable Half Full Interrupt and Sample Counter Interrupt */
-+                      tmp |=
-+                          ME4000_AI_CTRL_BIT_SC_IRQ |
-+                          ME4000_AI_CTRL_BIT_HF_IRQ |
-+                          ME4000_AI_CTRL_BIT_SC_RELOAD;
-+              }
-+      } else {
-+              /* Enable only Half Full Interrupt */
-+              tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
-+      }
-+
-+      /* Clear the stop bits */
-+      tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
-+
-+      /* Write setup to hardware */
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+
-+      /* Write sample counter */
-+      me4000_outl(ai_context->sample_counter, ai_context->sample_counter_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_start(me4000_ai_context_t * ai_context)
-+{
-+      int err;
-+      CALL_PDEBUG("me4000_ai_start() is executed\n");
-+
-+      /* Prepare Hardware */
-+      err = ai_common_start(ai_context);
-+      if (err)
-+              return err;
-+
-+      /* Start conversion by dummy read */
-+      me4000_inl(ai_context->start_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_start_ex(unsigned long *arg,
-+                            me4000_ai_context_t * ai_context)
-+{
-+      int err;
-+      wait_queue_head_t queue;
-+      unsigned long ref;
-+      unsigned long timeout;
-+
-+      CALL_PDEBUG("me4000_ai_start_ex() is executed\n");
-+
-+      if (get_user(timeout, arg)) {
-+              printk(KERN_ERR
-+                     "me4000_ai_start_ex():Cannot copy data from user\n");
-+              return -EFAULT;
-+      }
-+
-+      init_waitqueue_head(&queue);
-+
-+      /* Prepare Hardware */
-+      err = ai_common_start(ai_context);
-+      if (err)
-+              return err;
-+
-+      if (timeout) {
-+              ref = jiffies;
-+              while (!
-+                     (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM))
-+              {
-+                      interruptible_sleep_on_timeout(&queue, 1);
-+                      if (signal_pending(current)) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_start_ex():Wait on start of state machine interrupted\n");
-+                              return -EINTR;
-+                      }
-+                      if (((jiffies - ref) > (timeout * HZ / USER_HZ))) {     // 2.6 has diffrent definitions for HZ in user and kernel space
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_start_ex():Timeout reached\n");
-+                              return -EIO;
-+                      }
-+              }
-+      } else {
-+              while (!
-+                     (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM))
-+              {
-+                      interruptible_sleep_on_timeout(&queue, 1);
-+                      if (signal_pending(current)) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_start_ex():Wait on start of state machine interrupted\n");
-+                              return -EINTR;
-+                      }
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_stop(me4000_ai_context_t * ai_context)
-+{
-+      wait_queue_head_t queue;
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ai_stop() is executed\n");
-+
-+      init_waitqueue_head(&queue);
-+
-+      /* Disable irqs and clear data fifo */
-+      spin_lock_irqsave(&ai_context->int_lock, flags);
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp &=
-+          ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ |
-+            ME4000_AI_CTRL_BIT_DATA_FIFO);
-+      /* Stop conversion of the state machine */
-+      tmp |= ME4000_AI_CTRL_BIT_STOP;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+
-+      /* Clear circular buffer */
-+      ai_context->circ_buf.head = 0;
-+      ai_context->circ_buf.tail = 0;
-+
-+      while (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) {
-+              interruptible_sleep_on_timeout(&queue, 1);
-+              if (signal_pending(current)) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_stop():Wait on state machine after stop interrupted\n");
-+                      return -EINTR;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_immediate_stop(me4000_ai_context_t * ai_context)
-+{
-+      wait_queue_head_t queue;
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ai_stop() is executed\n");
-+
-+      init_waitqueue_head(&queue);
-+
-+      /* Disable irqs and clear data fifo */
-+      spin_lock_irqsave(&ai_context->int_lock, flags);
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp &=
-+          ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ |
-+            ME4000_AI_CTRL_BIT_DATA_FIFO);
-+      /* Stop conversion of the state machine */
-+      tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+
-+      /* Clear circular buffer */
-+      ai_context->circ_buf.head = 0;
-+      ai_context->circ_buf.tail = 0;
-+
-+      while (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) {
-+              interruptible_sleep_on_timeout(&queue, 1);
-+              if (signal_pending(current)) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_stop():Wait on state machine after stop interrupted\n");
-+                      return -EINTR;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_ex_trig_enable(me4000_ai_context_t * ai_context)
-+{
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ai_ex_trig_enable() is executed\n");
-+
-+      spin_lock_irqsave(&ai_context->int_lock, flags);
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp |= ME4000_AI_CTRL_BIT_EX_TRIG;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_ex_trig_disable(me4000_ai_context_t * ai_context)
-+{
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ai_ex_trig_disable() is executed\n");
-+
-+      spin_lock_irqsave(&ai_context->int_lock, flags);
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_ex_trig_setup(me4000_ai_trigger_t * arg,
-+                                 me4000_ai_context_t * ai_context)
-+{
-+      me4000_ai_trigger_t cmd;
-+      int err;
-+      u32 tmp;
-+      unsigned long flags;
-+
-+      CALL_PDEBUG("me4000_ai_ex_trig_setup() is executed\n");
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_ai_trigger_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_ex_trig_setup():Can't copy from user space\n");
-+              return -EFAULT;
-+      }
-+
-+      spin_lock_irqsave(&ai_context->int_lock, flags);
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+
-+      if (cmd.mode == ME4000_AI_TRIGGER_EXT_DIGITAL) {
-+              tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG;
-+      } else if (cmd.mode == ME4000_AI_TRIGGER_EXT_ANALOG) {
-+              if (!ai_context->board_info->board_p->ai.ex_trig_analog) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_ex_trig_setup():No analog trigger available\n");
-+                      return -EINVAL;
-+              }
-+              tmp |= ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG;
-+      } else {
-+              spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_ex_trig_setup():Invalid trigger mode specified\n");
-+              return -EINVAL;
-+      }
-+
-+      if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_RISING) {
-+              tmp &=
-+                  ~(ME4000_AI_CTRL_BIT_EX_TRIG_BOTH |
-+                    ME4000_AI_CTRL_BIT_EX_TRIG_FALLING);
-+      } else if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_FALLING) {
-+              tmp |= ME4000_AI_CTRL_BIT_EX_TRIG_FALLING;
-+              tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG_BOTH;
-+      } else if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_BOTH) {
-+              tmp |=
-+                  ME4000_AI_CTRL_BIT_EX_TRIG_BOTH |
-+                  ME4000_AI_CTRL_BIT_EX_TRIG_FALLING;
-+      } else {
-+              spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_ex_trig_setup():Invalid trigger edge specified\n");
-+              return -EINVAL;
-+      }
-+
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+      spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+      return 0;
-+}
-+
-+static int me4000_ai_sc_setup(me4000_ai_sc_t * arg,
-+                            me4000_ai_context_t * ai_context)
-+{
-+      me4000_ai_sc_t cmd;
-+      int err;
-+
-+      CALL_PDEBUG("me4000_ai_sc_setup() is executed\n");
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_ai_sc_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_sc_setup():Can't copy from user space\n");
-+              return -EFAULT;
-+      }
-+
-+      ai_context->sample_counter = cmd.value;
-+      ai_context->sample_counter_reload = cmd.reload;
-+
-+      return 0;
-+}
-+
-+static ssize_t me4000_ai_read(struct file *filep, char *buff, size_t cnt,
-+                            loff_t * offp)
-+{
-+      me4000_ai_context_t *ai_context = filep->private_data;
-+      s16 *buffer = (s16 *) buff;
-+      size_t count = cnt / 2;
-+      unsigned long flags;
-+      int tmp;
-+      int c = 0;
-+      int k = 0;
-+      int ret = 0;
-+      wait_queue_t wait;
-+
-+      CALL_PDEBUG("me4000_ai_read() is executed\n");
-+
-+      init_waitqueue_entry(&wait, current);
-+
-+      /* Check count */
-+      if (count <= 0) {
-+              PDEBUG("me4000_ai_read():Count is 0\n");
-+              return 0;
-+      }
-+
-+      while (count > 0) {
-+              if (filep->f_flags & O_NONBLOCK) {
-+                      c = me4000_values_to_end(ai_context->circ_buf,
-+                                               ME4000_AI_BUFFER_COUNT);
-+                      if (!c) {
-+                              PDEBUG
-+                                  ("me4000_ai_read():Returning from nonblocking read\n");
-+                              break;
-+                      }
-+              } else {
-+                      /* Check if conversion is still running */
-+                      if (!
-+                          (me4000_inl(ai_context->status_reg) &
-+                           ME4000_AI_STATUS_BIT_FSM)) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_read():Conversion interrupted\n");
-+                              return -EPIPE;
-+                      }
-+
-+                      wait_event_interruptible(ai_context->wait_queue,
-+                                               (me4000_values_to_end
-+                                                (ai_context->circ_buf,
-+                                                 ME4000_AI_BUFFER_COUNT)));
-+                      if (signal_pending(current)) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_ai_read():Wait on values interrupted from signal\n");
-+                              return -EINTR;
-+                      }
-+              }
-+
-+              /* Only read count values or as much as available */
-+              c = me4000_values_to_end(ai_context->circ_buf,
-+                                       ME4000_AI_BUFFER_COUNT);
-+              PDEBUG("me4000_ai_read():%d values to end\n", c);
-+              if (count < c)
-+                      c = count;
-+
-+              PDEBUG("me4000_ai_read():Copy %d values to user space\n", c);
-+              k = 2 * c;
-+              k -= copy_to_user(buffer,
-+                                ai_context->circ_buf.buf +
-+                                ai_context->circ_buf.tail, k);
-+              c = k / 2;
-+              if (!c) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_ai_read():Cannot copy new values to user\n");
-+                      return -EFAULT;
-+              }
-+
-+              ai_context->circ_buf.tail =
-+                  (ai_context->circ_buf.tail + c) & (ME4000_AI_BUFFER_COUNT -
-+                                                     1);
-+              buffer += c;
-+              count -= c;
-+              ret += c;
-+
-+              spin_lock_irqsave(&ai_context->int_lock, flags);
-+              if (me4000_buf_space
-+                  (ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) {
-+                      tmp = me4000_inl(ai_context->ctrl_reg);
-+
-+                      /* Determine interrupt setup */
-+                      if (ai_context->sample_counter
-+                          && !ai_context->sample_counter_reload) {
-+                              /* Enable Half Full Interrupt and Sample Counter Interrupt */
-+                              tmp |=
-+                                  ME4000_AI_CTRL_BIT_SC_IRQ |
-+                                  ME4000_AI_CTRL_BIT_HF_IRQ;
-+                      } else if (ai_context->sample_counter
-+                                 && ai_context->sample_counter_reload) {
-+                              if (ai_context->sample_counter <
-+                                  ME4000_AI_FIFO_COUNT / 2) {
-+                                      /* Enable only Sample Counter Interrupt */
-+                                      tmp |= ME4000_AI_CTRL_BIT_SC_IRQ;
-+                              } else {
-+                                      /* Enable Half Full Interrupt and Sample Counter Interrupt */
-+                                      tmp |=
-+                                          ME4000_AI_CTRL_BIT_SC_IRQ |
-+                                          ME4000_AI_CTRL_BIT_HF_IRQ;
-+                              }
-+                      } else {
-+                              /* Enable only Half Full Interrupt */
-+                              tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
-+                      }
-+
-+                      me4000_outl(tmp, ai_context->ctrl_reg);
-+              }
-+              spin_unlock_irqrestore(&ai_context->int_lock, flags);
-+      }
-+
-+      /* Check if conversion is still running */
-+      if (!(me4000_inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_read():Conversion not running after complete read\n");
-+              return -EPIPE;
-+      }
-+
-+      if (filep->f_flags & O_NONBLOCK) {
-+              return (k == 0) ? -EAGAIN : 2 * ret;
-+      }
-+
-+      CALL_PDEBUG("me4000_ai_read() is leaved\n");
-+      return ret * 2;
-+}
-+
-+static unsigned int me4000_ai_poll(struct file *file_p, poll_table * wait)
-+{
-+      me4000_ai_context_t *ai_context;
-+      unsigned long mask = 0;
-+
-+      CALL_PDEBUG("me4000_ai_poll() is executed\n");
-+
-+      ai_context = file_p->private_data;
-+
-+      /* Register wait queue */
-+      poll_wait(file_p, &ai_context->wait_queue, wait);
-+
-+      /* Get available values */
-+      if (me4000_values_to_end(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT))
-+              mask |= POLLIN | POLLRDNORM;
-+
-+      PDEBUG("me4000_ai_poll():Return mask %lX\n", mask);
-+
-+      return mask;
-+}
-+
-+static int me4000_ai_offset_enable(me4000_ai_context_t * ai_context)
-+{
-+      unsigned long tmp;
-+
-+      CALL_PDEBUG("me4000_ai_offset_enable() is executed\n");
-+
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp |= ME4000_AI_CTRL_BIT_OFFSET;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_offset_disable(me4000_ai_context_t * ai_context)
-+{
-+      unsigned long tmp;
-+
-+      CALL_PDEBUG("me4000_ai_offset_disable() is executed\n");
-+
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp &= ~ME4000_AI_CTRL_BIT_OFFSET;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_fullscale_enable(me4000_ai_context_t * ai_context)
-+{
-+      unsigned long tmp;
-+
-+      CALL_PDEBUG("me4000_ai_fullscale_enable() is executed\n");
-+
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp |= ME4000_AI_CTRL_BIT_FULLSCALE;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_fullscale_disable(me4000_ai_context_t * ai_context)
-+{
-+      unsigned long tmp;
-+
-+      CALL_PDEBUG("me4000_ai_fullscale_disable() is executed\n");
-+
-+      tmp = me4000_inl(ai_context->ctrl_reg);
-+      tmp &= ~ME4000_AI_CTRL_BIT_FULLSCALE;
-+      me4000_outl(tmp, ai_context->ctrl_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_fsm_state(int *arg, me4000_ai_context_t * ai_context)
-+{
-+      unsigned long tmp;
-+
-+      CALL_PDEBUG("me4000_ai_fsm_state() is executed\n");
-+
-+      tmp =
-+          (me4000_inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) ? 1
-+          : 0;
-+
-+      if (put_user(tmp, arg)) {
-+              printk(KERN_ERR "me4000_ai_fsm_state():Cannot copy to user\n");
-+              return -EFAULT;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_ai_get_count_buffer(unsigned long *arg,
-+                                    me4000_ai_context_t * ai_context)
-+{
-+      unsigned long c;
-+      int err;
-+
-+      c = me4000_buf_count(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT);
-+
-+      err = copy_to_user(arg, &c, sizeof(unsigned long));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ai_get_count_buffer():Can't copy to user space\n");
-+              return -EFAULT;
-+      }
-+
-+      return 0;
-+}
-+
-+/*---------------------------------- EEPROM stuff ---------------------------*/
-+
-+static int eeprom_write_cmd(me4000_ai_context_t * ai_context, unsigned long cmd,
-+                          int length)
-+{
-+      int i;
-+      unsigned long value;
-+
-+      CALL_PDEBUG("eeprom_write_cmd() is executed\n");
-+
-+      PDEBUG("eeprom_write_cmd():Write command 0x%08lX with length = %d\n",
-+             cmd, length);
-+
-+      /* Get the ICR register and clear the related bits */
-+      value = me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR);
-+      value &= ~(PLX_ICR_MASK_EEPROM);
-+      me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-+
-+      /* Raise the chip select */
-+      value |= PLX_ICR_BIT_EEPROM_CHIP_SELECT;
-+      me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-+      udelay(EEPROM_DELAY);
-+
-+      for (i = 0; i < length; i++) {
-+              if (cmd & ((0x1 << (length - 1)) >> i)) {
-+                      value |= PLX_ICR_BIT_EEPROM_WRITE;
-+              } else {
-+                      value &= ~PLX_ICR_BIT_EEPROM_WRITE;
-+              }
-+
-+              /* Write to EEPROM */
-+              me4000_outl(value,
-+                          ai_context->board_info->plx_regbase + PLX_ICR);
-+              udelay(EEPROM_DELAY);
-+
-+              /* Raising edge of the clock */
-+              value |= PLX_ICR_BIT_EEPROM_CLOCK_SET;
-+              me4000_outl(value,
-+                          ai_context->board_info->plx_regbase + PLX_ICR);
-+              udelay(EEPROM_DELAY);
-+
-+              /* Falling edge of the clock */
-+              value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET;
-+              me4000_outl(value,
-+                          ai_context->board_info->plx_regbase + PLX_ICR);
-+              udelay(EEPROM_DELAY);
-+      }
-+
-+      /* Clear the chip select */
-+      value &= ~PLX_ICR_BIT_EEPROM_CHIP_SELECT;
-+      me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-+      udelay(EEPROM_DELAY);
-+
-+      /* Wait until hardware is ready for sure */
-+      mdelay(10);
-+
-+      return 0;
-+}
-+
-+static unsigned short eeprom_read_cmd(me4000_ai_context_t * ai_context,
-+                                    unsigned long cmd, int length)
-+{
-+      int i;
-+      unsigned long value;
-+      unsigned short id = 0;
-+
-+      CALL_PDEBUG("eeprom_read_cmd() is executed\n");
-+
-+      PDEBUG("eeprom_read_cmd():Read command 0x%08lX with length = %d\n", cmd,
-+             length);
-+
-+      /* Get the ICR register and clear the related bits */
-+      value = me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR);
-+      value &= ~(PLX_ICR_MASK_EEPROM);
-+
-+      me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-+
-+      /* Raise the chip select */
-+      value |= PLX_ICR_BIT_EEPROM_CHIP_SELECT;
-+      me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-+      udelay(EEPROM_DELAY);
-+
-+      /* Write the read command to the eeprom */
-+      for (i = 0; i < length; i++) {
-+              if (cmd & ((0x1 << (length - 1)) >> i)) {
-+                      value |= PLX_ICR_BIT_EEPROM_WRITE;
-+              } else {
-+                      value &= ~PLX_ICR_BIT_EEPROM_WRITE;
-+              }
-+              me4000_outl(value,
-+                          ai_context->board_info->plx_regbase + PLX_ICR);
-+              udelay(EEPROM_DELAY);
-+
-+              /* Raising edge of the clock */
-+              value |= PLX_ICR_BIT_EEPROM_CLOCK_SET;
-+              me4000_outl(value,
-+                          ai_context->board_info->plx_regbase + PLX_ICR);
-+              udelay(EEPROM_DELAY);
-+
-+              /* Falling edge of the clock */
-+              value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET;
-+              me4000_outl(value,
-+                          ai_context->board_info->plx_regbase + PLX_ICR);
-+              udelay(EEPROM_DELAY);
-+      }
-+
-+      /* Read the value from the eeprom */
-+      for (i = 0; i < 16; i++) {
-+              /* Raising edge of the clock */
-+              value |= PLX_ICR_BIT_EEPROM_CLOCK_SET;
-+              me4000_outl(value,
-+                          ai_context->board_info->plx_regbase + PLX_ICR);
-+              udelay(EEPROM_DELAY);
-+
-+              if (me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR) &
-+                  PLX_ICR_BIT_EEPROM_READ) {
-+                      id |= (0x8000 >> i);
-+                      PDEBUG("eeprom_read_cmd():OR with 0x%04X\n",
-+                             (0x8000 >> i));
-+              } else {
-+                      PDEBUG("eeprom_read_cmd():Dont't OR\n");
-+              }
-+
-+              /* Falling edge of the clock */
-+              value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET;
-+              me4000_outl(value,
-+                          ai_context->board_info->plx_regbase + PLX_ICR);
-+              udelay(EEPROM_DELAY);
-+      }
-+
-+      /* Clear the chip select */
-+      value &= ~PLX_ICR_BIT_EEPROM_CHIP_SELECT;
-+      me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-+      udelay(EEPROM_DELAY);
-+
-+      return id;
-+}
-+
-+static int me4000_eeprom_write(me4000_eeprom_t * arg,
-+                             me4000_ai_context_t * ai_context)
-+{
-+      int err;
-+      me4000_eeprom_t setup;
-+      unsigned long cmd;
-+      unsigned long date_high;
-+      unsigned long date_low;
-+
-+      CALL_PDEBUG("me4000_eeprom_write() is executed\n");
-+
-+      err = copy_from_user(&setup, arg, sizeof(setup));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_eeprom_write():Cannot copy from user\n");
-+              return err;
-+      }
-+
-+      /* Enable writing */
-+      eeprom_write_cmd(ai_context, ME4000_EEPROM_CMD_WRITE_ENABLE,
-+                       ME4000_EEPROM_CMD_LENGTH_WRITE_ENABLE);
-+
-+      /* Command for date */
-+      date_high = (setup.date & 0xFFFF0000) >> 16;
-+      date_low = (setup.date & 0x0000FFFF);
-+
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_DATE_HIGH <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   date_high);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_DATE_LOW <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   date_low);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for unipolar 10V offset */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   uni_10_offset);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for unipolar 10V fullscale */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   uni_10_fullscale);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for unipolar 2,5V offset */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   uni_2_5_offset);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for unipolar 2,5V fullscale */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   uni_2_5_fullscale);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for bipolar 10V offset */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   bi_10_offset);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for bipolar 10V fullscale */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   bi_10_fullscale);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for bipolar 2,5V offset */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   bi_2_5_offset);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for bipolar 2,5V fullscale */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   bi_2_5_fullscale);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for differential 10V offset */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   diff_10_offset);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for differential 10V fullscale */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE
-+                                     << ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                      (unsigned
-+                                                                       long)
-+                                                                      setup.
-+                                                                      diff_10_fullscale);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for differential 2,5V offset */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET <<
-+                                     ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                   (unsigned
-+                                                                    long)
-+                                                                   setup.
-+                                                                   diff_2_5_offset);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Command for differential 2,5V fullscale */
-+      cmd =
-+          ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE
-+                                     << ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-+                                                                      (unsigned
-+                                                                       long)
-+                                                                      setup.
-+                                                                      diff_2_5_fullscale);
-+      err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-+      if (err)
-+              return err;
-+
-+      /* Disable writing */
-+      eeprom_write_cmd(ai_context, ME4000_EEPROM_CMD_WRITE_DISABLE,
-+                       ME4000_EEPROM_CMD_LENGTH_WRITE_DISABLE);
-+
-+      return 0;
-+}
-+
-+static int me4000_eeprom_read(me4000_eeprom_t * arg,
-+                            me4000_ai_context_t * ai_context)
-+{
-+      int err;
-+      unsigned long cmd;
-+      me4000_eeprom_t setup;
-+
-+      CALL_PDEBUG("me4000_eeprom_read() is executed\n");
-+
-+      /* Command for date */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_DATE_HIGH;
-+      setup.date =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+      setup.date <<= 16;
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_DATE_LOW;
-+      setup.date |=
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for unipolar 10V offset */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET;
-+      setup.uni_10_offset =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for unipolar 10V fullscale */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE;
-+      setup.uni_10_fullscale =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for unipolar 2,5V offset */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET;
-+      setup.uni_2_5_offset =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for unipolar 2,5V fullscale */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE;
-+      setup.uni_2_5_fullscale =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for bipolar 10V offset */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET;
-+      setup.bi_10_offset =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for bipolar 10V fullscale */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE;
-+      setup.bi_10_fullscale =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for bipolar 2,5V offset */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET;
-+      setup.bi_2_5_offset =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for bipolar 2,5V fullscale */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE;
-+      setup.bi_2_5_fullscale =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for differntial 10V offset */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET;
-+      setup.diff_10_offset =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for differential 10V fullscale */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE;
-+      setup.diff_10_fullscale =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for differntial 2,5V offset */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET;
-+      setup.diff_2_5_offset =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      /* Command for differential 2,5V fullscale */
-+      cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE;
-+      setup.diff_2_5_fullscale =
-+          eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-+
-+      err = copy_to_user(arg, &setup, sizeof(setup));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_eeprom_read():Cannot copy to user\n");
-+              return err;
-+      }
-+
-+      return 0;
-+}
-+
-+/*------------------------------------ DIO stuff ----------------------------------------------*/
-+
-+static int me4000_dio_ioctl(struct inode *inode_p, struct file *file_p,
-+                          unsigned int service, unsigned long arg)
-+{
-+      me4000_dio_context_t *dio_context;
-+
-+      CALL_PDEBUG("me4000_dio_ioctl() is executed\n");
-+
-+      dio_context = file_p->private_data;
-+
-+      if (_IOC_TYPE(service) != ME4000_MAGIC) {
-+              printk(KERN_ERR "me4000_dio_ioctl():Wrong magic number\n");
-+              return -ENOTTY;
-+      }
-+      if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-+              printk(KERN_ERR "me4000_dio_ioctl():Service number to high\n");
-+              return -ENOTTY;
-+      }
-+
-+      switch (service) {
-+      case ME4000_DIO_CONFIG:
-+              return me4000_dio_config((me4000_dio_config_t *) arg,
-+                                       dio_context);
-+      case ME4000_DIO_SET_BYTE:
-+              return me4000_dio_set_byte((me4000_dio_byte_t *) arg,
-+                                         dio_context);
-+      case ME4000_DIO_GET_BYTE:
-+              return me4000_dio_get_byte((me4000_dio_byte_t *) arg,
-+                                         dio_context);
-+      case ME4000_DIO_RESET:
-+              return me4000_dio_reset(dio_context);
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_ioctl():Invalid service number %d\n",
-+                     service);
-+              return -ENOTTY;
-+      }
-+      return 0;
-+}
-+
-+static int me4000_dio_config(me4000_dio_config_t * arg,
-+                           me4000_dio_context_t * dio_context)
-+{
-+      me4000_dio_config_t cmd;
-+      u32 tmp;
-+      int err;
-+
-+      CALL_PDEBUG("me4000_dio_config() is executed\n");
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_dio_config_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_config():Can't copy from user space\n");
-+              return -EFAULT;
-+      }
-+
-+      /* Check port parameter */
-+      if (cmd.port >= dio_context->dio_count) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_config():Port %d is not available\n",
-+                     cmd.port);
-+              return -EINVAL;
-+      }
-+
-+      PDEBUG("me4000_dio_config(): port %d, mode %d, function %d\n", cmd.port,
-+             cmd.mode, cmd.function);
-+
-+      if (cmd.port == ME4000_DIO_PORT_A) {
-+              if (cmd.mode == ME4000_DIO_PORT_INPUT) {
-+                      /* Check if opto isolated version */
-+                      if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_dio_config():Cannot set to input on opto isolated versions\n");
-+                              return -EIO;
-+                      }
-+
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-+                            ME4000_DIO_CTRL_BIT_MODE_1);
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-+                            ME4000_DIO_CTRL_BIT_MODE_1);
-+                      tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-+                            ME4000_DIO_CTRL_BIT_MODE_1 |
-+                            ME4000_DIO_CTRL_BIT_FIFO_HIGH_0);
-+                      tmp |=
-+                          ME4000_DIO_CTRL_BIT_MODE_0 |
-+                          ME4000_DIO_CTRL_BIT_MODE_1;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp |=
-+                          ME4000_DIO_CTRL_BIT_MODE_0 |
-+                          ME4000_DIO_CTRL_BIT_MODE_1 |
-+                          ME4000_DIO_CTRL_BIT_FIFO_HIGH_0;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_dio_config():Mode %d is not available\n",
-+                             cmd.mode);
-+                      return -EINVAL;
-+              }
-+      } else if (cmd.port == ME4000_DIO_PORT_B) {
-+              if (cmd.mode == ME4000_DIO_PORT_INPUT) {
-+                      /* Only do anything when TTL version is installed */
-+                      if ((me4000_inl(dio_context->dir_reg) & 0x1)) {
-+                              tmp = me4000_inl(dio_context->ctrl_reg);
-+                              tmp &=
-+                                  ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-+                                    ME4000_DIO_CTRL_BIT_MODE_3);
-+                              me4000_outl(tmp, dio_context->ctrl_reg);
-+                      }
-+              } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
-+                      /* Check if opto isolated version */
-+                      if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_dio_config():Cannot set to output on opto isolated versions\n");
-+                              return -EIO;
-+                      }
-+
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-+                            ME4000_DIO_CTRL_BIT_MODE_3);
-+                      tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
-+                      /* Check if opto isolated version */
-+                      if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_dio_config():Cannot set to FIFO low output on opto isolated versions\n");
-+                              return -EIO;
-+                      }
-+
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-+                            ME4000_DIO_CTRL_BIT_MODE_3 |
-+                            ME4000_DIO_CTRL_BIT_FIFO_HIGH_1);
-+                      tmp |=
-+                          ME4000_DIO_CTRL_BIT_MODE_2 |
-+                          ME4000_DIO_CTRL_BIT_MODE_3;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
-+                      /* Check if opto isolated version */
-+                      if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-+                              printk(KERN_ERR
-+                                     "ME4000:me4000_dio_config():Cannot set to FIFO high output on opto isolated versions\n");
-+                              return -EIO;
-+                      }
-+
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp |=
-+                          ME4000_DIO_CTRL_BIT_MODE_2 |
-+                          ME4000_DIO_CTRL_BIT_MODE_3 |
-+                          ME4000_DIO_CTRL_BIT_FIFO_HIGH_1;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_dio_config():Mode %d is not available\n",
-+                             cmd.mode);
-+                      return -EINVAL;
-+              }
-+      } else if (cmd.port == ME4000_DIO_PORT_C) {
-+              if (cmd.mode == ME4000_DIO_PORT_INPUT) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-+                            ME4000_DIO_CTRL_BIT_MODE_5);
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-+                            ME4000_DIO_CTRL_BIT_MODE_5);
-+                      tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-+                            ME4000_DIO_CTRL_BIT_MODE_5 |
-+                            ME4000_DIO_CTRL_BIT_FIFO_HIGH_2);
-+                      tmp |=
-+                          ME4000_DIO_CTRL_BIT_MODE_4 |
-+                          ME4000_DIO_CTRL_BIT_MODE_5;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp |=
-+                          ME4000_DIO_CTRL_BIT_MODE_4 |
-+                          ME4000_DIO_CTRL_BIT_MODE_5 |
-+                          ME4000_DIO_CTRL_BIT_FIFO_HIGH_2;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_dio_config():Mode %d is not available\n",
-+                             cmd.mode);
-+                      return -EINVAL;
-+              }
-+      } else if (cmd.port == ME4000_DIO_PORT_D) {
-+              if (cmd.mode == ME4000_DIO_PORT_INPUT) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-+                            ME4000_DIO_CTRL_BIT_MODE_7);
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-+                            ME4000_DIO_CTRL_BIT_MODE_7);
-+                      tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp &=
-+                          ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-+                            ME4000_DIO_CTRL_BIT_MODE_7 |
-+                            ME4000_DIO_CTRL_BIT_FIFO_HIGH_3);
-+                      tmp |=
-+                          ME4000_DIO_CTRL_BIT_MODE_6 |
-+                          ME4000_DIO_CTRL_BIT_MODE_7;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
-+                      tmp = me4000_inl(dio_context->ctrl_reg);
-+                      tmp |=
-+                          ME4000_DIO_CTRL_BIT_MODE_6 |
-+                          ME4000_DIO_CTRL_BIT_MODE_7 |
-+                          ME4000_DIO_CTRL_BIT_FIFO_HIGH_3;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_dio_config():Mode %d is not available\n",
-+                             cmd.mode);
-+                      return -EINVAL;
-+              }
-+      } else {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_config():Port %d is not available\n",
-+                     cmd.port);
-+              return -EINVAL;
-+      }
-+
-+      PDEBUG("me4000_dio_config(): port %d, mode %d, function %d\n", cmd.port,
-+             cmd.mode, cmd.function);
-+
-+      if ((cmd.mode == ME4000_DIO_FIFO_HIGH)
-+          || (cmd.mode == ME4000_DIO_FIFO_LOW)) {
-+              tmp = me4000_inl(dio_context->ctrl_reg);
-+              tmp &=
-+                  ~(ME4000_DIO_CTRL_BIT_FUNCTION_0 |
-+                    ME4000_DIO_CTRL_BIT_FUNCTION_1);
-+              if (cmd.function == ME4000_DIO_FUNCTION_PATTERN) {
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.function == ME4000_DIO_FUNCTION_DEMUX) {
-+                      tmp |= ME4000_DIO_CTRL_BIT_FUNCTION_0;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else if (cmd.function == ME4000_DIO_FUNCTION_MUX) {
-+                      tmp |= ME4000_DIO_CTRL_BIT_FUNCTION_1;
-+                      me4000_outl(tmp, dio_context->ctrl_reg);
-+              } else {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_dio_config():Invalid port function specified\n");
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_dio_set_byte(me4000_dio_byte_t * arg,
-+                             me4000_dio_context_t * dio_context)
-+{
-+      me4000_dio_byte_t cmd;
-+      int err;
-+
-+      CALL_PDEBUG("me4000_dio_set_byte() is executed\n");
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_dio_byte_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_set_byte():Can't copy from user space\n");
-+              return -EFAULT;
-+      }
-+
-+      /* Check port parameter */
-+      if (cmd.port >= dio_context->dio_count) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_set_byte():Port %d is not available\n",
-+                     cmd.port);
-+              return -EINVAL;
-+      }
-+
-+      if (cmd.port == ME4000_DIO_PORT_A) {
-+              if ((me4000_inl(dio_context->ctrl_reg) & 0x3) != 0x1) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
-+                             cmd.port);
-+                      return -EIO;
-+              }
-+              me4000_outl(cmd.byte, dio_context->port_0_reg);
-+      } else if (cmd.port == ME4000_DIO_PORT_B) {
-+              if ((me4000_inl(dio_context->ctrl_reg) & 0xC) != 0x4) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
-+                             cmd.port);
-+                      return -EIO;
-+              }
-+              me4000_outl(cmd.byte, dio_context->port_1_reg);
-+      } else if (cmd.port == ME4000_DIO_PORT_C) {
-+              if ((me4000_inl(dio_context->ctrl_reg) & 0x30) != 0x10) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
-+                             cmd.port);
-+                      return -EIO;
-+              }
-+              me4000_outl(cmd.byte, dio_context->port_2_reg);
-+      } else if (cmd.port == ME4000_DIO_PORT_D) {
-+              if ((me4000_inl(dio_context->ctrl_reg) & 0xC0) != 0x40) {
-+                      printk(KERN_ERR
-+                             "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
-+                             cmd.port);
-+                      return -EIO;
-+              }
-+              me4000_outl(cmd.byte, dio_context->port_3_reg);
-+      } else {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_set_byte():Port %d is not available\n",
-+                     cmd.port);
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_dio_get_byte(me4000_dio_byte_t * arg,
-+                             me4000_dio_context_t * dio_context)
-+{
-+      me4000_dio_byte_t cmd;
-+      int err;
-+
-+      CALL_PDEBUG("me4000_dio_get_byte() is executed\n");
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_dio_byte_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_get_byte():Can't copy from user space\n");
-+              return -EFAULT;
-+      }
-+
-+      /* Check port parameter */
-+      if (cmd.port >= dio_context->dio_count) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_get_byte():Port %d is not available\n",
-+                     cmd.port);
-+              return -EINVAL;
-+      }
-+
-+      if (cmd.port == ME4000_DIO_PORT_A) {
-+              cmd.byte = me4000_inl(dio_context->port_0_reg) & 0xFF;
-+      } else if (cmd.port == ME4000_DIO_PORT_B) {
-+              cmd.byte = me4000_inl(dio_context->port_1_reg) & 0xFF;
-+      } else if (cmd.port == ME4000_DIO_PORT_C) {
-+              cmd.byte = me4000_inl(dio_context->port_2_reg) & 0xFF;
-+      } else if (cmd.port == ME4000_DIO_PORT_D) {
-+              cmd.byte = me4000_inl(dio_context->port_3_reg) & 0xFF;
-+      } else {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_get_byte():Port %d is not available\n",
-+                     cmd.port);
-+              return -EINVAL;
-+      }
-+
-+      /* Copy result back to user */
-+      err = copy_to_user(arg, &cmd, sizeof(me4000_dio_byte_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_get_byte():Can't copy to user space\n");
-+              return -EFAULT;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_dio_reset(me4000_dio_context_t * dio_context)
-+{
-+      CALL_PDEBUG("me4000_dio_reset() is executed\n");
-+
-+      /* Clear the control register */
-+      me4000_outl(0, dio_context->ctrl_reg);
-+
-+      /* Check for opto isolated version */
-+      if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-+              me4000_outl(0x1, dio_context->ctrl_reg);
-+              me4000_outl(0x0, dio_context->port_0_reg);
-+      }
-+
-+      return 0;
-+}
-+
-+/*------------------------------------ COUNTER STUFF ------------------------------------*/
-+
-+static int me4000_cnt_ioctl(struct inode *inode_p, struct file *file_p,
-+                          unsigned int service, unsigned long arg)
-+{
-+      me4000_cnt_context_t *cnt_context;
-+
-+      CALL_PDEBUG("me4000_cnt_ioctl() is executed\n");
-+
-+      cnt_context = file_p->private_data;
-+
-+      if (_IOC_TYPE(service) != ME4000_MAGIC) {
-+              printk(KERN_ERR "me4000_dio_ioctl():Wrong magic number\n");
-+              return -ENOTTY;
-+      }
-+      if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-+              printk(KERN_ERR "me4000_dio_ioctl():Service number to high\n");
-+              return -ENOTTY;
-+      }
-+
-+      switch (service) {
-+      case ME4000_CNT_READ:
-+              return me4000_cnt_read((me4000_cnt_t *) arg, cnt_context);
-+      case ME4000_CNT_WRITE:
-+              return me4000_cnt_write((me4000_cnt_t *) arg, cnt_context);
-+      case ME4000_CNT_CONFIG:
-+              return me4000_cnt_config((me4000_cnt_config_t *) arg,
-+                                       cnt_context);
-+      case ME4000_CNT_RESET:
-+              return me4000_cnt_reset(cnt_context);
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_dio_ioctl():Invalid service number %d\n",
-+                     service);
-+              return -ENOTTY;
-+      }
-+      return 0;
-+}
-+
-+static int me4000_cnt_config(me4000_cnt_config_t * arg,
-+                           me4000_cnt_context_t * cnt_context)
-+{
-+      me4000_cnt_config_t cmd;
-+      u8 counter;
-+      u8 mode;
-+      int err;
-+
-+      CALL_PDEBUG("me4000_cnt_config() is executed\n");
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_cnt_config_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_cnt_config():Can't copy from user space\n");
-+              return -EFAULT;
-+      }
-+
-+      /* Check counter parameter */
-+      switch (cmd.counter) {
-+      case ME4000_CNT_COUNTER_0:
-+              counter = ME4000_CNT_CTRL_BIT_COUNTER_0;
-+              break;
-+      case ME4000_CNT_COUNTER_1:
-+              counter = ME4000_CNT_CTRL_BIT_COUNTER_1;
-+              break;
-+      case ME4000_CNT_COUNTER_2:
-+              counter = ME4000_CNT_CTRL_BIT_COUNTER_2;
-+              break;
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_cnt_config():Counter %d is not available\n",
-+                     cmd.counter);
-+              return -EINVAL;
-+      }
-+
-+      /* Check mode parameter */
-+      switch (cmd.mode) {
-+      case ME4000_CNT_MODE_0:
-+              mode = ME4000_CNT_CTRL_BIT_MODE_0;
-+              break;
-+      case ME4000_CNT_MODE_1:
-+              mode = ME4000_CNT_CTRL_BIT_MODE_1;
-+              break;
-+      case ME4000_CNT_MODE_2:
-+              mode = ME4000_CNT_CTRL_BIT_MODE_2;
-+              break;
-+      case ME4000_CNT_MODE_3:
-+              mode = ME4000_CNT_CTRL_BIT_MODE_3;
-+              break;
-+      case ME4000_CNT_MODE_4:
-+              mode = ME4000_CNT_CTRL_BIT_MODE_4;
-+              break;
-+      case ME4000_CNT_MODE_5:
-+              mode = ME4000_CNT_CTRL_BIT_MODE_5;
-+              break;
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_cnt_config():Mode %d is not available\n",
-+                     cmd.mode);
-+              return -EINVAL;
-+      }
-+
-+      /* Write the control word */
-+      me4000_outb((counter | mode | 0x30), cnt_context->ctrl_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_cnt_read(me4000_cnt_t * arg,
-+                         me4000_cnt_context_t * cnt_context)
-+{
-+      me4000_cnt_t cmd;
-+      u8 tmp;
-+      int err;
-+
-+      CALL_PDEBUG("me4000_cnt_read() is executed\n");
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_cnt_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_cnt_read():Can't copy from user space\n");
-+              return -EFAULT;
-+      }
-+
-+      /* Read counter */
-+      switch (cmd.counter) {
-+      case ME4000_CNT_COUNTER_0:
-+              tmp = me4000_inb(cnt_context->counter_0_reg);
-+              cmd.value = tmp;
-+              tmp = me4000_inb(cnt_context->counter_0_reg);
-+              cmd.value |= ((u16) tmp) << 8;
-+              break;
-+      case ME4000_CNT_COUNTER_1:
-+              tmp = me4000_inb(cnt_context->counter_1_reg);
-+              cmd.value = tmp;
-+              tmp = me4000_inb(cnt_context->counter_1_reg);
-+              cmd.value |= ((u16) tmp) << 8;
-+              break;
-+      case ME4000_CNT_COUNTER_2:
-+              tmp = me4000_inb(cnt_context->counter_2_reg);
-+              cmd.value = tmp;
-+              tmp = me4000_inb(cnt_context->counter_2_reg);
-+              cmd.value |= ((u16) tmp) << 8;
-+              break;
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_cnt_read():Counter %d is not available\n",
-+                     cmd.counter);
-+              return -EINVAL;
-+      }
-+
-+      /* Copy result back to user */
-+      err = copy_to_user(arg, &cmd, sizeof(me4000_cnt_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_cnt_read():Can't copy to user space\n");
-+              return -EFAULT;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_cnt_write(me4000_cnt_t * arg,
-+                          me4000_cnt_context_t * cnt_context)
-+{
-+      me4000_cnt_t cmd;
-+      u8 tmp;
-+      int err;
-+
-+      CALL_PDEBUG("me4000_cnt_write() is executed\n");
-+
-+      /* Copy data from user */
-+      err = copy_from_user(&cmd, arg, sizeof(me4000_cnt_t));
-+      if (err) {
-+              printk(KERN_ERR
-+                     "ME4000:me4000_cnt_write():Can't copy from user space\n");
-+              return -EFAULT;
-+      }
-+
-+      /* Write counter */
-+      switch (cmd.counter) {
-+      case ME4000_CNT_COUNTER_0:
-+              tmp = cmd.value & 0xFF;
-+              me4000_outb(tmp, cnt_context->counter_0_reg);
-+              tmp = (cmd.value >> 8) & 0xFF;
-+              me4000_outb(tmp, cnt_context->counter_0_reg);
-+              break;
-+      case ME4000_CNT_COUNTER_1:
-+              tmp = cmd.value & 0xFF;
-+              me4000_outb(tmp, cnt_context->counter_1_reg);
-+              tmp = (cmd.value >> 8) & 0xFF;
-+              me4000_outb(tmp, cnt_context->counter_1_reg);
-+              break;
-+      case ME4000_CNT_COUNTER_2:
-+              tmp = cmd.value & 0xFF;
-+              me4000_outb(tmp, cnt_context->counter_2_reg);
-+              tmp = (cmd.value >> 8) & 0xFF;
-+              me4000_outb(tmp, cnt_context->counter_2_reg);
-+              break;
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_cnt_write():Counter %d is not available\n",
-+                     cmd.counter);
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static int me4000_cnt_reset(me4000_cnt_context_t * cnt_context)
-+{
-+      CALL_PDEBUG("me4000_cnt_reset() is executed\n");
-+
-+      /* Set the mode and value for counter 0 */
-+      me4000_outb(0x30, cnt_context->ctrl_reg);
-+      me4000_outb(0x00, cnt_context->counter_0_reg);
-+      me4000_outb(0x00, cnt_context->counter_0_reg);
-+
-+      /* Set the mode and value for counter 1 */
-+      me4000_outb(0x70, cnt_context->ctrl_reg);
-+      me4000_outb(0x00, cnt_context->counter_1_reg);
-+      me4000_outb(0x00, cnt_context->counter_1_reg);
-+
-+      /* Set the mode and value for counter 2 */
-+      me4000_outb(0xB0, cnt_context->ctrl_reg);
-+      me4000_outb(0x00, cnt_context->counter_2_reg);
-+      me4000_outb(0x00, cnt_context->counter_2_reg);
-+
-+      return 0;
-+}
-+
-+/*------------------------------------ External Interrupt stuff ------------------------------------*/
-+
-+static int me4000_ext_int_ioctl(struct inode *inode_p, struct file *file_p,
-+                              unsigned int service, unsigned long arg)
-+{
-+      me4000_ext_int_context_t *ext_int_context;
-+
-+      CALL_PDEBUG("me4000_ext_int_ioctl() is executed\n");
-+
-+      ext_int_context = file_p->private_data;
-+
-+      if (_IOC_TYPE(service) != ME4000_MAGIC) {
-+              printk(KERN_ERR "me4000_ext_int_ioctl():Wrong magic number\n");
-+              return -ENOTTY;
-+      }
-+      if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-+              printk(KERN_ERR
-+                     "me4000_ext_int_ioctl():Service number to high\n");
-+              return -ENOTTY;
-+      }
-+
-+      switch (service) {
-+      case ME4000_EXT_INT_ENABLE:
-+              return me4000_ext_int_enable(ext_int_context);
-+      case ME4000_EXT_INT_DISABLE:
-+              return me4000_ext_int_disable(ext_int_context);
-+      case ME4000_EXT_INT_COUNT:
-+              return me4000_ext_int_count((unsigned long *)arg,
-+                                          ext_int_context);
-+      default:
-+              printk(KERN_ERR
-+                     "ME4000:me4000_ext_int_ioctl():Invalid service number %d\n",
-+                     service);
-+              return -ENOTTY;
-+      }
-+      return 0;
-+}
-+
-+static int me4000_ext_int_enable(me4000_ext_int_context_t * ext_int_context)
-+{
-+      unsigned long tmp;
-+
-+      CALL_PDEBUG("me4000_ext_int_enable() is executed\n");
-+
-+      tmp = me4000_inl(ext_int_context->ctrl_reg);
-+      tmp |= ME4000_AI_CTRL_BIT_EX_IRQ;
-+      me4000_outl(tmp, ext_int_context->ctrl_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ext_int_disable(me4000_ext_int_context_t * ext_int_context)
-+{
-+      unsigned long tmp;
-+
-+      CALL_PDEBUG("me4000_ext_int_disable() is executed\n");
-+
-+      tmp = me4000_inl(ext_int_context->ctrl_reg);
-+      tmp &= ~ME4000_AI_CTRL_BIT_EX_IRQ;
-+      me4000_outl(tmp, ext_int_context->ctrl_reg);
-+
-+      return 0;
-+}
-+
-+static int me4000_ext_int_count(unsigned long *arg,
-+                              me4000_ext_int_context_t * ext_int_context)
-+{
-+
-+      CALL_PDEBUG("me4000_ext_int_count() is executed\n");
-+
-+      put_user(ext_int_context->int_count, arg);
-+      return 0;
-+}
-+
-+/*------------------------------------ General stuff ------------------------------------*/
-+
-+static int me4000_get_user_info(me4000_user_info_t * arg,
-+                              me4000_info_t * board_info)
-+{
-+      me4000_user_info_t user_info;
-+
-+      CALL_PDEBUG("me4000_get_user_info() is executed\n");
-+
-+      user_info.board_count = board_info->board_count;
-+      user_info.plx_regbase = board_info->plx_regbase;
-+      user_info.plx_regbase_size = board_info->plx_regbase_size;
-+      user_info.me4000_regbase = board_info->me4000_regbase;
-+      user_info.me4000_regbase_size = board_info->me4000_regbase_size;
-+      user_info.serial_no = board_info->serial_no;
-+      user_info.hw_revision = board_info->hw_revision;
-+      user_info.vendor_id = board_info->vendor_id;
-+      user_info.device_id = board_info->device_id;
-+      user_info.pci_bus_no = board_info->pci_bus_no;
-+      user_info.pci_dev_no = board_info->pci_dev_no;
-+      user_info.pci_func_no = board_info->pci_func_no;
-+      user_info.irq = board_info->irq;
-+      user_info.irq_count = board_info->irq_count;
-+      user_info.driver_version = ME4000_DRIVER_VERSION;
-+      user_info.ao_count = board_info->board_p->ao.count;
-+      user_info.ao_fifo_count = board_info->board_p->ao.fifo_count;
-+
-+      user_info.ai_count = board_info->board_p->ai.count;
-+      user_info.ai_sh_count = board_info->board_p->ai.sh_count;
-+      user_info.ai_ex_trig_analog = board_info->board_p->ai.ex_trig_analog;
-+
-+      user_info.dio_count = board_info->board_p->dio.count;
-+
-+      user_info.cnt_count = board_info->board_p->cnt.count;
-+
-+      if (copy_to_user(arg, &user_info, sizeof(me4000_user_info_t)))
-+              return -EFAULT;
-+
-+      return 0;
-+}
-+
-+/*------------------------------------ ISR STUFF ------------------------------------*/
-+
-+static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode)
-+{
-+      int result = 0;
-+      me4000_ext_int_context_t *ext_int_context;
-+
-+      CALL_PDEBUG("me4000_ext_int_fasync() is executed\n");
-+
-+      ext_int_context = file_ptr->private_data;
-+
-+      result =
-+          fasync_helper(fd, file_ptr, mode, &ext_int_context->fasync_ptr);
-+
-+      CALL_PDEBUG("me4000_ext_int_fasync() is leaved\n");
-+      return result;
-+}
-+
-+static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
-+{
-+      u32 tmp;
-+      u32 value;
-+      me4000_ao_context_t *ao_context;
-+      int i;
-+      int c = 0;
-+      int c1 = 0;
-+      //unsigned long before;
-+      //unsigned long after;
-+
-+      ISR_PDEBUG("me4000_ao_isr() is executed\n");
-+
-+      ao_context = dev_id;
-+
-+      /* Check if irq number is right */
-+      if (irq != ao_context->irq) {
-+              ISR_PDEBUG("me4000_ao_isr():incorrect interrupt num: %d\n",
-+                         irq);
-+              return IRQ_NONE;
-+      }
-+
-+      /* Check if this DAC rised an interrupt */
-+      if (!
-+          ((0x1 << (ao_context->index + 3)) &
-+           me4000_inl(ao_context->irq_status_reg))) {
-+              ISR_PDEBUG("me4000_ao_isr():Not this DAC\n");
-+              return IRQ_NONE;
-+      }
-+
-+      /* Read status register to find out what happened */
-+      tmp = me4000_inl(ao_context->status_reg);
-+
-+      if (!(tmp & ME4000_AO_STATUS_BIT_EF) && (tmp & ME4000_AO_STATUS_BIT_HF)
-+          && (tmp & ME4000_AO_STATUS_BIT_HF)) {
-+              c = ME4000_AO_FIFO_COUNT;
-+              ISR_PDEBUG("me4000_ao_isr():Fifo empty\n");
-+      } else if ((tmp & ME4000_AO_STATUS_BIT_EF)
-+                 && (tmp & ME4000_AO_STATUS_BIT_HF)
-+                 && (tmp & ME4000_AO_STATUS_BIT_HF)) {
-+              c = ME4000_AO_FIFO_COUNT / 2;
-+              ISR_PDEBUG("me4000_ao_isr():Fifo under half full\n");
-+      } else {
-+              c = 0;
-+              ISR_PDEBUG("me4000_ao_isr():Fifo full\n");
-+      }
-+
-+      ISR_PDEBUG("me4000_ao_isr():Try to write 0x%04X values\n", c);
-+
-+      while (1) {
-+              c1 = me4000_values_to_end(ao_context->circ_buf,
-+                                        ME4000_AO_BUFFER_COUNT);
-+              ISR_PDEBUG("me4000_ao_isr():Values to end = %d\n", c1);
-+              if (c1 > c)
-+                      c1 = c;
-+
-+              if (c1 <= 0) {
-+                      ISR_PDEBUG
-+                          ("me4000_ao_isr():Work done or buffer empty\n");
-+                      break;
-+              }
-+              //rdtscl(before);
-+              if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG) ||
-+                  ((ao_context->fifo_reg & 0xFF) == ME4000_AO_03_FIFO_REG)) {
-+                      for (i = 0; i < c1; i++) {
-+                              value =
-+                                  ((u32)
-+                                   (*
-+                                    (ao_context->circ_buf.buf +
-+                                     ao_context->circ_buf.tail + i))) << 16;
-+                              outl(value, ao_context->fifo_reg);
-+                      }
-+              } else
-+                      outsw(ao_context->fifo_reg,
-+                            ao_context->circ_buf.buf +
-+                            ao_context->circ_buf.tail, c1);
-+
-+              //rdtscl(after);
-+              //printk(KERN_ERR"ME4000:me4000_ao_isr():Time lapse = %lu\n", after - before);
-+
-+              ao_context->circ_buf.tail =
-+                  (ao_context->circ_buf.tail + c1) & (ME4000_AO_BUFFER_COUNT -
-+                                                      1);
-+              ISR_PDEBUG("me4000_ao_isr():%d values wrote to port 0x%04X\n",
-+                         c1, ao_context->fifo_reg);
-+              c -= c1;
-+      }
-+
-+      /* If there are no values left in the buffer, disable interrupts */
-+      spin_lock(&ao_context->int_lock);
-+      if (!me4000_buf_count(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) {
-+              ISR_PDEBUG
-+                  ("me4000_ao_isr():Disable Interrupt because no values left in buffer\n");
-+              tmp = me4000_inl(ao_context->ctrl_reg);
-+              tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ;
-+              me4000_outl(tmp, ao_context->ctrl_reg);
-+      }
-+      spin_unlock(&ao_context->int_lock);
-+
-+      /* Reset the interrupt */
-+      spin_lock(&ao_context->int_lock);
-+      tmp = me4000_inl(ao_context->ctrl_reg);
-+      tmp |= ME4000_AO_CTRL_BIT_RESET_IRQ;
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+      tmp &= ~ME4000_AO_CTRL_BIT_RESET_IRQ;
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+
-+      /* If state machine is stopped, flow was interrupted */
-+      if (!(me4000_inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM)) {
-+              printk(KERN_ERR "ME4000:me4000_ao_isr():Broken pipe\n");
-+              ao_context->pipe_flag = 1;      // Set flag in order to inform write routine
-+              tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ;  // Disable interrupt
-+      }
-+      me4000_outl(tmp, ao_context->ctrl_reg);
-+      spin_unlock(&ao_context->int_lock);
-+
-+      /* Wake up waiting process */
-+      wake_up_interruptible(&(ao_context->wait_queue));
-+
-+      /* Count the interrupt */
-+      ao_context->board_info->irq_count++;
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
-+{
-+      u32 tmp;
-+      me4000_ai_context_t *ai_context;
-+      int i;
-+      int c = 0;
-+      int c1 = 0;
-+#ifdef ME4000_ISR_DEBUG
-+      unsigned long before;
-+      unsigned long after;
-+#endif
-+
-+      ISR_PDEBUG("me4000_ai_isr() is executed\n");
-+
-+#ifdef ME4000_ISR_DEBUG
-+      rdtscl(before);
-+#endif
-+
-+      ai_context = dev_id;
-+
-+      /* Check if irq number is right */
-+      if (irq != ai_context->irq) {
-+              ISR_PDEBUG("me4000_ai_isr():incorrect interrupt num: %d\n",
-+                         irq);
-+              return IRQ_NONE;
-+      }
-+
-+      if (me4000_inl(ai_context->irq_status_reg) &
-+          ME4000_IRQ_STATUS_BIT_AI_HF) {
-+              ISR_PDEBUG
-+                  ("me4000_ai_isr():Fifo half full interrupt occured\n");
-+
-+              /* Read status register to find out what happened */
-+              tmp = me4000_inl(ai_context->ctrl_reg);
-+
-+              if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
-+                  !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
-+                  && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
-+                      ISR_PDEBUG("me4000_ai_isr():Fifo full\n");
-+                      c = ME4000_AI_FIFO_COUNT;
-+
-+                      /* FIFO overflow, so stop conversion and disable all interrupts */
-+                      spin_lock(&ai_context->int_lock);
-+                      tmp = me4000_inl(ai_context->ctrl_reg);
-+                      tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-+                      tmp &=
-+                          ~(ME4000_AI_CTRL_BIT_HF_IRQ |
-+                            ME4000_AI_CTRL_BIT_SC_IRQ);
-+                      outl(tmp, ai_context->ctrl_reg);
-+                      spin_unlock(&ai_context->int_lock);
-+              } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
-+                         !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
-+                         && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
-+                      ISR_PDEBUG("me4000_ai_isr():Fifo half full\n");
-+                      c = ME4000_AI_FIFO_COUNT / 2;
-+              } else {
-+                      c = 0;
-+                      ISR_PDEBUG
-+                          ("me4000_ai_isr():Can't determine state of fifo\n");
-+              }
-+
-+              ISR_PDEBUG("me4000_ai_isr():Try to read %d values\n", c);
-+
-+              while (1) {
-+                      c1 = me4000_space_to_end(ai_context->circ_buf,
-+                                               ME4000_AI_BUFFER_COUNT);
-+                      ISR_PDEBUG("me4000_ai_isr():Space to end = %d\n", c1);
-+                      if (c1 > c)
-+                              c1 = c;
-+
-+                      if (c1 <= 0) {
-+                              ISR_PDEBUG
-+                                  ("me4000_ai_isr():Work done or buffer full\n");
-+                              break;
-+                      }
-+
-+                      insw(ai_context->data_reg,
-+                           ai_context->circ_buf.buf +
-+                           ai_context->circ_buf.head, c1);
-+                      ai_context->circ_buf.head =
-+                          (ai_context->circ_buf.head +
-+                           c1) & (ME4000_AI_BUFFER_COUNT - 1);
-+                      c -= c1;
-+              }
-+
-+              /* Work is done, so reset the interrupt */
-+              ISR_PDEBUG
-+                  ("me4000_ai_isr():reset interrupt fifo half full interrupt\n");
-+              spin_lock(&ai_context->int_lock);
-+              tmp = me4000_inl(ai_context->ctrl_reg);
-+              tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
-+              me4000_outl(tmp, ai_context->ctrl_reg);
-+              tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
-+              me4000_outl(tmp, ai_context->ctrl_reg);
-+              spin_unlock(&ai_context->int_lock);
-+      }
-+
-+      if (me4000_inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
-+              ISR_PDEBUG
-+                  ("me4000_ai_isr():Sample counter interrupt occured\n");
-+
-+              if (!ai_context->sample_counter_reload) {
-+                      ISR_PDEBUG
-+                          ("me4000_ai_isr():Single data block available\n");
-+
-+                      /* Poll data until fifo empty */
-+                      for (i = 0;
-+                           (i < ME4000_AI_FIFO_COUNT / 2)
-+                           && (inl(ai_context->ctrl_reg) &
-+                               ME4000_AI_STATUS_BIT_EF_DATA); i++) {
-+                              if (me4000_space_to_end
-+                                  (ai_context->circ_buf,
-+                                   ME4000_AI_BUFFER_COUNT)) {
-+                                      *(ai_context->circ_buf.buf +
-+                                        ai_context->circ_buf.head) =
-+               inw(ai_context->data_reg);
-+                                      ai_context->circ_buf.head =
-+                                          (ai_context->circ_buf.head +
-+                                           1) & (ME4000_AI_BUFFER_COUNT - 1);
-+                              } else
-+                                      break;
-+                      }
-+                      ISR_PDEBUG("me4000_ai_isr():%d values read\n", i);
-+              } else {
-+                      if (ai_context->sample_counter <=
-+                          ME4000_AI_FIFO_COUNT / 2) {
-+                              ISR_PDEBUG
-+                                  ("me4000_ai_isr():Interrupt from adjustable half full threshold\n");
-+
-+                              /* Read status register to find out what happened */
-+                              tmp = me4000_inl(ai_context->ctrl_reg);
-+
-+                              if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
-+                                  !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
-+                                  && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
-+                                      ISR_PDEBUG
-+                                          ("me4000_ai_isr():Fifo full\n");
-+                                      c = ME4000_AI_FIFO_COUNT;
-+
-+                                      /* FIFO overflow, so stop conversion */
-+                                      spin_lock(&ai_context->int_lock);
-+                                      tmp = me4000_inl(ai_context->ctrl_reg);
-+                                      tmp |=
-+                                          ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-+                                      outl(tmp, ai_context->ctrl_reg);
-+                                      spin_unlock(&ai_context->int_lock);
-+                              } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
-+                                         && !(tmp &
-+                                              ME4000_AI_STATUS_BIT_HF_DATA)
-+                                         && (tmp &
-+                                             ME4000_AI_STATUS_BIT_EF_DATA)) {
-+                                      ISR_PDEBUG
-+                                          ("me4000_ai_isr():Fifo half full\n");
-+                                      c = ME4000_AI_FIFO_COUNT / 2;
-+                              } else {
-+                                      c = ai_context->sample_counter;
-+                                      ISR_PDEBUG
-+                                          ("me4000_ai_isr():Sample count values\n");
-+                              }
-+
-+                              ISR_PDEBUG
-+                                  ("me4000_ai_isr():Try to read %d values\n",
-+                                   c);
-+
-+                              while (1) {
-+                                      c1 = me4000_space_to_end(ai_context->
-+                                                               circ_buf,
-+                                                               ME4000_AI_BUFFER_COUNT);
-+                                      ISR_PDEBUG
-+                                          ("me4000_ai_isr():Space to end = %d\n",
-+                                           c1);
-+                                      if (c1 > c)
-+                                              c1 = c;
-+
-+                                      if (c1 <= 0) {
-+                                              ISR_PDEBUG
-+                                                  ("me4000_ai_isr():Work done or buffer full\n");
-+                                              break;
-+                                      }
-+
-+                                      insw(ai_context->data_reg,
-+                                           ai_context->circ_buf.buf +
-+                                           ai_context->circ_buf.head, c1);
-+                                      ai_context->circ_buf.head =
-+                                          (ai_context->circ_buf.head +
-+                                           c1) & (ME4000_AI_BUFFER_COUNT - 1);
-+                                      c -= c1;
-+                              }
-+                      } else {
-+                              ISR_PDEBUG
-+                                  ("me4000_ai_isr():Multiple data block available\n");
-+
-+                              /* Read status register to find out what happened */
-+                              tmp = me4000_inl(ai_context->ctrl_reg);
-+
-+                              if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
-+                                  !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
-+                                  && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
-+                                      ISR_PDEBUG
-+                                          ("me4000_ai_isr():Fifo full\n");
-+                                      c = ME4000_AI_FIFO_COUNT;
-+
-+                                      /* FIFO overflow, so stop conversion */
-+                                      spin_lock(&ai_context->int_lock);
-+                                      tmp = me4000_inl(ai_context->ctrl_reg);
-+                                      tmp |=
-+                                          ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-+                                      outl(tmp, ai_context->ctrl_reg);
-+                                      spin_unlock(&ai_context->int_lock);
-+
-+                                      while (1) {
-+                                              c1 = me4000_space_to_end
-+                                                  (ai_context->circ_buf,
-+                                                   ME4000_AI_BUFFER_COUNT);
-+                                              ISR_PDEBUG
-+                                                  ("me4000_ai_isr():Space to end = %d\n",
-+                                                   c1);
-+                                              if (c1 > c)
-+                                                      c1 = c;
-+
-+                                              if (c1 <= 0) {
-+                                                      ISR_PDEBUG
-+                                                          ("me4000_ai_isr():Work done or buffer full\n");
-+                                                      break;
-+                                              }
-+
-+                                              insw(ai_context->data_reg,
-+                                                   ai_context->circ_buf.buf +
-+                                                   ai_context->circ_buf.head,
-+                                                   c1);
-+                                              ai_context->circ_buf.head =
-+                                                  (ai_context->circ_buf.head +
-+                                                   c1) &
-+                                                  (ME4000_AI_BUFFER_COUNT -
-+                                                   1);
-+                                              c -= c1;
-+                                      }
-+                              } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
-+                                         && !(tmp &
-+                                              ME4000_AI_STATUS_BIT_HF_DATA)
-+                                         && (tmp &
-+                                             ME4000_AI_STATUS_BIT_EF_DATA)) {
-+                                      ISR_PDEBUG
-+                                          ("me4000_ai_isr():Fifo half full\n");
-+                                      c = ME4000_AI_FIFO_COUNT / 2;
-+
-+                                      while (1) {
-+                                              c1 = me4000_space_to_end
-+                                                  (ai_context->circ_buf,
-+                                                   ME4000_AI_BUFFER_COUNT);
-+                                              ISR_PDEBUG
-+                                                  ("me4000_ai_isr():Space to end = %d\n",
-+                                                   c1);
-+                                              if (c1 > c)
-+                                                      c1 = c;
-+
-+                                              if (c1 <= 0) {
-+                                                      ISR_PDEBUG
-+                                                          ("me4000_ai_isr():Work done or buffer full\n");
-+                                                      break;
-+                                              }
-+
-+                                              insw(ai_context->data_reg,
-+                                                   ai_context->circ_buf.buf +
-+                                                   ai_context->circ_buf.head,
-+                                                   c1);
-+                                              ai_context->circ_buf.head =
-+                                                  (ai_context->circ_buf.head +
-+                                                   c1) &
-+                                                  (ME4000_AI_BUFFER_COUNT -
-+                                                   1);
-+                                              c -= c1;
-+                                      }
-+                              } else {
-+                                      /* Poll data until fifo empty */
-+                                      for (i = 0;
-+                                           (i < ME4000_AI_FIFO_COUNT / 2)
-+                                           && (inl(ai_context->ctrl_reg) &
-+                                               ME4000_AI_STATUS_BIT_EF_DATA);
-+                                           i++) {
-+                                              if (me4000_space_to_end
-+                                                  (ai_context->circ_buf,
-+                                                   ME4000_AI_BUFFER_COUNT)) {
-+                                                      *(ai_context->circ_buf.
-+                                                        buf +
-+                                                        ai_context->circ_buf.
-+                                                        head) =
-+                                     inw(ai_context->data_reg);
-+                                                      ai_context->circ_buf.
-+                                                          head =
-+                                                          (ai_context->
-+                                                           circ_buf.head +
-+                                                           1) &
-+                                                          (ME4000_AI_BUFFER_COUNT
-+                                                           - 1);
-+                                              } else
-+                                                      break;
-+                                      }
-+                                      ISR_PDEBUG
-+                                          ("me4000_ai_isr():%d values read\n",
-+                                           i);
-+                              }
-+                      }
-+              }
-+
-+              /* Work is done, so reset the interrupt */
-+              ISR_PDEBUG
-+                  ("me4000_ai_isr():reset interrupt from sample counter\n");
-+              spin_lock(&ai_context->int_lock);
-+              tmp = me4000_inl(ai_context->ctrl_reg);
-+              tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
-+              me4000_outl(tmp, ai_context->ctrl_reg);
-+              tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
-+              me4000_outl(tmp, ai_context->ctrl_reg);
-+              spin_unlock(&ai_context->int_lock);
-+      }
-+
-+      /* Values are now available, so wake up waiting process */
-+      if (me4000_buf_count(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) {
-+              ISR_PDEBUG("me4000_ai_isr():Wake up waiting process\n");
-+              wake_up_interruptible(&(ai_context->wait_queue));
-+      }
-+
-+      /* If there is no space left in the buffer, disable interrupts */
-+      spin_lock(&ai_context->int_lock);
-+      if (!me4000_buf_space(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) {
-+              ISR_PDEBUG
-+                  ("me4000_ai_isr():Disable Interrupt because no space left in buffer\n");
-+              tmp = me4000_inl(ai_context->ctrl_reg);
-+              tmp &=
-+                  ~(ME4000_AI_CTRL_BIT_SC_IRQ | ME4000_AI_CTRL_BIT_HF_IRQ |
-+                    ME4000_AI_CTRL_BIT_LE_IRQ);
-+              me4000_outl(tmp, ai_context->ctrl_reg);
-+      }
-+      spin_unlock(&ai_context->int_lock);
-+
-+#ifdef ME4000_ISR_DEBUG
-+      rdtscl(after);
-+      printk(KERN_ERR "ME4000:me4000_ai_isr():Time lapse = %lu\n",
-+             after - before);
-+#endif
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t me4000_ext_int_isr(int irq, void *dev_id)
-+{
-+      me4000_ext_int_context_t *ext_int_context;
-+      unsigned long tmp;
-+
-+      ISR_PDEBUG("me4000_ext_int_isr() is executed\n");
-+
-+      ext_int_context = dev_id;
-+
-+      /* Check if irq number is right */
-+      if (irq != ext_int_context->irq) {
-+              ISR_PDEBUG("me4000_ext_int_isr():incorrect interrupt num: %d\n",
-+                         irq);
-+              return IRQ_NONE;
-+      }
-+
-+      if (me4000_inl(ext_int_context->irq_status_reg) &
-+          ME4000_IRQ_STATUS_BIT_EX) {
-+              ISR_PDEBUG("me4000_ext_int_isr():External interrupt occured\n");
-+              tmp = me4000_inl(ext_int_context->ctrl_reg);
-+              tmp |= ME4000_AI_CTRL_BIT_EX_IRQ_RESET;
-+              me4000_outl(tmp, ext_int_context->ctrl_reg);
-+              tmp &= ~ME4000_AI_CTRL_BIT_EX_IRQ_RESET;
-+              me4000_outl(tmp, ext_int_context->ctrl_reg);
-+
-+              ext_int_context->int_count++;
-+
-+              if (ext_int_context->fasync_ptr) {
-+                      ISR_PDEBUG
-+                          ("me2600_ext_int_isr():Send signal to process\n");
-+                      kill_fasync(&ext_int_context->fasync_ptr, SIGIO,
-+                                  POLL_IN);
-+              }
-+      }
-+
-+      return IRQ_HANDLED;
-+}
-+
-+void __exit me4000_module_exit(void)
-+{
-+      struct list_head *board_p;
-+      me4000_info_t *board_info;
-+
-+      CALL_PDEBUG("cleanup_module() is executed\n");
-+
-+      unregister_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME);
-+
-+      unregister_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME);
-+
-+      unregister_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME);
-+
-+      unregister_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME);
-+
-+      unregister_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME);
-+
-+      remove_proc_entry("me4000", NULL);
-+
-+      pci_unregister_driver(&me4000_driver);
-+
-+      /* Reset the boards */
-+      for (board_p = me4000_board_info_list.next;
-+           board_p != &me4000_board_info_list; board_p = board_p->next) {
-+              board_info = list_entry(board_p, me4000_info_t, list);
-+              me4000_reset_board(board_info);
-+      }
-+
-+      clear_board_info_list();
-+}
-+
-+module_exit(me4000_module_exit);
-+
-+static int me4000_read_procmem(char *buf, char **start, off_t offset, int count,
-+                             int *eof, void *data)
-+{
-+      int len = 0;
-+      int limit = count - 1000;
-+      me4000_info_t *board_info;
-+      struct list_head *ptr;
-+
-+      len += sprintf(buf + len, "\nME4000 DRIVER VERSION %X.%X.%X\n\n",
-+                     (ME4000_DRIVER_VERSION & 0xFF0000) >> 16,
-+                     (ME4000_DRIVER_VERSION & 0xFF00) >> 8,
-+                     (ME4000_DRIVER_VERSION & 0xFF));
-+
-+      /* Search for the board context */
-+      for (ptr = me4000_board_info_list.next;
-+           (ptr != &me4000_board_info_list) && (len < limit);
-+           ptr = ptr->next) {
-+              board_info = list_entry(ptr, me4000_info_t, list);
-+
-+              len +=
-+                  sprintf(buf + len, "Board number %d:\n",
-+                          board_info->board_count);
-+              len += sprintf(buf + len, "---------------\n");
-+              len +=
-+                  sprintf(buf + len, "PLX base register = 0x%lX\n",
-+                          board_info->plx_regbase);
-+              len +=
-+                  sprintf(buf + len, "PLX base register size = 0x%lX\n",
-+                          board_info->plx_regbase_size);
-+              len +=
-+                  sprintf(buf + len, "ME4000 base register = 0x%lX\n",
-+                          board_info->me4000_regbase);
-+              len +=
-+                  sprintf(buf + len, "ME4000 base register size = 0x%lX\n",
-+                          board_info->me4000_regbase_size);
-+              len +=
-+                  sprintf(buf + len, "Serial number = 0x%X\n",
-+                          board_info->serial_no);
-+              len +=
-+                  sprintf(buf + len, "Hardware revision = 0x%X\n",
-+                          board_info->hw_revision);
-+              len +=
-+                  sprintf(buf + len, "Vendor id = 0x%X\n",
-+                          board_info->vendor_id);
-+              len +=
-+                  sprintf(buf + len, "Device id = 0x%X\n",
-+                          board_info->device_id);
-+              len +=
-+                  sprintf(buf + len, "PCI bus number = %d\n",
-+                          board_info->pci_bus_no);
-+              len +=
-+                  sprintf(buf + len, "PCI device number = %d\n",
-+                          board_info->pci_dev_no);
-+              len +=
-+                  sprintf(buf + len, "PCI function number = %d\n",
-+                          board_info->pci_func_no);
-+              len += sprintf(buf + len, "IRQ = %u\n", board_info->irq);
-+              len +=
-+                  sprintf(buf + len,
-+                          "Count of interrupts since module was loaded = %d\n",
-+                          board_info->irq_count);
-+
-+              len +=
-+                  sprintf(buf + len, "Count of analog outputs = %d\n",
-+                          board_info->board_p->ao.count);
-+              len +=
-+                  sprintf(buf + len, "Count of analog output fifos = %d\n",
-+                          board_info->board_p->ao.fifo_count);
-+
-+              len +=
-+                  sprintf(buf + len, "Count of analog inputs = %d\n",
-+                          board_info->board_p->ai.count);
-+              len +=
-+                  sprintf(buf + len,
-+                          "Count of sample and hold devices for analog input = %d\n",
-+                          board_info->board_p->ai.sh_count);
-+              len +=
-+                  sprintf(buf + len,
-+                          "Analog external trigger available for analog input = %d\n",
-+                          board_info->board_p->ai.ex_trig_analog);
-+
-+              len +=
-+                  sprintf(buf + len, "Count of digital ports = %d\n",
-+                          board_info->board_p->dio.count);
-+
-+              len +=
-+                  sprintf(buf + len, "Count of counter devices = %d\n",
-+                          board_info->board_p->cnt.count);
-+              len +=
-+                  sprintf(buf + len, "AI control register = 0x%08X\n",
-+                          inl(board_info->me4000_regbase +
-+                              ME4000_AI_CTRL_REG));
-+
-+              len += sprintf(buf + len, "AO 0 control register = 0x%08X\n",
-+                             inl(board_info->me4000_regbase +
-+                                 ME4000_AO_00_CTRL_REG));
-+              len +=
-+                  sprintf(buf + len, "AO 0 status register = 0x%08X\n",
-+                          inl(board_info->me4000_regbase +
-+                              ME4000_AO_00_STATUS_REG));
-+              len +=
-+                  sprintf(buf + len, "AO 1 control register = 0x%08X\n",
-+                          inl(board_info->me4000_regbase +
-+                              ME4000_AO_01_CTRL_REG));
-+              len +=
-+                  sprintf(buf + len, "AO 1 status register = 0x%08X\n",
-+                          inl(board_info->me4000_regbase +
-+                              ME4000_AO_01_STATUS_REG));
-+              len +=
-+                  sprintf(buf + len, "AO 2 control register = 0x%08X\n",
-+                          inl(board_info->me4000_regbase +
-+                              ME4000_AO_02_CTRL_REG));
-+              len +=
-+                  sprintf(buf + len, "AO 2 status register = 0x%08X\n",
-+                          inl(board_info->me4000_regbase +
-+                              ME4000_AO_02_STATUS_REG));
-+              len +=
-+                  sprintf(buf + len, "AO 3 control register = 0x%08X\n",
-+                          inl(board_info->me4000_regbase +
-+                              ME4000_AO_03_CTRL_REG));
-+              len +=
-+                  sprintf(buf + len, "AO 3 status register = 0x%08X\n",
-+                          inl(board_info->me4000_regbase +
-+                              ME4000_AO_03_STATUS_REG));
-+      }
-+
-+      *eof = 1;
-+      return len;
-+}
-diff --git a/drivers/staging/me4000/me4000.h b/drivers/staging/me4000/me4000.h
-new file mode 100644
-index 0000000..c35e4b9
---- /dev/null
-+++ b/drivers/staging/me4000/me4000.h
-@@ -0,0 +1,954 @@
-+/*
-+ * Copyright (C) 2003 Meilhaus Electronic GmbH (support@meilhaus.de)
-+ *
-+ * Source File : me4000.h
-+ * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
-+ */
-+
-+#ifndef _ME4000_H_
-+#define _ME4000_H_
-+
-+#ifdef __KERNEL__
-+
-+/*=============================================================================
-+  The version of the driver release
-+  ===========================================================================*/
-+
-+#define ME4000_DRIVER_VERSION  0x10009        // Version 1.00.09
-+
-+/*=============================================================================
-+  Debug section
-+  ===========================================================================*/
-+
-+#undef ME4000_CALL_DEBUG      // Debug function entry and exit
-+#undef ME4000_ISR_DEBUG               // Debug the interrupt service routine
-+#undef ME4000_PORT_DEBUG      // Debug port access
-+#undef ME4000_DEBUG           // General purpose debug masseges
-+
-+#ifdef ME4000_CALL_DEBUG
-+#undef CALL_PDEBUG
-+#define CALL_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
-+#else
-+# define CALL_PDEBUG(fmt, args...)    // no debugging, do nothing
-+#endif
-+
-+#ifdef ME4000_ISR_DEBUG
-+#undef ISR_PDEBUG
-+#define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
-+#else
-+#define ISR_PDEBUG(fmt, args...)      // no debugging, do nothing
-+#endif
-+
-+#ifdef ME4000_PORT_DEBUG
-+#undef PORT_PDEBUG
-+#define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
-+#else
-+#define PORT_PDEBUG(fmt, args...)     // no debugging, do nothing
-+#endif
-+
-+#ifdef ME4000_DEBUG
-+#undef PDEBUG
-+#define PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
-+#else
-+#define PDEBUG(fmt, args...)  // no debugging, do nothing
-+#endif
-+
-+/*=============================================================================
-+  PCI vendor and device IDs
-+  ===========================================================================*/
-+
-+#define PCI_VENDOR_ID_MEILHAUS 0x1402
-+
-+#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650  // Low Cost version
-+
-+#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660  // Standard version
-+#define PCI_DEVICE_ID_MEILHAUS_ME4660I        0x4661  // Isolated version
-+#define PCI_DEVICE_ID_MEILHAUS_ME4660S        0x4662  // Standard version with Sample and Hold
-+#define PCI_DEVICE_ID_MEILHAUS_ME4660IS       0x4663  // Isolated version with Sample and Hold
-+
-+#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670  // Standard version
-+#define PCI_DEVICE_ID_MEILHAUS_ME4670I        0x4671  // Isolated version
-+#define PCI_DEVICE_ID_MEILHAUS_ME4670S        0x4672  // Standard version with Sample and Hold
-+#define PCI_DEVICE_ID_MEILHAUS_ME4670IS       0x4673  // Isolated version with Sample and Hold
-+
-+#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680  // Standard version
-+#define PCI_DEVICE_ID_MEILHAUS_ME4680I        0x4681  // Isolated version
-+#define PCI_DEVICE_ID_MEILHAUS_ME4680S        0x4682  // Standard version with Sample and Hold
-+#define PCI_DEVICE_ID_MEILHAUS_ME4680IS       0x4683  // Isolated version with Sample and Hold
-+
-+/*=============================================================================
-+  Device names, for entries in /proc/..
-+  ===========================================================================*/
-+
-+#define ME4000_NAME           "me4000"
-+#define ME4000_AO_NAME                "me4000_ao"
-+#define ME4000_AI_NAME                "me4000_ai"
-+#define ME4000_DIO_NAME               "me4000_dio"
-+#define ME4000_CNT_NAME               "me4000_cnt"
-+#define ME4000_EXT_INT_NAME   "me4000_ext_int"
-+
-+/*=============================================================================
-+  ME-4000 base register offsets
-+  ===========================================================================*/
-+
-+#define ME4000_AO_00_CTRL_REG                 0x00    // R/W
-+#define ME4000_AO_00_STATUS_REG                       0x04    // R/_
-+#define ME4000_AO_00_FIFO_REG                 0x08    // _/W
-+#define ME4000_AO_00_SINGLE_REG                       0x0C    // R/W
-+#define ME4000_AO_00_TIMER_REG                        0x10    // _/W
-+
-+#define ME4000_AO_01_CTRL_REG                 0x18    // R/W
-+#define ME4000_AO_01_STATUS_REG                       0x1C    // R/_
-+#define ME4000_AO_01_FIFO_REG                 0x20    // _/W
-+#define ME4000_AO_01_SINGLE_REG                       0x24    // R/W
-+#define ME4000_AO_01_TIMER_REG                        0x28    // _/W
-+
-+#define ME4000_AO_02_CTRL_REG                 0x30    // R/W
-+#define ME4000_AO_02_STATUS_REG                       0x34    // R/_
-+#define ME4000_AO_02_FIFO_REG                 0x38    // _/W
-+#define ME4000_AO_02_SINGLE_REG                       0x3C    // R/W
-+#define ME4000_AO_02_TIMER_REG                        0x40    // _/W
-+
-+#define ME4000_AO_03_CTRL_REG                 0x48    // R/W
-+#define ME4000_AO_03_STATUS_REG                       0x4C    // R/_
-+#define ME4000_AO_03_FIFO_REG                 0x50    // _/W
-+#define ME4000_AO_03_SINGLE_REG                       0x54    // R/W
-+#define ME4000_AO_03_TIMER_REG                        0x58    // _/W
-+
-+#define ME4000_AI_CTRL_REG                    0x74    // _/W
-+#define ME4000_AI_STATUS_REG                  0x74    // R/_
-+#define ME4000_AI_CHANNEL_LIST_REG            0x78    // _/W
-+#define ME4000_AI_DATA_REG                    0x7C    // R/_
-+#define ME4000_AI_CHAN_TIMER_REG              0x80    // _/W
-+#define ME4000_AI_CHAN_PRE_TIMER_REG          0x84    // _/W
-+#define ME4000_AI_SCAN_TIMER_LOW_REG          0x88    // _/W
-+#define ME4000_AI_SCAN_TIMER_HIGH_REG         0x8C    // _/W
-+#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG      0x90    // _/W
-+#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG     0x94    // _/W
-+#define ME4000_AI_START_REG                   0x98    // R/_
-+
-+#define ME4000_IRQ_STATUS_REG                 0x9C    // R/_
-+
-+#define ME4000_DIO_PORT_0_REG                 0xA0    // R/W
-+#define ME4000_DIO_PORT_1_REG                 0xA4    // R/W
-+#define ME4000_DIO_PORT_2_REG                 0xA8    // R/W
-+#define ME4000_DIO_PORT_3_REG                 0xAC    // R/W
-+#define ME4000_DIO_DIR_REG                    0xB0    // R/W
-+
-+#define ME4000_AO_LOADSETREG_XX                       0xB4    // R/W
-+
-+#define ME4000_DIO_CTRL_REG                   0xB8    // R/W
-+
-+#define ME4000_AO_DEMUX_ADJUST_REG            0xBC    // -/W
-+
-+#define ME4000_AI_SAMPLE_COUNTER_REG          0xC0    // _/W
-+
-+/*=============================================================================
-+  Value to adjust Demux
-+  ===========================================================================*/
-+
-+#define ME4000_AO_DEMUX_ADJUST_VALUE            0x4C
-+
-+/*=============================================================================
-+  Counter base register offsets
-+  ===========================================================================*/
-+
-+#define ME4000_CNT_COUNTER_0_REG              0x00
-+#define ME4000_CNT_COUNTER_1_REG              0x01
-+#define ME4000_CNT_COUNTER_2_REG              0x02
-+#define ME4000_CNT_CTRL_REG                   0x03
-+
-+/*=============================================================================
-+  PLX base register offsets
-+  ===========================================================================*/
-+
-+#define PLX_INTCSR    0x4C    // Interrupt control and status register
-+#define PLX_ICR               0x50    // Initialization control register
-+
-+/*=============================================================================
-+  Bits for the PLX_ICSR register
-+  ===========================================================================*/
-+
-+#define PLX_INTCSR_LOCAL_INT1_EN             0x01     // If set, local interrupt 1 is enabled (r/w)
-+#define PLX_INTCSR_LOCAL_INT1_POL            0x02     // If set, local interrupt 1 polarity is active high (r/w)
-+#define PLX_INTCSR_LOCAL_INT1_STATE          0x04     // If set, local interrupt 1 is active (r/_)
-+#define PLX_INTCSR_LOCAL_INT2_EN             0x08     // If set, local interrupt 2 is enabled (r/w)
-+#define PLX_INTCSR_LOCAL_INT2_POL            0x10     // If set, local interrupt 2 polarity is active high (r/w)
-+#define PLX_INTCSR_LOCAL_INT2_STATE          0x20     // If set, local interrupt 2 is active  (r/_)
-+#define PLX_INTCSR_PCI_INT_EN                0x40     // If set, PCI interrupt is enabled (r/w)
-+#define PLX_INTCSR_SOFT_INT                  0x80     // If set, a software interrupt is generated (r/w)
-+
-+/*=============================================================================
-+  Bits for the PLX_ICR register
-+  ===========================================================================*/
-+
-+#define PLX_ICR_BIT_EEPROM_CLOCK_SET          0x01000000
-+#define PLX_ICR_BIT_EEPROM_CHIP_SELECT                0x02000000
-+#define PLX_ICR_BIT_EEPROM_WRITE              0x04000000
-+#define PLX_ICR_BIT_EEPROM_READ                       0x08000000
-+#define PLX_ICR_BIT_EEPROM_VALID              0x10000000
-+
-+#define PLX_ICR_MASK_EEPROM                   0x1F000000
-+
-+#define EEPROM_DELAY                          1
-+
-+/*=============================================================================
-+  Bits for the ME4000_AO_CTRL_REG register
-+  ===========================================================================*/
-+
-+#define ME4000_AO_CTRL_BIT_MODE_0             0x001
-+#define ME4000_AO_CTRL_BIT_MODE_1             0x002
-+#define ME4000_AO_CTRL_MASK_MODE              0x003
-+#define ME4000_AO_CTRL_BIT_STOP                       0x004
-+#define ME4000_AO_CTRL_BIT_ENABLE_FIFO                0x008
-+#define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG     0x010
-+#define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE               0x020
-+#define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP     0x080
-+#define ME4000_AO_CTRL_BIT_ENABLE_DO          0x100
-+#define ME4000_AO_CTRL_BIT_ENABLE_IRQ         0x200
-+#define ME4000_AO_CTRL_BIT_RESET_IRQ          0x400
-+#define ME4000_AO_CTRL_BIT_EX_TRIG_BOTH               0x800
-+
-+/*=============================================================================
-+  Bits for the ME4000_AO_STATUS_REG register
-+  ===========================================================================*/
-+
-+#define ME4000_AO_STATUS_BIT_FSM              0x01
-+#define ME4000_AO_STATUS_BIT_FF                       0x02
-+#define ME4000_AO_STATUS_BIT_HF                       0x04
-+#define ME4000_AO_STATUS_BIT_EF                       0x08
-+
-+/*=============================================================================
-+  Bits for the ME4000_AI_CTRL_REG register
-+  ===========================================================================*/
-+
-+#define ME4000_AI_CTRL_BIT_MODE_0             0x00000001
-+#define ME4000_AI_CTRL_BIT_MODE_1             0x00000002
-+#define ME4000_AI_CTRL_BIT_MODE_2             0x00000004
-+#define ME4000_AI_CTRL_BIT_SAMPLE_HOLD                0x00000008
-+#define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP     0x00000010
-+#define ME4000_AI_CTRL_BIT_STOP                       0x00000020
-+#define ME4000_AI_CTRL_BIT_CHANNEL_FIFO               0x00000040
-+#define ME4000_AI_CTRL_BIT_DATA_FIFO          0x00000080
-+#define ME4000_AI_CTRL_BIT_FULLSCALE          0x00000100
-+#define ME4000_AI_CTRL_BIT_OFFSET             0x00000200
-+#define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG     0x00000400
-+#define ME4000_AI_CTRL_BIT_EX_TRIG            0x00000800
-+#define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING    0x00001000
-+#define ME4000_AI_CTRL_BIT_EX_IRQ             0x00002000
-+#define ME4000_AI_CTRL_BIT_EX_IRQ_RESET               0x00004000
-+#define ME4000_AI_CTRL_BIT_LE_IRQ             0x00008000
-+#define ME4000_AI_CTRL_BIT_LE_IRQ_RESET               0x00010000
-+#define ME4000_AI_CTRL_BIT_HF_IRQ             0x00020000
-+#define ME4000_AI_CTRL_BIT_HF_IRQ_RESET               0x00040000
-+#define ME4000_AI_CTRL_BIT_SC_IRQ             0x00080000
-+#define ME4000_AI_CTRL_BIT_SC_IRQ_RESET               0x00100000
-+#define ME4000_AI_CTRL_BIT_SC_RELOAD          0x00200000
-+#define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH               0x80000000
-+
-+/*=============================================================================
-+  Bits for the ME4000_AI_STATUS_REG register
-+  ===========================================================================*/
-+
-+#define ME4000_AI_STATUS_BIT_EF_CHANNEL               0x00400000
-+#define ME4000_AI_STATUS_BIT_HF_CHANNEL               0x00800000
-+#define ME4000_AI_STATUS_BIT_FF_CHANNEL               0x01000000
-+#define ME4000_AI_STATUS_BIT_EF_DATA          0x02000000
-+#define ME4000_AI_STATUS_BIT_HF_DATA          0x04000000
-+#define ME4000_AI_STATUS_BIT_FF_DATA          0x08000000
-+#define ME4000_AI_STATUS_BIT_LE                       0x10000000
-+#define ME4000_AI_STATUS_BIT_FSM              0x20000000
-+
-+/*=============================================================================
-+  Bits for the ME4000_IRQ_STATUS_REG register
-+  ===========================================================================*/
-+
-+#define ME4000_IRQ_STATUS_BIT_EX              0x01
-+#define ME4000_IRQ_STATUS_BIT_LE              0x02
-+#define ME4000_IRQ_STATUS_BIT_AI_HF           0x04
-+#define ME4000_IRQ_STATUS_BIT_AO_0_HF         0x08
-+#define ME4000_IRQ_STATUS_BIT_AO_1_HF         0x10
-+#define ME4000_IRQ_STATUS_BIT_AO_2_HF         0x20
-+#define ME4000_IRQ_STATUS_BIT_AO_3_HF         0x40
-+#define ME4000_IRQ_STATUS_BIT_SC              0x80
-+
-+/*=============================================================================
-+  Bits for the ME4000_DIO_CTRL_REG register
-+  ===========================================================================*/
-+
-+#define ME4000_DIO_CTRL_BIT_MODE_0            0X0001
-+#define ME4000_DIO_CTRL_BIT_MODE_1            0X0002
-+#define ME4000_DIO_CTRL_BIT_MODE_2            0X0004
-+#define ME4000_DIO_CTRL_BIT_MODE_3            0X0008
-+#define ME4000_DIO_CTRL_BIT_MODE_4            0X0010
-+#define ME4000_DIO_CTRL_BIT_MODE_5            0X0020
-+#define ME4000_DIO_CTRL_BIT_MODE_6            0X0040
-+#define ME4000_DIO_CTRL_BIT_MODE_7            0X0080
-+
-+#define ME4000_DIO_CTRL_BIT_FUNCTION_0                0X0100
-+#define ME4000_DIO_CTRL_BIT_FUNCTION_1                0X0200
-+
-+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0               0X0400
-+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1               0X0800
-+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2               0X1000
-+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3               0X2000
-+
-+/*=============================================================================
-+  Bits for the ME4000_CNT_CTRL_REG register
-+  ===========================================================================*/
-+
-+#define ME4000_CNT_CTRL_BIT_COUNTER_0  0x00
-+#define ME4000_CNT_CTRL_BIT_COUNTER_1  0x40
-+#define ME4000_CNT_CTRL_BIT_COUNTER_2  0x80
-+
-+#define ME4000_CNT_CTRL_BIT_MODE_0     0x00   // Change state if zero crossing
-+#define ME4000_CNT_CTRL_BIT_MODE_1     0x02   // Retriggerable One-Shot
-+#define ME4000_CNT_CTRL_BIT_MODE_2     0x04   // Asymmetrical divider
-+#define ME4000_CNT_CTRL_BIT_MODE_3     0x06   // Symmetrical divider
-+#define ME4000_CNT_CTRL_BIT_MODE_4     0x08   // Counter start by software trigger
-+#define ME4000_CNT_CTRL_BIT_MODE_5     0x0A   // Counter start by hardware trigger
-+
-+/*=============================================================================
-+  Extract information from minor device number
-+  ===========================================================================*/
-+
-+#define AO_BOARD(dev) ((MINOR(dev) >> 6) & 0x3)
-+#define AO_PORT(dev)  ((MINOR(dev) >> 2) & 0xF)
-+#define AO_MODE(dev)  (MINOR(dev) & 0x3)
-+
-+#define AI_BOARD(dev) ((MINOR(dev) >> 3) & 0x1F)
-+#define AI_MODE(dev)  (MINOR(dev) & 0x7)
-+
-+#define DIO_BOARD(dev) (MINOR(dev))
-+
-+#define CNT_BOARD(dev) (MINOR(dev))
-+
-+#define EXT_INT_BOARD(dev) (MINOR(dev))
-+
-+/*=============================================================================
-+  Circular buffer used for analog input/output reads/writes.
-+  ===========================================================================*/
-+
-+typedef struct me4000_circ_buf {
-+      s16 *buf;
-+      int volatile head;
-+      int volatile tail;
-+} me4000_circ_buf_t;
-+
-+/*=============================================================================
-+  Information about the hardware capabilities
-+  ===========================================================================*/
-+
-+typedef struct me4000_ao_info {
-+      int count;
-+      int fifo_count;
-+} me4000_ao_info_t;
-+
-+typedef struct me4000_ai_info {
-+      int count;
-+      int sh_count;
-+      int diff_count;
-+      int ex_trig_analog;
-+} me4000_ai_info_t;
-+
-+typedef struct me4000_dio_info {
-+      int count;
-+} me4000_dio_info_t;
-+
-+typedef struct me4000_cnt_info {
-+      int count;
-+} me4000_cnt_info_t;
-+
-+typedef struct me4000_board {
-+      u16 vendor_id;
-+      u16 device_id;
-+      me4000_ao_info_t ao;
-+      me4000_ai_info_t ai;
-+      me4000_dio_info_t dio;
-+      me4000_cnt_info_t cnt;
-+} me4000_board_t;
-+
-+static me4000_board_t me4000_boards[] = {
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4610, {0, 0}, {16, 0, 0, 0}, {4}, {3}},
-+
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
-+
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4660, {2, 0}, {16, 0, 0, 0}, {4}, {3}},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4661, {2, 0}, {16, 0, 0, 0}, {4}, {3}},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4662, {2, 0}, {16, 8, 0, 0}, {4}, {3}},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4663, {2, 0}, {16, 8, 0, 0}, {4}, {3}},
-+
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
-+
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
-+
-+      {0},
-+};
-+
-+#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
-+
-+/*=============================================================================
-+  PCI device table.
-+  This is used by modprobe to translate PCI IDs to drivers.
-+  ===========================================================================*/
-+
-+static struct pci_device_id me4000_pci_table[] __devinitdata = {
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4610, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+      {PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+
-+      {0}
-+};
-+
-+MODULE_DEVICE_TABLE(pci, me4000_pci_table);
-+
-+/*=============================================================================
-+  Global board and subdevice information structures
-+  ===========================================================================*/
-+
-+typedef struct me4000_info {
-+      struct list_head list;  // List of all detected boards
-+      int board_count;        // Index of the board after detection
-+
-+      unsigned long plx_regbase;      // PLX configuration space base address
-+      unsigned long me4000_regbase;   // Base address of the ME4000
-+      unsigned long timer_regbase;    // Base address of the timer circuit
-+      unsigned long program_regbase;  // Base address to set the program pin for the xilinx
-+
-+      unsigned long plx_regbase_size; // PLX register set space
-+      unsigned long me4000_regbase_size;      // ME4000 register set space
-+      unsigned long timer_regbase_size;       // Timer circuit register set space
-+      unsigned long program_regbase_size;     // Size of program base address of the ME4000
-+
-+      unsigned int serial_no; // Serial number of the board
-+      unsigned char hw_revision;      // Hardware revision of the board
-+      unsigned short vendor_id;       // Meilhaus vendor id (0x1402)
-+      unsigned short device_id;       // Device ID
-+
-+      int pci_bus_no;         // PCI bus number
-+      int pci_dev_no;         // PCI device number
-+      int pci_func_no;        // PCI function number
-+      struct pci_dev *pci_dev_p;      // General PCI information
-+
-+      me4000_board_t *board_p;        // Holds the board capabilities
-+
-+      unsigned int irq;       // IRQ assigned from the PCI BIOS
-+      unsigned int irq_count; // Count of external interrupts
-+
-+      spinlock_t preload_lock;        // Guards the analog output preload register
-+      spinlock_t ai_ctrl_lock;        // Guards the analog input control register
-+
-+      struct list_head ao_context_list;       // List with analog output specific context
-+      struct me4000_ai_context *ai_context;   // Analog input  specific context
-+      struct me4000_dio_context *dio_context; // Digital I/O specific context
-+      struct me4000_cnt_context *cnt_context; // Counter specific context
-+      struct me4000_ext_int_context *ext_int_context; // External interrupt specific context
-+} me4000_info_t;
-+
-+typedef struct me4000_ao_context {
-+      struct list_head list;  // linked list of me4000_ao_context_t
-+      int index;              // Index in the list
-+      int mode;               // Indicates mode (0 = single, 1 = wraparound, 2 = continous)
-+      int dac_in_use;         // Indicates if already opend
-+      spinlock_t use_lock;    // Guards in_use
-+      spinlock_t int_lock;    // Used when locking out interrupts
-+      me4000_circ_buf_t circ_buf;     // Circular buffer
-+      wait_queue_head_t wait_queue;   // Wait queue to sleep while blocking write
-+      me4000_info_t *board_info;
-+      unsigned int irq;       // The irq associated with this ADC
-+      int volatile pipe_flag; // Indicates broken pipe set from me4000_ao_isr()
-+      unsigned long ctrl_reg;
-+      unsigned long status_reg;
-+      unsigned long fifo_reg;
-+      unsigned long single_reg;
-+      unsigned long timer_reg;
-+      unsigned long irq_status_reg;
-+      unsigned long preload_reg;
-+      struct fasync_struct *fasync_p; // Queue for asynchronous notification
-+} me4000_ao_context_t;
-+
-+typedef struct me4000_ai_context {
-+      struct list_head list;  // linked list of me4000_ai_info_t
-+      int mode;               // Indicates mode
-+      int in_use;             // Indicates if already opend
-+      spinlock_t use_lock;    // Guards in_use
-+      spinlock_t int_lock;    // Used when locking out interrupts
-+      int number;             // Number of the DAC
-+      unsigned int irq;       // The irq associated with this ADC
-+      me4000_circ_buf_t circ_buf;     // Circular buffer
-+      wait_queue_head_t wait_queue;   // Wait queue to sleep while blocking read
-+      me4000_info_t *board_info;
-+
-+      struct fasync_struct *fasync_p; // Queue for asynchronous notification
-+
-+      unsigned long ctrl_reg;
-+      unsigned long status_reg;
-+      unsigned long channel_list_reg;
-+      unsigned long data_reg;
-+      unsigned long chan_timer_reg;
-+      unsigned long chan_pre_timer_reg;
-+      unsigned long scan_timer_low_reg;
-+      unsigned long scan_timer_high_reg;
-+      unsigned long scan_pre_timer_low_reg;
-+      unsigned long scan_pre_timer_high_reg;
-+      unsigned long start_reg;
-+      unsigned long irq_status_reg;
-+      unsigned long sample_counter_reg;
-+
-+      unsigned long chan_timer;
-+      unsigned long chan_pre_timer;
-+      unsigned long scan_timer_low;
-+      unsigned long scan_timer_high;
-+      unsigned long channel_list_count;
-+      unsigned long sample_counter;
-+      int sample_counter_reload;
-+} me4000_ai_context_t;
-+
-+typedef struct me4000_dio_context {
-+      struct list_head list;  // linked list of me4000_dio_context_t
-+      int in_use;             // Indicates if already opend
-+      spinlock_t use_lock;    // Guards in_use
-+      int number;
-+      int dio_count;
-+      me4000_info_t *board_info;
-+      unsigned long dir_reg;
-+      unsigned long ctrl_reg;
-+      unsigned long port_0_reg;
-+      unsigned long port_1_reg;
-+      unsigned long port_2_reg;
-+      unsigned long port_3_reg;
-+} me4000_dio_context_t;
-+
-+typedef struct me4000_cnt_context {
-+      struct list_head list;  // linked list of me4000_dio_context_t
-+      int in_use;             // Indicates if already opend
-+      spinlock_t use_lock;    // Guards in_use
-+      int number;
-+      int cnt_count;
-+      me4000_info_t *board_info;
-+      unsigned long ctrl_reg;
-+      unsigned long counter_0_reg;
-+      unsigned long counter_1_reg;
-+      unsigned long counter_2_reg;
-+} me4000_cnt_context_t;
-+
-+typedef struct me4000_ext_int_context {
-+      struct list_head list;  // linked list of me4000_dio_context_t
-+      int in_use;             // Indicates if already opend
-+      spinlock_t use_lock;    // Guards in_use
-+      int number;
-+      me4000_info_t *board_info;
-+      unsigned int irq;
-+      unsigned long int_count;
-+      struct fasync_struct *fasync_ptr;
-+      unsigned long ctrl_reg;
-+      unsigned long irq_status_reg;
-+} me4000_ext_int_context_t;
-+
-+#endif
-+
-+/*=============================================================================
-+  Application include section starts here
-+  ===========================================================================*/
-+
-+/*-----------------------------------------------------------------------------
-+  Defines for analog input
-+  ----------------------------------------------------------------------------*/
-+
-+/* General stuff */
-+#define ME4000_AI_FIFO_COUNT          2048
-+
-+#define ME4000_AI_MIN_TICKS           66
-+#define ME4000_AI_MAX_SCAN_TICKS      0xFFFFFFFFFFLL
-+
-+#define ME4000_AI_BUFFER_SIZE                 (32 * 1024)     // Size in bytes
-+
-+#define ME4000_AI_BUFFER_COUNT                ((ME4000_AI_BUFFER_SIZE) / 2)   // Size in values
-+
-+/* Channel list defines and masks */
-+#define ME4000_AI_CHANNEL_LIST_COUNT          1024
-+
-+#define ME4000_AI_LIST_INPUT_SINGLE_ENDED     0x000
-+#define ME4000_AI_LIST_INPUT_DIFFERENTIAL     0x020
-+
-+#define ME4000_AI_LIST_RANGE_BIPOLAR_10               0x000
-+#define ME4000_AI_LIST_RANGE_BIPOLAR_2_5      0x040
-+#define ME4000_AI_LIST_RANGE_UNIPOLAR_10      0x080
-+#define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5     0x0C0
-+
-+#define ME4000_AI_LIST_LAST_ENTRY             0x100
-+
-+/* External trigger defines */
-+#define ME4000_AI_TRIGGER_SOFTWARE            0x0     // Use only with API
-+#define ME4000_AI_TRIGGER_EXT_DIGITAL         0x1
-+#define ME4000_AI_TRIGGER_EXT_ANALOG          0x2
-+
-+#define ME4000_AI_TRIGGER_EXT_EDGE_RISING     0x0
-+#define ME4000_AI_TRIGGER_EXT_EDGE_FALLING    0x1
-+#define ME4000_AI_TRIGGER_EXT_EDGE_BOTH               0x2
-+
-+/* Sample and Hold */
-+#define ME4000_AI_SIMULTANEOUS_DISABLE                0x0
-+#define ME4000_AI_SIMULTANEOUS_ENABLE         0x1
-+
-+/* Defines for the Sample Counter */
-+#define ME4000_AI_SC_RELOAD                   0x0
-+#define ME4000_AI_SC_ONCE                     0x1
-+
-+/* Modes for analog input */
-+#define ME4000_AI_ACQ_MODE_SINGLE             0x00    // Catch one single value
-+#define ME4000_AI_ACQ_MODE_SOFTWARE           0x01    // Continous sampling with software start
-+#define ME4000_AI_ACQ_MODE_EXT                        0x02    // Continous sampling with external trigger start
-+#define ME4000_AI_ACQ_MODE_EXT_SINGLE_VALUE   0x03    // Sample one value by external trigger
-+#define ME4000_AI_ACQ_MODE_EXT_SINGLE_CHANLIST        0x04    // Sample one channel list by external trigger
-+
-+/* Staus of AI FSM */
-+#define ME4000_AI_STATUS_IDLE                 0x0
-+#define ME4000_AI_STATUS_BUSY                 0x1
-+
-+/* Voltages for calibration */
-+#define ME4000_AI_GAIN_1_UNI_OFFSET           10.0E-3
-+#define ME4000_AI_GAIN_1_UNI_FULLSCALE                9950.0E-3
-+#define ME4000_AI_GAIN_1_BI_OFFSET            0.0
-+#define ME4000_AI_GAIN_1_BI_FULLSCALE         9950.0E-3
-+#define ME4000_AI_GAIN_4_UNI_OFFSET           10.0E-3
-+#define ME4000_AI_GAIN_4_UNI_FULLSCALE                2450.0E-3
-+#define ME4000_AI_GAIN_4_BI_OFFSET            0.0
-+#define ME4000_AI_GAIN_4_BI_FULLSCALE         2450.0E-3
-+
-+/* Ideal digits for calibration */
-+#define ME4000_AI_GAIN_1_UNI_OFFSET_DIGITS    (-32702)
-+#define ME4000_AI_GAIN_1_UNI_FULLSCALE_DIGITS 32440
-+#define ME4000_AI_GAIN_1_BI_OFFSET_DIGITS     0
-+#define ME4000_AI_GAIN_1_BI_FULLSCALE_DIGITS  32604
-+#define ME4000_AI_GAIN_4_UNI_OFFSET_DIGITS    (-32505)
-+#define ME4000_AI_GAIN_4_UNI_FULLSCALE_DIGITS 31457
-+#define ME4000_AI_GAIN_4_BI_OFFSET_DIGITS     0
-+#define ME4000_AI_GAIN_4_BI_FULLSCALE_DIGITS  32113
-+
-+/*-----------------------------------------------------------------------------
-+  Defines for analog output
-+  ----------------------------------------------------------------------------*/
-+
-+/* General stuff */
-+#define ME4000_AO_FIFO_COUNT                  (4 * 1024)
-+
-+#define ME4000_AO_MIN_TICKS                   66
-+
-+#define ME4000_AO_BUFFER_SIZE                         (32 * 1024)     // Size in bytes
-+
-+#define ME4000_AO_BUFFER_COUNT                        ((ME4000_AO_BUFFER_SIZE) / 2)   // Size in values
-+
-+/* Conversion modes for analog output */
-+#define ME4000_AO_CONV_MODE_SINGLE            0x0
-+#define ME4000_AO_CONV_MODE_WRAPAROUND                0x1
-+#define ME4000_AO_CONV_MODE_CONTINUOUS                0x2
-+
-+/* Trigger setup */
-+#define ME4000_AO_TRIGGER_EXT_EDGE_RISING     0x0
-+#define ME4000_AO_TRIGGER_EXT_EDGE_FALLING    0x1
-+#define ME4000_AO_TRIGGER_EXT_EDGE_BOTH               0x2
-+
-+/* Status of AO FSM */
-+#define ME4000_AO_STATUS_IDLE                 0x0
-+#define ME4000_AO_STATUS_BUSY                 0x1
-+
-+/*-----------------------------------------------------------------------------
-+  Defines for eeprom
-+  ----------------------------------------------------------------------------*/
-+
-+#define ME4000_EEPROM_CMD_READ                        0x180
-+#define ME4000_EEPROM_CMD_WRITE_ENABLE                0x130
-+#define ME4000_EEPROM_CMD_WRITE_DISABLE               0x100
-+#define ME4000_EEPROM_CMD_WRITE                       0x1400000
-+
-+#define ME4000_EEPROM_CMD_LENGTH_READ         9
-+#define ME4000_EEPROM_CMD_LENGTH_WRITE_ENABLE 9
-+#define ME4000_EEPROM_CMD_LENGTH_WRITE_DISABLE        9
-+#define ME4000_EEPROM_CMD_LENGTH_WRITE                25
-+
-+#define ME4000_EEPROM_ADR_DATE_HIGH           0x32
-+#define ME4000_EEPROM_ADR_DATE_LOW            0x33
-+
-+#define ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET   0x34
-+#define ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE        0x35
-+#define ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET    0x36
-+#define ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE 0x37
-+#define ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET  0x38
-+#define ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE       0x39
-+
-+#define ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET   0x3A
-+#define ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE        0x3B
-+#define ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET    0x3C
-+#define ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE 0x3D
-+#define ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET  0x3E
-+#define ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE       0x3F
-+
-+#define ME4000_EEPROM_ADR_LENGTH              6
-+#define ME4000_EEPROM_DATA_LENGTH             16
-+
-+/*-----------------------------------------------------------------------------
-+  Defines for digital I/O
-+  ----------------------------------------------------------------------------*/
-+
-+#define ME4000_DIO_PORT_A             0x0
-+#define ME4000_DIO_PORT_B             0x1
-+#define ME4000_DIO_PORT_C             0x2
-+#define ME4000_DIO_PORT_D             0x3
-+
-+#define ME4000_DIO_PORT_INPUT         0x0
-+#define ME4000_DIO_PORT_OUTPUT                0x1
-+#define ME4000_DIO_FIFO_LOW           0x2
-+#define ME4000_DIO_FIFO_HIGH          0x3
-+
-+#define ME4000_DIO_FUNCTION_PATTERN   0x0
-+#define ME4000_DIO_FUNCTION_DEMUX     0x1
-+#define ME4000_DIO_FUNCTION_MUX               0x2
-+
-+/*-----------------------------------------------------------------------------
-+  Defines for counters
-+  ----------------------------------------------------------------------------*/
-+
-+#define ME4000_CNT_COUNTER_0  0
-+#define ME4000_CNT_COUNTER_1  1
-+#define ME4000_CNT_COUNTER_2  2
-+
-+#define ME4000_CNT_MODE_0     0       // Change state if zero crossing
-+#define ME4000_CNT_MODE_1     1       // Retriggerable One-Shot
-+#define ME4000_CNT_MODE_2     2       // Asymmetrical divider
-+#define ME4000_CNT_MODE_3     3       // Symmetrical divider
-+#define ME4000_CNT_MODE_4     4       // Counter start by software trigger
-+#define ME4000_CNT_MODE_5     5       // Counter start by hardware trigger
-+
-+/*-----------------------------------------------------------------------------
-+  General type definitions
-+  ----------------------------------------------------------------------------*/
-+
-+typedef struct me4000_user_info {
-+      int board_count;        // Index of the board after detection
-+      unsigned long plx_regbase;      // PLX configuration space base address
-+      unsigned long me4000_regbase;   // Base address of the ME4000
-+      unsigned long plx_regbase_size; // PLX register set space
-+      unsigned long me4000_regbase_size;      // ME4000 register set space
-+      unsigned long serial_no;        // Serial number of the board
-+      unsigned char hw_revision;      // Hardware revision of the board
-+      unsigned short vendor_id;       // Meilhaus vendor id (0x1402)
-+      unsigned short device_id;       // Device ID
-+      int pci_bus_no;         // PCI bus number
-+      int pci_dev_no;         // PCI device number
-+      int pci_func_no;        // PCI function number
-+      char irq;               // IRQ assigned from the PCI BIOS
-+      int irq_count;          // Count of external interrupts
-+
-+      int driver_version;     // Version of the driver release
-+
-+      int ao_count;           // Count of analog output channels
-+      int ao_fifo_count;      // Count fo analog output fifos
-+
-+      int ai_count;           // Count of analog input channels
-+      int ai_sh_count;        // Count of sample and hold devices
-+      int ai_ex_trig_analog;  // Flag to indicate if analogous external trigger is available
-+
-+      int dio_count;          // Count of digital I/O ports
-+
-+      int cnt_count;          // Count of counters
-+} me4000_user_info_t;
-+
-+/*-----------------------------------------------------------------------------
-+  Type definitions for analog output
-+  ----------------------------------------------------------------------------*/
-+
-+typedef struct me4000_ao_channel_list {
-+      unsigned long count;
-+      unsigned long *list;
-+} me4000_ao_channel_list_t;
-+
-+/*-----------------------------------------------------------------------------
-+  Type definitions for analog input
-+  ----------------------------------------------------------------------------*/
-+
-+typedef struct me4000_ai_channel_list {
-+      unsigned long count;
-+      unsigned long *list;
-+} me4000_ai_channel_list_t;
-+
-+typedef struct me4000_ai_timer {
-+      unsigned long pre_chan;
-+      unsigned long chan;
-+      unsigned long scan_low;
-+      unsigned long scan_high;
-+} me4000_ai_timer_t;
-+
-+typedef struct me4000_ai_config {
-+      me4000_ai_timer_t timer;
-+      me4000_ai_channel_list_t channel_list;
-+      int sh;
-+} me4000_ai_config_t;
-+
-+typedef struct me4000_ai_single {
-+      int channel;
-+      int range;
-+      int mode;
-+      short value;
-+      unsigned long timeout;
-+} me4000_ai_single_t;
-+
-+typedef struct me4000_ai_trigger {
-+      int mode;
-+      int edge;
-+} me4000_ai_trigger_t;
-+
-+typedef struct me4000_ai_sc {
-+      unsigned long value;
-+      int reload;
-+} me4000_ai_sc_t;
-+
-+/*-----------------------------------------------------------------------------
-+  Type definitions for eeprom
-+  ----------------------------------------------------------------------------*/
-+
-+typedef struct me4000_eeprom {
-+      unsigned long date;
-+      short uni_10_offset;
-+      short uni_10_fullscale;
-+      short uni_2_5_offset;
-+      short uni_2_5_fullscale;
-+      short bi_10_offset;
-+      short bi_10_fullscale;
-+      short bi_2_5_offset;
-+      short bi_2_5_fullscale;
-+      short diff_10_offset;
-+      short diff_10_fullscale;
-+      short diff_2_5_offset;
-+      short diff_2_5_fullscale;
-+} me4000_eeprom_t;
-+
-+/*-----------------------------------------------------------------------------
-+  Type definitions for digital I/O
-+  ----------------------------------------------------------------------------*/
-+
-+typedef struct me4000_dio_config {
-+      int port;
-+      int mode;
-+      int function;
-+} me4000_dio_config_t;
-+
-+typedef struct me4000_dio_byte {
-+      int port;
-+      unsigned char byte;
-+} me4000_dio_byte_t;
-+
-+/*-----------------------------------------------------------------------------
-+  Type definitions for counters
-+  ----------------------------------------------------------------------------*/
-+
-+typedef struct me4000_cnt {
-+      int counter;
-+      unsigned short value;
-+} me4000_cnt_t;
-+
-+typedef struct me4000_cnt_config {
-+      int counter;
-+      int mode;
-+} me4000_cnt_config_t;
-+
-+/*-----------------------------------------------------------------------------
-+  Type definitions for external interrupt
-+  ----------------------------------------------------------------------------*/
-+
-+typedef struct {
-+      int int1_count;
-+      int int2_count;
-+} me4000_int_type;
-+
-+/*-----------------------------------------------------------------------------
-+  The ioctls of the board
-+  ----------------------------------------------------------------------------*/
-+
-+#define ME4000_IOCTL_MAXNR 50
-+#define ME4000_MAGIC 'y'
-+#define ME4000_GET_USER_INFO          _IOR (ME4000_MAGIC, 0, me4000_user_info_t)
-+
-+#define ME4000_AO_START               _IOW (ME4000_MAGIC, 1, unsigned long)
-+#define ME4000_AO_STOP                _IO  (ME4000_MAGIC, 2)
-+#define ME4000_AO_IMMEDIATE_STOP      _IO  (ME4000_MAGIC, 3)
-+#define ME4000_AO_RESET               _IO  (ME4000_MAGIC, 4)
-+#define ME4000_AO_PRELOAD             _IO  (ME4000_MAGIC, 5)
-+#define ME4000_AO_PRELOAD_UPDATE      _IO  (ME4000_MAGIC, 6)
-+#define ME4000_AO_EX_TRIG_ENABLE      _IO  (ME4000_MAGIC, 7)
-+#define ME4000_AO_EX_TRIG_DISABLE     _IO  (ME4000_MAGIC, 8)
-+#define ME4000_AO_EX_TRIG_SETUP       _IOW (ME4000_MAGIC, 9, int)
-+#define ME4000_AO_TIMER_SET_DIVISOR   _IOW (ME4000_MAGIC, 10, unsigned long)
-+#define ME4000_AO_ENABLE_DO           _IO  (ME4000_MAGIC, 11)
-+#define ME4000_AO_DISABLE_DO          _IO  (ME4000_MAGIC, 12)
-+#define ME4000_AO_FSM_STATE           _IOR (ME4000_MAGIC, 13, int)
-+
-+#define ME4000_AI_SINGLE              _IOR (ME4000_MAGIC, 14, me4000_ai_single_t)
-+#define ME4000_AI_START               _IOW (ME4000_MAGIC, 15, unsigned long)
-+#define ME4000_AI_STOP                _IO  (ME4000_MAGIC, 16)
-+#define ME4000_AI_IMMEDIATE_STOP      _IO  (ME4000_MAGIC, 17)
-+#define ME4000_AI_EX_TRIG_ENABLE      _IO  (ME4000_MAGIC, 18)
-+#define ME4000_AI_EX_TRIG_DISABLE     _IO  (ME4000_MAGIC, 19)
-+#define ME4000_AI_EX_TRIG_SETUP       _IOW (ME4000_MAGIC, 20, me4000_ai_trigger_t)
-+#define ME4000_AI_CONFIG              _IOW (ME4000_MAGIC, 21, me4000_ai_config_t)
-+#define ME4000_AI_SC_SETUP            _IOW (ME4000_MAGIC, 22, me4000_ai_sc_t)
-+#define ME4000_AI_FSM_STATE           _IOR (ME4000_MAGIC, 23, int)
-+
-+#define ME4000_DIO_CONFIG             _IOW (ME4000_MAGIC, 24, me4000_dio_config_t)
-+#define ME4000_DIO_GET_BYTE           _IOR (ME4000_MAGIC, 25, me4000_dio_byte_t)
-+#define ME4000_DIO_SET_BYTE           _IOW (ME4000_MAGIC, 26, me4000_dio_byte_t)
-+#define ME4000_DIO_RESET              _IO  (ME4000_MAGIC, 27)
-+
-+#define ME4000_CNT_READ               _IOR (ME4000_MAGIC, 28, me4000_cnt_t)
-+#define ME4000_CNT_WRITE              _IOW (ME4000_MAGIC, 29, me4000_cnt_t)
-+#define ME4000_CNT_CONFIG             _IOW (ME4000_MAGIC, 30, me4000_cnt_config_t)
-+#define ME4000_CNT_RESET              _IO  (ME4000_MAGIC, 31)
-+
-+#define ME4000_EXT_INT_DISABLE        _IO  (ME4000_MAGIC, 32)
-+#define ME4000_EXT_INT_ENABLE         _IO  (ME4000_MAGIC, 33)
-+#define ME4000_EXT_INT_COUNT          _IOR (ME4000_MAGIC, 34, int)
-+
-+#define ME4000_AI_OFFSET_ENABLE       _IO  (ME4000_MAGIC, 35)
-+#define ME4000_AI_OFFSET_DISABLE      _IO  (ME4000_MAGIC, 36)
-+#define ME4000_AI_FULLSCALE_ENABLE    _IO  (ME4000_MAGIC, 37)
-+#define ME4000_AI_FULLSCALE_DISABLE   _IO  (ME4000_MAGIC, 38)
-+
-+#define ME4000_AI_EEPROM_READ         _IOR (ME4000_MAGIC, 39, me4000_eeprom_t)
-+#define ME4000_AI_EEPROM_WRITE        _IOW (ME4000_MAGIC, 40, me4000_eeprom_t)
-+
-+#define ME4000_AO_SIMULTANEOUS_EX_TRIG _IO  (ME4000_MAGIC, 41)
-+#define ME4000_AO_SIMULTANEOUS_SW      _IO  (ME4000_MAGIC, 42)
-+#define ME4000_AO_SIMULTANEOUS_DISABLE _IO  (ME4000_MAGIC, 43)
-+#define ME4000_AO_SIMULTANEOUS_UPDATE  _IOW (ME4000_MAGIC, 44, me4000_ao_channel_list_t)
-+
-+#define ME4000_AO_SYNCHRONOUS_EX_TRIG  _IO  (ME4000_MAGIC, 45)
-+#define ME4000_AO_SYNCHRONOUS_SW       _IO  (ME4000_MAGIC, 46)
-+#define ME4000_AO_SYNCHRONOUS_DISABLE  _IO  (ME4000_MAGIC, 47)
-+
-+#define ME4000_AO_EX_TRIG_TIMEOUT      _IOW (ME4000_MAGIC, 48, unsigned long)
-+#define ME4000_AO_GET_FREE_BUFFER      _IOR (ME4000_MAGIC, 49, unsigned long)
-+
-+#define ME4000_AI_GET_COUNT_BUFFER     _IOR (ME4000_MAGIC, 50, unsigned long)
-+
-+#endif
--- 
-1.6.0.2
-