diff -u -r -N -xCVS u2f.cern/.cvsignore u2f/.cvsignore
--- u2f.cern/.cvsignore	1970-01-01 01:00:00.000000000 +0100
+++ u2f/.cvsignore	2006-01-27 09:54:54.000000000 +0100
@@ -0,0 +1,6 @@
+Makefile.in
+_build
+aclocal.m4
+*.tar.gz
+autom4te.cache
+configure
diff -u -r -N -xCVS u2f.cern/Makefile u2f/Makefile
--- u2f.cern/Makefile	2005-03-20 08:45:12.000000000 +0100
+++ u2f/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,13 +0,0 @@
-
-all:
-	cd tools && make all
-	cd altro && make all
-	cd u2f && make all
-	cd goofie && make all
-
-clean: 
-	cd tools && make clean
-	cd altro && make clean
-	cd u2f && make clean
-	cd goofie && make clean
-
diff -u -r -N -xCVS u2f.cern/Makefile.am u2f/Makefile.am
--- u2f.cern/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ u2f/Makefile.am	2006-01-27 09:52:55.000000000 +0100
@@ -0,0 +1,61 @@
+#
+#
+#
+AUTOMAKE_OPTIONS	= foreign
+ACLOCAL_AMFLAGS		= -I .
+CLEANFILES		= stamp-driver
+SUBDIRS			= . tools altro u2f goofie scripts
+EXTRA_DIST		= driver/Makefile.in 		\
+			  driver/altro_driver_26.c	\
+			  driver/altro_driver_24.c	\
+			  driver/unused_26.c		\
+			  driver/unused_24.c		\
+			  driver/load.sh		\
+			  autogen.sh
+HOSTCC			= $(CC)
+
+clean-local:
+	rm -rf 	driver/altro_driver*.o		\
+		driver/altro_driver*.ko		\
+		driver/altro_driver*.mod	\
+		driver/altro_driver*.mod.o	\
+		driver/altro_driver*.mod.c	\
+		driver/.altro_driver*		\
+		driver/*~ 			\
+		driver/.tmp_versions		\
+		driver/altro_driver.c		\
+		driver/altro_common.h
+
+#	$(MAKE) $(AM_MAKEFLAGS) -C driver -f \
+#		$(top_srcdir)/driver/Makefile.in clean
+
+install-exec-local:
+	$(MAKE) $(AM_MAKEFLAGS) -C driver install KVERS=$(KVERS)
+
+all-local: stamp-driver
+
+stamp-driver:$(PWD)/driver/altro_driver.c $(PWD)/driver/altro_common.h
+# For 2.4 like kernel module builds 
+if OLD_MODULE_BUILD
+	$(MAKE) -C $(KSRC) SUBDIRS=$(PWD)/driver \
+		BUILD_DIR=$(PWD)/driver modules
+# For 2.6 kernel module builds 
+else
+	$(MAKE) -C $(KSRC) V=1 CC=$(HOSTCC) HOSTCC=$(HOSTCC) \
+		SUBDIRS=$(PWD)/driver MODVERDIR=$(PWD)/driver modules 
+endif
+	touch stamp-driver
+
+if OLD_MODULE_BUILD
+$(PWD)/driver/altro_driver.c:$(top_srcdir)/driver/altro_driver_24.c
+	cp $< $@ 
+else 
+$(PWD)/driver/altro_driver.c:$(top_srcdir)/driver/altro_driver_26.c
+	cp $< $@ 
+endif
+$(PWD)/driver/altro_common.h:$(top_srcdir)/altro/altro_common.h
+	cp $< $@ 
+
+#
+# EOF
+#
diff -u -r -N -xCVS u2f.cern/acinclude.m4 u2f/acinclude.m4
--- u2f.cern/acinclude.m4	1970-01-01 01:00:00.000000000 +0100
+++ u2f/acinclude.m4	2006-01-26 04:03:42.000000000 +0100
@@ -0,0 +1,66 @@
+dnl
+dnl $Id: acinclude.m4,v 1.1.1.1 2006/01/26 03:03:42 cholm Exp $
+dnl
+dnl  Copyright (C) 2002 Christian Holm Christensen <cholm@nbi.dk>
+dnl
+dnl  This library is free software; you can redistribute it and/or
+dnl  modify it under the terms of the GNU Lesser General Public License
+dnl  as published by the Free Software Foundation; either version 2.1
+dnl  of the License, or (at your option) any later version.
+dnl
+dnl  This library is distributed in the hope that it will be useful,
+dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl  Lesser General Public License for more details.
+dnl
+dnl  You should have received a copy of the GNU Lesser General Public
+dnl  License along with this library; if not, write to the Free
+dnl  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+dnl  02111-1307 USA
+dnl
+dnl ------------------------------------------------------------------
+AC_DEFUN([AC_DEBUG],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_MSG_CHECKING(whether to make debug objects)
+  AC_ARG_ENABLE(debug,
+    [AC_HELP_STRING([--enable-debug],[Enable debugging symbols in objects])])
+  if test "x$enable_debug" = "xno" ; then
+    CFLAGS=`echo $CFLAGS | sed 's,-g,,'`
+  else
+    case $CFLAGS in
+    *-g*) ;;
+    *)    CFLAGS="$CFLAGS -g" ;;
+    esac
+  fi
+  AC_MSG_RESULT($enable_debug 'CFLAGS=$CFLAGS')
+])
+
+dnl ------------------------------------------------------------------
+AC_DEFUN([AC_OPTIMIZATION],
+[
+  AC_REQUIRE([AC_PROG_CC])
+
+  AC_ARG_ENABLE(optimization,
+    [AC_HELP_STRING([--enable-optimization],[Enable optimization of objects])])
+
+  AC_MSG_CHECKING(for optimiztion level)
+
+  changequote(<<, >>)dnl
+  if test "x$enable_optimization" = "xno" ; then
+    CFLAGS=`echo   $CFLAGS   | sed 's,-O\([0-9][0-9]*\|\),,'`
+  elif test "x$enable_optimization" = "xyes" ; then
+    case $CFLAGS in
+    *-O*) ;;
+    *)    CFLAGS="$CXXFLAGS -O2" ;;
+    esac
+  else
+    CFLAGS=`echo $CFLAGS | sed "s,-O\([0-9][0-9]*\|\),-O$enable_optimization,"`
+  fi
+  changequote([, ])dnl
+  AC_MSG_RESULT($enable_optimization 'CFLAGS=$CFLAGS')
+])
+
+#
+# EOF
+#
diff -u -r -N -xCVS u2f.cern/altro/.cvsignore u2f/altro/.cvsignore
--- u2f.cern/altro/.cvsignore	1970-01-01 01:00:00.000000000 +0100
+++ u2f/altro/.cvsignore	2006-01-26 04:03:43.000000000 +0100
@@ -0,0 +1,8 @@
+.deps
+.libs
+Makefile
+Makefile.in
+altro_lib.lo
+altroscope
+libaltro.la
+semantic.cache
diff -u -r -N -xCVS u2f.cern/altro/Makefile u2f/altro/Makefile
--- u2f.cern/altro/Makefile	2005-03-20 08:45:12.000000000 +0100
+++ u2f/altro/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,25 +0,0 @@
-CFLAGS = -Wall -D__KERNEL__ -DALTRO_KERNEL_DEBUG -DMODULE -I/usr/src/linux-2.4/include -DMODVERSIONS -include /usr/src/linux-2.4/include/linux/modversions.h -O2 -I.. -c 
-
-CFLAGS2 = -DALTRODEBUG -I.. -c -g -O3 -pedantic -funsigned-char -Wall -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align
-
-all: altro_driver.o altroscope libaltro.so
-
-altro_driver.o: altro_driver_24.c altro.h altro_common.h
-	gcc $(CFLAGS) -o altro_driver.o altro_driver_24.c
-
-libaltro.so: altro_lib.o 
-	gcc -shared -L. -o libaltro.so altro_lib.o
-
-altro_lib.o: altro_lib.c altro_common.h 
-	gcc $(CFLAGS2) altro_lib.c -o altro_lib.o
-
-altroscope.o: altroscope.c
-	gcc $(CFLAGS2) altroscope.c -o altroscope.o
-
-altroscope: altro_driver.o altroscope.o libaltro.so
-	gcc  -L. -L../tools altroscope.o -ltools -laltro -o altroscope 
-	
-clean:
-	rm -f *.so *.o *~ core altroscope
-
-
diff -u -r -N -xCVS u2f.cern/altro/Makefile.am u2f/altro/Makefile.am
--- u2f.cern/altro/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ u2f/altro/Makefile.am	2006-01-26 04:03:42.000000000 +0100
@@ -0,0 +1,22 @@
+#
+#
+#
+AM_CPPFLAGS		= -I$(top_srcdir) -DALTRODEBUG  -DALTRO_BUILD
+AM_CFLAGS		= -pedantic -funsigned-char -Wall \
+			  -Wpointer-arith \
+			  -Wcast-qual -Wcast-align
+pkglib_LTLIBRARIES	= libaltro.la
+libaltro_la_SOURCES	= altro_lib.c
+libaltro_la_LIBADD	= $(top_builddir)/tools/libtools.la
+
+pkginclude_HEADERS	= altro.h altro_common.h
+bin_PROGRAMS		= altroscope
+
+altroscope_SOURCES	= altroscope.c
+altroscope_LDADD	= libaltro.la
+
+#
+# EOF
+#
+
+
diff -u -r -N -xCVS u2f.cern/altro/altro u2f/altro/altro
--- u2f.cern/altro/altro	2005-03-20 08:45:12.000000000 +0100
+++ u2f/altro/altro	1970-01-01 01:00:00.000000000 +0100
@@ -1,60 +0,0 @@
-#!/bin/sh
-#
-# altro:       Starts the ALTRO driver
-#
-# Version:      @(#) /etc/rc.d/init.d/altro 1.0
-#
-# chkconfig: 5 95 5
-# description: Starts and stops the ALTRO driver at boot time and shutdown.
-#
-# processname: altro
-# hide: true
-
-# Source function library.
-. /etc/rc.d/init.d/functions
-# See how we were called.
-case "$1" in
-  start)
-        echo    "Starting ALTRO driver "
-        # load the module
-        /sbin/insmod -f altro_driver.o
-        # remove old device node
-        rm -f /dev/usb/altro
-        # get major number
-        major=`awk "\\$2==\"usb\" {print \\$1}" /proc/devices`
-        echo major number is $major
-        # make device node
-        mknod /dev/usb/altro c $major 192
-        #give permissions
-        chmod 666 /dev/usb/altro
-        echo
-        ;;
-  stop)
-        echo    "Shutting down ALTRO driver "
-        /sbin/rmmod altro_driver
-        echo
-        ;;
-  status)
-        cat /proc/altro
-        ;;
-  restart)
-        echo    "Shutting down altro driver "
-        /sbin/rmmod altro_driver
-        echo    "Starting altro driver "
-        /sbin/insmod -f altro_driver.o
-        echo
-        ;;
-  restart_debug)
-        echo    "Shutting down altro driver "
-        /sbin/rmmod altro_driver
-        echo    "Starting altro driver "
-        /sbin/insmod -f altro_driver.o debug=1
-        echo
-        ;;
-  *)
-        echo "*** Usage: altro {start|stop|status|restart|restart_debug}"
-        exit 1
-esac
-
-exit 0
-
diff -u -r -N -xCVS u2f.cern/altro/altro.h u2f/altro/altro.h
--- u2f.cern/altro/altro.h	2005-03-20 08:45:12.000000000 +0100
+++ u2f/altro/altro.h	2006-01-26 04:03:42.000000000 +0100
@@ -10,7 +10,7 @@
 #define _ALTRO_H
 
 #include <stdio.h>
-#include "altro_common.h"
+#include <altro/altro_common.h>
 
 #define ALTROISOPEN {if(!altro_is_open) return(ALTRO_NOTOPEN);}
 #define DEFAULT_NODE "/dev/usb/altro"
diff -u -r -N -xCVS u2f.cern/altro/altro_common.h u2f/altro/altro_common.h
--- u2f.cern/altro/altro_common.h	2005-11-21 09:57:20.000000000 +0100
+++ u2f/altro/altro_common.h	2006-01-26 04:03:42.000000000 +0100
@@ -8,8 +8,11 @@
 
 #ifndef _ALTRO_COMMON_H
 #define _ALTRO_COMMON_H
-
+#ifdef ALTRO_BUILD
 #include <tools/rcc_error.h>
+#else
+#include <altro/rcc_error.h>
+#endif
 
 #ifndef __KERNEL__
 # ifndef _RCC_ERROR_H_
diff -u -r -N -xCVS u2f.cern/altro/altro_driver_24.c u2f/altro/altro_driver_24.c
--- u2f.cern/altro/altro_driver_24.c	2005-11-21 09:58:45.000000000 +0100
+++ u2f/altro/altro_driver_24.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,636 +0,0 @@
-/********************************************************/
-/*  This is the driver for the ALICE ALTRO USB core	*/
-/*							*/
-/*  Markus Joos, CERN-PH-ESS 15.3.2004			*/		
-/*							*/
-/*** C 2004 - The software with that certain something **/
-
-/****************************************************************************************/
-/* This dirver works for kernels from 2.4 onwards					*/
-/*											*/
-/* Currently only one ALTRO card is supported. Extending the driver for multiple cards	*/
-/* would require to introduce a "minor" array as done in the usb-skeleton driver	*/
-/****************************************************************************************/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/uaccess.h>
-#include "altro_common.h"
-
-MODULE_PARM (debug, "i");
-MODULE_PARM_DESC(debug, "1 = enable debugging   0 = disable debugging");
-MODULE_PARM (timeout, "i");
-MODULE_PARM_DESC(timeout, "timeout for usb_bulk_msg in units of jiffies");
-MODULE_PARM (ddump, "i");
-MODULE_PARM_DESC(ddump, "1 = enable data dumping   0 = disable data dumping");
-MODULE_DESCRIPTION("USB driver for the ALICE ALTRO USB core");
-MODULE_AUTHOR("Markus Joos, CERN/EP");
-MODULE_LICENSE("Private: Contact markus.joos@cern.ch");
-
-
-#ifndef USB_ALTRO_MINOR_BASE
-# define USB_ALTRO_MINOR_BASE 192
-#endif
-#ifdef ALTRO_KERNEL_DEBUG
-# define kdebug(x) {if (debug) printk x;}
-#else
-# define kdebug(x)
-#endif
-
-static int altro_open (struct inode *inode, struct file *file);
-static int altro_release(struct inode *inode, struct file *file);
-static int proc_write_altro(struct file *file, const char *buffer, unsigned long count, void *data);
-static int proc_read_altro(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int altro_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-static void altro_disconnect(struct usb_device *udev, void *clientdata);
-static void *altro_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id);
-int altro_init(void);
-void altro_exit(void);
-
-/* Globals */ 
-static int cardtype, debug = 1, timeout = HZ * 10, ddump = 0;
-static struct proc_dir_entry *altro_file;
-struct altro_proc_data_t altro_proc_data;
-struct altro_device *altrop = NULL;
-int urbdone;
-
-/* Externals */
-extern devfs_handle_t usb_devfs_handle;
-
-/*We need a local data structure, as it must be allocated for each*/
-/*new device plugged in the USB bus*/ 
-struct altro_device 
-{
-  char data [10];
-  char *name;                          /* the name of the device */
-  struct urb urb;                      /* USB Request block, to get USB data*/
-  int maxp;                            /* packet len */
-  char output[80];                     /* used for printk at irq time */
-  unsigned char minor;                 /* the starting minor number for this device */
-  devfs_handle_t devfs;                /* devfs device node */
-  struct usb_device *udev;             /* save off the usb device pointer */
-  struct semaphore sem;                /* locks this structure */
-  unsigned char *bulk_in_buffer;       /* the buffer to receive data */
-  int bulk_in_size;                    /* the size of the receive buffer */
-  __u8 bulk_in_endpointAddr;           /* the address of the bulk in endpoint */
-  unsigned char *bulk_out_buffer;      /* the buffer to send data */
-  int bulk_out_size;                   /* the size of the send buffer */
-  struct urb *write_urb;               /* the urb used to send data */
-  __u8 bulk_out_endpointAddr;          /* the address of the bulk out endpoint */
-};
-
-/* Data in /proc file system */
-struct altro_proc_data_t
-{
-  char name[10];
-  char value[100];
-};
-
-/* The id_table, lists all devices that can be handled by this driver. */
-/* The three numbers are class, subclass, protocol. <linux/usb.h> has */
-/* more details about interface matches and vendor/device matches. */
-/* Here we use a fake usb_device_id structure defined in ./usb-sysdep.h */
-
-/*The parameters for the ALTRO are*/
-/*Class    = */
-/*Subclass = */
-/*Protocol = */
-
-static struct usb_device_id altro_id_table [] = 
-{
-  { 
-    USB_DEVICE(0x1556, 0x0350),
-    driver_info: (unsigned long)"altro_by_vendor (invalid device id)"
-  },
-  {
-    USB_DEVICE(0x1556, 0x15e),
-    driver_info: (unsigned long)"ALICE U2F"
-  },
-  { 
-    USB_DEVICE(0x1556, 0x15f),
-    driver_info: (unsigned long)"ALICE GOOFIE"
-  },
-  {
-    USB_DEVICE(0x1556, 0x163),
-    driver_info: (unsigned long)"ALICE MPT"
-  },
-  {
-    0, /* no more matches */
-  }
-};
-
-MODULE_DEVICE_TABLE (usb, altro_id_table);
-
-/* file operations supported */
-static struct file_operations altro_fops = 
-{
-  owner:       THIS_MODULE,
-  ioctl:       altro_ioctl,
-  open:        altro_open,
-  release:     altro_release,
-};
-
-/* The callbacks are registered within the USB subsystem using the */
-/* usb_driver data structure */
-static struct usb_driver altro_usb_driver = 
-{
-  owner:       THIS_MODULE,
-  name:        "altro",
-  probe:       altro_probe,
-  disconnect:  altro_disconnect,
-  fops:        &altro_fops,
-  minor:       USB_ALTRO_MINOR_BASE,
-  id_table:    altro_id_table,
-};
-
-
-/************************************************************/
-static int altro_open (struct inode *inode, struct file *file)
-/************************************************************/
-{
-  int retval = 0;
-  
-  kdebug(("altro_drv(altro_open): function called\n"));
-  if (altrop == NULL) 
-  {
-    kdebug(("altro_drv(altro_open): Sorry. So far no ALTRO has been connected\n"));
-    return -ENODEV;
-  }
-  
-  kdebug(("altro_drv(altro_open): minor number = %d\n", MINOR(inode->i_rdev)));
-  
-  /* save our object in the file's private structure */
-  /*MJ: assigning altrop to private_data does not make sense. We use it nowhere. Instead*/
-  /*MJ: we should define a proper "private_stuff" structure (a la cmem_rcc)*/
-  file->private_data = altrop;
-  
-  kdebug(("altro_drv(altro_open): function done\n"));
-  return retval;
-}
-
-
-/**************************************************************/
-static int altro_release(struct inode *inode, struct file *file)
-/**************************************************************/
-{
-  kdebug(("altro_drv(altro_release): function called\n"));
-
-  return(0);
-}
-
-
-/* This callback is invoked when a USB device is detached from the bus*/
-/*********************************************************************/
-static void altro_disconnect(struct usb_device *udev, void *clientdata)
-/*********************************************************************/
-{
-  /* the clientdata is the altro_device we passed originally */
-  struct altro_device *altro = clientdata;
-
-  kdebug(("altro_drv(altro_disconnect): function called\n"));
-
-  /* remove the URB, remove the input device, free memory */
-  usb_unlink_urb(&altro->urb);
-
-  /* remove our devfs node */
-  devfs_unregister(altro->devfs);
-
-  kfree(altro);
-  kdebug(("altro_drv(altro_disconnect): USB %s disconnected\n", altro->name));
-
-  return;
-}
-
-
-/*This callback is invoked when a USB device is attached to the bus */ 
-/***************************************************************************************************/
-static void *altro_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-/***************************************************************************************************/
-{
-  /* The probe procedure is pretty standard. Device matching has already */
-  /* been performed based on the id_table structure */
-
-  struct usb_interface *iface;
-  struct usb_interface_descriptor *interface;
-  struct usb_endpoint_descriptor *endpoint;
-  struct altro_device *altro;
-  int i, buffer_size, inok, outok;
-
-  kdebug(("altro_drv(altro_probe): probe called for %s device\n", (char *)id->driver_info));
-  kdebug(("altro_drv(altro_probe): ifnum = %d\n", ifnum));
-
-  /* allocate and zero a new data structure for the new device */
-  altro = kmalloc(sizeof(struct altro_device), GFP_KERNEL);
-  if (!altro) 
-  { 
-    kdebug(("altro_drv(altro_probe): ERROR failed to kmalloc altro_device\n"));
-    return NULL; /* failure */
-  }
-  
-  memset(altro, 0, sizeof(*altro));
-  altro->name = (char *)id->driver_info;
-  init_MUTEX(&altro->sem);
-
-  kdebug(("altro_drv(altro_probe): udev->descriptor.idVendor = 0x%08x\n", udev->descriptor.idVendor));
-  kdebug(("altro_drv(altro_probe): udev->descriptor.idProduct = 0x%08x\n", udev->descriptor.idProduct));
-  cardtype = udev->descriptor.idProduct;
-  
-  iface = &udev->actconfig->interface[ifnum];
-  interface = &iface->altsetting[iface->act_altsetting];
-
-  if (interface->bNumEndpoints != 2) 
-  {
-    kdebug(("altro_drv(altro_probe): ERROR interface->bNumEndpoints != 2 (number = %d)\n", interface->bNumEndpoints));
-    return NULL;
-  }
-  
-  inok = 0;
-  outok = 0;
-    
-  for (i = 0; i < interface->bNumEndpoints; ++i) 
-  {
-    kdebug(("altro_drv(altro_probe): Processing endpoint %d ...\n", i));
-    endpoint = &interface->endpoint[i];
-    
-    if ((endpoint->bEndpointAddress & 0x80) && ((endpoint->bmAttributes & 3) == 0x02)) 
-    {
-      if (!inok) 
-      {
-        kdebug(("altro_drv(altro_probe): we found the first bulk in endpoint\n"));
-	buffer_size = endpoint->wMaxPacketSize;
-	kdebug(("altro_drv(altro_probe): buffer_size = %d\n", buffer_size));
-	altro->bulk_in_size = buffer_size;
-	altro->bulk_in_endpointAddr = endpoint->bEndpointAddress;
-	kdebug(("altro_drv(altro_probe): bulk_in_endpointAddr = %d\n", altro->bulk_in_endpointAddr));
-	altro->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
-	if (!altro->bulk_in_buffer) 
-	{
-          kdebug(("altro_drv(altro_probe): Couldn't allocate bulk_in_buffer"));
-          return NULL;
-	}
-	inok = 1;
-      }
-      else
-        kdebug(("altro_drv(altro_probe): we found another bulk in endpoint\n"));
-    }
-    
-    else if (((endpoint->bEndpointAddress & 0x80) == 0x00) && ((endpoint->bmAttributes & 3) == 0x02)) 
-    {
-      if (!outok) 
-      {
-	kdebug(("altro_drv(altro_probe): we found the first bulk out endpoint\n"));
-	altro->write_urb = usb_alloc_urb(0);
-	if (!altro->write_urb) 
-	{
-          kdebug(("altro_drv(altro_probe): No free urbs available"));
-          return NULL;
-	}
-	buffer_size = endpoint->wMaxPacketSize;
-	kdebug(("altro_drv(altro_probe): buffer_size = %d\n", buffer_size));
-	altro->bulk_out_size = buffer_size;
-	altro->bulk_out_endpointAddr = endpoint->bEndpointAddress;
-	kdebug(("altro_drv(altro_probe): bulk_out_endpointAddr = %d\n", altro->bulk_out_endpointAddr));
-	altro->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
-	if (!altro->bulk_out_buffer) 
-	{
-          kdebug(("altro_drv(altro_probe): Couldn't allocate bulk_out_buffer"));
-          return NULL;
-	}
-	outok = 1;
-      }	
-
-      else
-        kdebug(("altro_drv(altro_probe): we found another bulk out endpoint\n"));
-    }
-    else
-      {
-	kdebug(("altro_drv(altro_probe): we found an unidentifiable endpoint\n"));
-	return NULL;
-    }
-  }
-  
-  altro->udev = udev;
-  altrop = altro;
-  kdebug(("altro_drv(altro_probe): End of function\n"));
-
-  return altro;
-}
-
-
-/* Function called at module load time: only register the USB callbacks */
-/******************/
-int altro_init(void)
-/******************/
-{
-  kdebug(("altro_drv(altro_init): function called\n"));
-
-  /* Install /proc entry */
-  altro_file = create_proc_entry("altro", 0644, NULL);
-  if (altro_file == NULL) 
-  {
-    kdebug(("altro_drv(altro_init): ERROR from call to create_proc_entry\n"));
-    return (-ENOMEM);
-  }
-
-  strcpy(altro_proc_data.name, "altro");
-  strcpy(altro_proc_data.value, "altro");
-  altro_file->data = &altro_proc_data;
-  altro_file->read_proc = proc_read_altro;
-  altro_file->write_proc = proc_write_altro;
-  altro_file->owner = THIS_MODULE;
-    
-  return usb_register(&altro_usb_driver);
-}
-
-
-/* Function called at module unload time: only unregister the USB callbacks */ 
-/*******************/
-void altro_exit(void)
-/*******************/
-{
-  kdebug(("altro_drv(altro_exit): function called\n"));
-
-  /* Remove /proc entry */
-  remove_proc_entry("altro", NULL);
-  
-  usb_deregister(&altro_usb_driver);
-}
-
-
-/**********************/
-module_init(altro_init);
-/**********************/
-
-
-/**********************/
-module_exit(altro_exit);
-/**********************/
-
-
-/*************************************************************************************************/
-static int proc_write_altro(struct file *file, const char *buffer, unsigned long count, void *data)
-/*************************************************************************************************/
-{
-  int len;
-  struct altro_proc_data_t *fb_data = (struct altro_proc_data_t *)data;
-
-  kdebug(("altro_drv(proc_write_altro): proc_write_altro called\n"));
-  
-  if(count > 99)
-    len = 99;
-  else
-    len = count;
-  
-  if (copy_from_user(fb_data->value, buffer, len)) 
-  {
-    kdebug(("altro_drv(proc_write_altro): error from copy_from_user\n"));
-    return(-EFAULT);
-  }
-
-  kdebug(("altro_drv(proc_write_altro): len = %d\n", len));
-  fb_data->value[len - 1] = '\0';
-  kdebug(("altro_drv(proc_write_altro): text passed = %s\n", fb_data->value));
-  
-  if (!strcmp(fb_data->value, "debug")) 
-  {
-    debug = 1;
-    kdebug(("altro_drv(proc_write_altro): debugging enabled\n")); 
-  }
- 
-  if (!strcmp(fb_data->value, "nodebug")) 
-  {
-    kdebug(("altro_drv(proc_write_altro): debugging disabled\n")); 
-    debug = 0; 
-  }
-  
-  if (!strcmp(fb_data->value, "datadump")) 
-  {
-    ddump = 1;
-    kdebug(("altro_drv(proc_write_altro): data dumping enabled\n")); 
-  }
- 
-  if (!strcmp(fb_data->value, "nodatadump")) 
-  {
-    ddump = 0; 
-    kdebug(("altro_drv(proc_write_altro): data dumping disabled\n")); 
-  }
-  
-  if (!strcmp(fb_data->value, "dec")) 
-  {
-    MOD_DEC_USE_COUNT;
-    kdebug(("altro_drv(proc_write_altro): Use count decremented\n"));
-  }
-
-  if (!strcmp(fb_data->value, "inc")) 
-  {
-    MOD_INC_USE_COUNT;
-    kdebug(("altro_drv(proc_write_altro): Use count incremented\n"));
-  }
- 
-  return len;
-}
-
-
-/**********************************************************************************************/
-static int proc_read_altro(char *page, char **start, off_t off, int count, int *eof, void *data)
-/**********************************************************************************************/
-{
-  int len;
-
-  kdebug(("altro_drv(proc_read_altro): proc_read_altro called\n"));
-
-  len = sprintf(page, "ALICE ALTRO USB driver\n");
-  len += sprintf(page + len, " \n");
-  len += sprintf(page + len, "Type of card connected: ");
-  if (cardtype == 0x15e || cardtype == 0x350)
-    len += sprintf(page + len, "ALICE U2F\n");
-  else if (cardtype == 0x15f)
-    len += sprintf(page + len, "ALICE GOOFIE\n");
-  else if (cardtype == 0x163)
-    len += sprintf(page + len, "ALICE MPT\n");
-  else
-    len += sprintf(page + len, "UNKNOWN (maybe your card is using an invalid device ID\n");
-  len += sprintf(page + len, "\n");
-  len += sprintf(page + len, "The time-out of usb_bulk_msg() is %d jiffies (usually: 1 jiffie = 10 ms)\n", timeout);
-  len += sprintf(page + len, "\n");
-  len += sprintf(page + len, "The command 'echo <action> > /proc/altro', executed as root,\n");
-  len += sprintf(page + len, "allows you to interact with the driver. Possible actions are:\n");
-  len += sprintf(page + len, "debug      -> enable debugging\n");
-  len += sprintf(page + len, "nodebug    -> disable debugging\n");
-  len += sprintf(page + len, "datadump   -> enable data dumping (use with care)\n");
-  len += sprintf(page + len, "nodatadump -> disable data dumping\n");
-  len += sprintf(page + len, "dec        -> Decrement use count\n");
-  len += sprintf(page + len, "inc        -> Increment use count\n");
-
-  *eof = 1;
-  *start = page + off;
-  len -= off;
-
-  if (len > count)
-    len = count;
-  return (len);
-}
-
-
-/**************************************************************************************************/
-static int altro_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-/**************************************************************************************************/
-{
-  struct altro_device *altro;
-  int pipe, retval, loop;
-  
-  kdebug(("altro_drv(altro_ioctl): function called\n")); 
-  kdebug(("altro_drv(altro_ioctl): minor number = %d\n", MINOR (inode->i_rdev)));
-
-  altro = (struct altro_device *)file->private_data;
-  
-  /* lock this object */
-  down (&altro->sem);
-  kdebug(("altro_drv(altro_ioctl): semaphore locked\n")); 
-  
-  /* verify that the device wasn't unplugged */
-  if (altro->udev == NULL) 
-  {
-    up (&altro->sem);
-    kdebug(("altro_drv(altro_ioctl): ERROR device was unplugged\n"));
-    return -ENODEV;
-  }
-  kdebug(("altro_drv(altro_ioctl): The device is still connected\n")); 
-  
-  switch (cmd) 
-  {    
-    case GET_DATA: 
-    {   
-      altro_bulk_in_t params; /*MJ: this memory gets allocated on the stack. Better move it to the private data*/
-      kdebug(("altro_drv(ioctl:GET_DATA): function called for endpoint 0x%08x\n", altro->bulk_in_endpointAddr));
-      kdebug(("altro_drv(ioctl:GET_DATA): altro->bulk_in_size = %d\n", altro->bulk_in_size));
-
-      pipe = usb_rcvbulkpipe(altro->udev, altro->bulk_in_endpointAddr);
-      kdebug(("altro_drv(ioctl:GET_DATA): reading from pipe %d\n", pipe));
-
-      /* do an immediate bulk read to get data from the device */
-      /* MJ: The parameter altro->bulk_in_size requests as much data as the ALTRO can actually send */
-      /* MJ: The real amount of data may be less than that.*/
-      /* MJ: The constant BULK_IN_SIZE in the header file has to be tuned to the value of endpoint->wMaxPacketSize*/ 
-      retval = usb_bulk_msg(altro->udev, pipe, &params.data[0], altro->bulk_in_size, &params.nbytes, timeout);
-      kdebug(("altro_drv(ioctl:GET_DATA): usb_bulk_msg returns %d\n", retval));
-
-      if (retval)  
-      {
-	kdebug(("altro_drv(ioctl:GET_DATA): No data received\n"));
-	params.nbytes = 0;
-      }
-      else
-	kdebug(("altro_drv(ioctl:GET_DATA): %d bytes received\n", params.nbytes));
-
-      if (ddump)
-      {
-	kdebug(("altro_drv(ioctl:GET_DATA): Now dumping newly received data.......\n"));
-        for (loop = 0; loop < params.nbytes; loop++)
-	  kdebug(("altro_drv(ioctl:GET_DATA): Byte #%d = 0x%02x\n", loop, params.data[loop]));
-      } 
-
-      if (copy_to_user ((void *)arg, &params, sizeof(altro_bulk_in_t)) != 0) 
-      {
-	kdebug(("altro_drv(ioctl:GET_DATA): error from copy_to_user\n"));
-	up (&altro->sem);
-	return(-ALTRO_EFAULT);
-      }
-      break;
-    }    
-
-    case SEND_DATA: 
-    {   
-      altro_bulk_out_t params;  /*MJ: this memory gets allocated on the stack. Better move it to the private data*/
-      int maxp, ndone;
-
-      kdebug(("altro_drv(ioctl:SEND_DATA): function called for endpoint 0x%08x\n", altro->bulk_out_endpointAddr));
-      kdebug(("altro_drv(ioctl:SEND_DATA): altro->bulk_in_size = %d\n", altro->bulk_out_size));
-
-      if (copy_from_user(&params, (void *)arg, sizeof(altro_bulk_out_t)) !=0) 
-      {
-	kdebug(("altro_drv(ioctl:SEND_DATA): error from copy_from_user\n"));
-	up (&altro->sem);
-	return(-ALTRO_EFAULT);
-      }
-
-      pipe = usb_sndbulkpipe(altro->udev, altro->bulk_out_endpointAddr);
-      kdebug(("altro_drv(ioctl:SEND_DATA): reading from pipe %d\n", pipe));
-
-      maxp = usb_maxpacket(altro->udev, pipe, usb_pipeout(pipe));
-      if (maxp > altro->bulk_out_size) 
-	maxp = altro->bulk_out_size; 
-      kdebug(("altro_drv(ioctl:SEND_DATA): it is possible to send %d bytes\n", maxp));
-
-      /* check if we would write more data than possible */
-      if (params.nbytes > maxp) 
-      {	
-	kdebug(("altro_drv(ioctl:SEND_DATA): Cannot write %d bytes to pipe of %d bytes\n", params.nbytes, maxp));
-	up (&altro->sem);
-	return(-ALTRO_EFAULT);
-      }
-      kdebug(("altro_drv(ioctl:SEND_DATA): trying to send %d bytes\n", params.nbytes));
-
-      if (ddump)
-      {
-	kdebug(("altro_drv(ioctl:SEND_DATA): Dumping data berfore sending it.......\n"));
-        for (loop = 0; loop < params.nbytes; loop++)
-	  kdebug(("altro_drv(ioctl:SEND_DATA): Byte #%d = 0x%02x\n", loop, params.data[loop]));
-      } 
-
-      /* do an immediate bulk write to send data to the device */
-      retval = usb_bulk_msg(altro->udev, pipe, &params.data[0], params.nbytes, &ndone, timeout);
-      kdebug(("altro_drv(ioctl:SEND_DATA): usb_bulk_msg returns %d\n", retval));
-      if (retval) 
-      {
-	kdebug(("altro_drv(ioctl:SEND_DATA): No data sent\n"));
-	up (&altro->sem);
-	return(-ALTRO_EFAULT);
-      }
-      else
-	kdebug(("altro_drv(ioctl:SEND_DATA): %d bytes sent\n", ndone));
-
-      break;
-    }     
-
-    case CONTROL: 
-    {
-      altro_control_t params;  /*MJ: this memory gets allocated on the stack. Better move it to the private data*/
-
-      kdebug(("altro_drv(ioctl:CONTROL): function called\n"));
-
-      if (copy_from_user(&params, (void *)arg, sizeof(altro_control_t)) !=0 ) 
-      {
-	kdebug(("altro_drv(ioctl:CONTROL): error from copy_from_user\n"));
-	up (&altro->sem);
-	return(-ALTRO_EFAULT);
-      }
-
-      kdebug(("altro_drv(ioctl:CONTROL): params.bRequest      = %d\n", params.bRequest));
-      kdebug(("altro_drv(ioctl:CONTROL): params.bmRequestType = %d\n", params.bmRequestType));
-      kdebug(("altro_drv(ioctl:CONTROL): params.wValue        = %d\n", params.wValue));
-      kdebug(("altro_drv(ioctl:CONTROL): params.wIndex        = %d\n", params.wIndex));
-      kdebug(("altro_drv(ioctl:CONTROL): params.data[0]       = %d\n", params.data[0]));
-      kdebug(("altro_drv(ioctl:CONTROL): params.wLength       = %d\n", params.wLength));
-
-      retval = usb_control_msg(altro->udev, usb_rcvctrlpipe(altro->udev,0), params.bRequest, params.bmRequestType, 
-			       params.wValue, params.wIndex, &params.data[0], params.wLength, HZ);
-      if (retval) 
-      {
-	kdebug(("altro_drv(ioctl:CONTROL): ERROR  failed to register control URB. Error code = %d\n", retval));
-	up (&altro->sem); 
-	return(-ALTRO_EFAULT);
-      }
-      break;
-    }
-  }
-  /* unlock the device */
-  up (&altro->sem);
-  return(0);
-}
diff -u -r -N -xCVS u2f.cern/altro/altro_driver_26.c u2f/altro/altro_driver_26.c
--- u2f.cern/altro/altro_driver_26.c	2005-11-21 09:57:24.000000000 +0100
+++ u2f/altro/altro_driver_26.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,1272 +0,0 @@
-/*
- * This diver based on:
- (
- * USB Skeleton driver - 1.1
- *
- * Copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
- *
- *	This program is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License as
- *	published by the Free Software Foundation, version 2.
- */
-/** @file    altro_driver_26.c
- *  @author  Markus Joos, CERN-PH-ESS 15.3.2004
- *  @date    Mon Jan 17 22:28:58 2005
- *  @brief   This is the driver for the ALICE RCU card
- *
- *  This driver works for kernels from 2.4 onwards
- *
- *  Currently only one RCU card is supported. Extending the driver for
- *  multiple cards would require to introduce a "minor" array as done
- *  in the usb-skeleton driver 
- *
- *  @par open issues:  
- *
- *  1) The memory read functions do not work because the IN
- *  transaction is executed before the OUT transaction 
- *
- *  2) If one repeats the same memory write two times
- *  (e.g. IMEM_Write) the first transaction has an ACK,   
- *  the second a NYet, the third URB does not complete and the
- *  fourth creates the error mentioned in issue 1) above  
- *
- *  3) The memory read/write calls in the U2F library need an offset
- *  parameter relative to the respective memory
-*/
-/** @defgroup altro_driver RCU driver code  */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/version.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/smp_lock.h>
-#include <linux/completion.h>
-#include <asm/uaccess.h>
-#include <linux/usb.h>
-#include <linux/proc_fs.h>
-#include "altro_common.h"
-
-/********************************************************************/
-/** @name Debug 
- *  @ingroup altro_driver 
- */
-#ifdef CONFIG_USB_DEBUG
-/** @var debug 
- *  @brief Debug flag 
- */
-static int debug = 1;
-#else
-static int debug;
-#endif
-
-#undef kdebug
-/** @def kdebug 
- *  @brief macro to print debug information to system log */
-#define kdebug(x) \
-  do { if (debug) { printk("ALTRO [%s]: ", __FUNCTION__); printk x; } } while (0)
-
-/********************************************************************/
-/*  @name Version Information 
- *  @ingroup altro_driver 
- */
-/** @def DRIVER_VERSION
- *  @ingroup altro_driver 
- *  @brief v1.0
- */
-#define DRIVER_VERSION "v1.0"
-/** @def DRIVER_AUTHOR
- *  @ingroup altro_driver 
- *  @brief Markus Joos, CERN/PH
- */
-#define DRIVER_AUTHOR  "Markus Joos, CERN/PH"
-/** @def DRIVER_DESC
- *  @ingroup altro_driver 
- *  @brief USB driver for the ALICE ALTRO card
- */
-#define DRIVER_DESC    "USB driver for the ALICE ALTRO card"
-/** @def DRIVER_LICENSE
- *  @ingroup altro_driver 
- *  @brief Private: Contact markus.joos@cern.ch
- */
-#define DRIVER_LICENSE "Private: Contact markus.joos@cern.ch"
-
-/********************************************************************/
-/*  @name Module parameters
- *  @ingroup altro_driver 
- */
-MODULE_PARM(debug, "i");
-MODULE_PARM_DESC(debug, "Debug enabled or not");
-
-/********************************************************************/
-/*  @name Device information
- *  @ingroup altro_driver 
- */
-/** @def USB_ALTRO_VENDOR_ID
- *  @ingroup altro_driver 
- *  @brief The vendor identifier 
- */
-#define USB_ALTRO_VENDOR_ID	 0x1556
-/** @def USB_ALTRO_PRODUCT_ID
- *  @ingroup altro_driver 
- *  @brief The product identifier 
- */
-#define USB_ALTRO_PRODUCT_ID 	0x0350
-/** @def USB_ALTRO_U2F_ID 
- *  @ingroup altro_driver
- *  @brief Product identifier for the U2F board 
- */
-#define USB_ALTRO_U2F_ID          0x15e
-/** @def USB_ALTRO_GOFFIE_ID 
- *  @ingroup altro_driver
- *  @brief Product identifier for the GOFFIE board 
- */
-#define USB_ALTRO_GOFFIE_ID       0x15f
-/** @def USB_ALTRO_MPT_ID 
- *  @ingroup altro_driver
- *  @brief Product identifier for the MPT board 
- */
-#define USB_ALTRO_MPT_ID          0x163
-
-
-/** @var altro_table
- *  @ingroup altro_driver 
- *  @brief  table of devices that work with this driver 
- */
-static struct usb_device_id altro_table [] = {
-  { USB_DEVICE(USB_ALTRO_VENDOR_ID, USB_ALTRO_PRODUCT_ID),
-    driver_info: (unsigned long)"altro_by_vendor (invalid device ID)" },
-  { USB_DEVICE(USB_ALTRO_VENDOR_ID, USB_ALTRO_U2F_ID), 
-    driver_info: (unsigned long)"ALICE U2F" },
-  { USB_DEVICE(USB_ALTRO_VENDOR_ID, USB_ALTRO_GOFFIE_ID), 
-    driver_info: (unsigned long)"ALICE GOFFIE" },
-  { USB_DEVICE(USB_ALTRO_VENDOR_ID, USB_ALTRO_MPT_ID), 
-    driver_info: (unsigned long)"ALICE MPT" },
-  { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, altro_table);
-
-
-/********************************************************************/
-/*  @name Driver information 
- *  @ingroup altro_driver 
- */ 
-#ifndef USB_ALTRO_MINOR_BASE
-/** @def  USB_ALTRO_MINOR_BASE
- *  @ingroup altro_driver 
- *  @brief Get a minor range for your devices from the usb maintainer
- */ 
-# define USB_ALTRO_MINOR_BASE	192
-#endif
-
-//____________________________________________________________________
-/** @struct altro_device 
- *  @brief Structure to hold all of our device specific stuff 
- *  @ingroup altro_driver 
- */
-struct altro_device {
-  /** save off the usb device pointer */ 
-  struct usb_device*	udev;			
-  /** the interface for this device */ 
-  struct usb_interface*	interface;		
-  /** the starting minor number for this device */ 
-  unsigned char minor;			
-  /** the number of ports this device has */ 
-  unsigned char	num_ports;		
-  /** number of interrupt in endpoints we have */ 
-  char num_interrupt_in;	
-  /** number of bulk in endpoints we have */
-  char num_bulk_in;		
-  /** number of bulk out endpoints we have */ 
-  char	num_bulk_out;		
-  
-  /** the buffer to receive data */ 
-  unsigned char* bulk_in_buffer;		
-  /** the size of the receive buffer */ 
-  size_t bulk_in_size;		
-  /** the urb used to recieve data */ 
-  struct urb* read_urb;		
-  /** the address of the bulk in endpoint */
-  __u8	bulk_in_endpointAddr;	
-
-  /** the buffer to send data */ 
-  unsigned char* bulk_out_buffer;	
-  /** the size of the send buffer */ 
-  size_t bulk_out_size;		
-  /** the urb used to send data */ 
-  struct urb* write_urb;		
-  /** the address of the bulk out endpoint */ 
-  __u8	bulk_out_endpointAddr;	
-  /** true iff write urb is busy */ 
-  atomic_t write_busy;		
-  /** wait for the write to finish */ 
-  struct completion write_finished;		
-
-  /** if the port is open or not */ 
-  int open;			
-  /** if the device is not disconnected */ 
-  int present;		
-  /** locks this structure */ 
-  struct semaphore sem;			
-
-  /** Test data */ 
-  int test;
-  /** Name */
-  char* name;
-};
-
-static u_int    n_our_devices = 0;
-static struct altro_device* our_devices[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-static void add_our_device(struct altro_device* dev) 
-{
-  if (n_our_devices >= 10) {
-    kdebug(("Cannot add the 11th device to internal table"));
-    return;
-  }
-  our_devices[n_our_devices] = dev;
-  kdebug(("Added device %s at %d", dev->name, n_our_devices));
-  n_our_devices++;
-}
-
-static void remove_our_device(struct altro_device* dev) 
-{
-  u_int i = 0;
-  for (i = 0; i < n_our_devices; i++) {
-    if (dev == our_devices[i]) {
-      our_devices[i] = 0;
-      n_our_devices--;
-      kdebug(("Removed device %s at %d", dev->name, i));
-      break;
-    }
-  }
-  for (; i < n_our_devices + 1; i++) 
-    our_devices[i] = our_devices[i+1];
-  if (i >=  n_our_devices + 1)
-    our_devices[i] = 0;
-}
-  
-
-/** @brief Semaphore to prevent races between open() and disconnect() 
- *  @ingroup altro_driver 
- */
-static DECLARE_MUTEX (disconnect_sem);
-
-/* static struct altro_device*     _altro = NULL; */
-
-/********************************************************************/
-/*  @name PROC node
- *  @ingroup altro_driver 
- */ 
-/** @struct altro_proc_data_t
- *  @ingroup altro_driver 
- *  @brief Data structure for the @c /proc file system node 
- */
-struct altro_proc_data_t
-{
-  /** Name */
-  char name[10];
-  /** Values */
-  char value[100];
-};
-/** @var altro_proc_file
- *  @ingroup altro_driver 
- *  @brief @c /proc file system node 
- */
-static struct proc_dir_entry* altro_proc_file;
-/** @var altro_proc_data
- *  @ingroup altro_driver 
- *  @brief Data of the @c /proc file system node 
- */
-static struct altro_proc_data_t altro_proc_data;
-
-/********************************************************************/
-/* local function prototypes  - the functions are documented at thier
- * definition 
- */
-static int altro_ioctl(struct inode *inode, struct file *file, 
-			   unsigned int cmd, unsigned long arg);
-static int altro_open(struct inode *inode, struct file *file);
-static int altro_release(struct inode *inode, struct file *file);
-static int altro_probe(struct usb_interface *interface, 
-		     const struct usb_device_id *id);
-static void altro_disconnect(struct usb_interface *interface);
-static ssize_t altro_read(struct file *file, char *buffer, 
-			size_t count, loff_t *ppos);
-static ssize_t altro_write(struct file *file, const char *buffer, 
-			 size_t count, loff_t *ppos);
-static void altro_write_bulk_callback(struct urb *urb, 
-				    struct pt_regs *regs);
-
-static int  altro_proc_write(struct file *file, const char *buffer, 
-			   unsigned long count, void *data);
-static int  altro_proc_read(char *page, char **start, off_t off, 
-			  int count, int *eof, void *data);
-
-
-/********************************************************************/
-/*  @name Driver structures used by USB layer in kernel
- *  @ingroup altro_driver 
- */ 
-/** @var altro_fops
- *  @brief Call-backs when doing I/O on this device 
- *  @ingroup altro_driver 
- *
- *  File operations needed when we register this driver.  This assumes
- *  that this driver @e needs file operations, of course, which means
- *  that the driver is expected to have a node in the @c /dev
- *  directory. If the USB device were for a network interface then the
- *  driver would use @c struct @c net_driver instead, and a serial
- *  device would use @c struct @c tty_driver.
- */
-static struct file_operations altro_fops = {
-  /*
-   * The owner field is part of the module-locking mechanism. The idea
-   * is that the kernel knows which module to increment the
-   * use-counter of BEFORE it calls the device's open() function.
-   * This also means that the kernel can decrement the use-counter
-   * again before calling release() or should the open() function
-   * fail.
-   */
-  .owner =	THIS_MODULE,
-  .ioctl =	altro_ioctl,
-  .open =	altro_open,
-  .release =	altro_release,
-  .read =	altro_read,
-  .write =	altro_write
-};
-
-/** @var altro_class 
- *  @brief The type of the USB device 
- *  @ingroup altro_driver 
- * 
- *  USB class driver info in order to get a minor number from the USB
- *  core, and to have the device registered with devfs and the driver
- *  core
- */
-static struct usb_class_driver altro_class = {
-  .name = "altro%d",
-  .fops = &altro_fops,
-  .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |  S_IWOTH,
-  .minor_base =	USB_ALTRO_MINOR_BASE,
-};
-
-/** @var altro_driver 
- *  @brief Driver call backs 
- *  @ingroup altro_driver 
- * 
- *  USB specific object needed to register this driver with the USB
- *  subsystem
- */ 
-static struct usb_driver altro_driver = {
-  .owner =	THIS_MODULE,
-  .name =	"altro",
-  .probe =	altro_probe,
-  .disconnect =	altro_disconnect,
-  .id_table =	altro_table,
-};
-
-/********************************************************************/
-/*  @name Functions
- *  @ingroup altro_driver 
- */ 
-/*__________________________________________________________________*/
-/** Delete the ALTRO driver structures 
- *  @param dev The device to free memory for 
- *  @ingroup altro_driver 
- */
-static inline void 
-altro_delete(struct altro_device *dev)
-{
-  kfree (dev->bulk_in_buffer);
-  usb_buffer_free(dev->udev, dev->bulk_out_size,
-		  dev->bulk_out_buffer,
-		  dev->write_urb->transfer_dma);
-  usb_free_urb(dev->write_urb);
-  kfree(dev);
-}
-
-/*__________________________________________________________________*/
-/** Call-back for @c open system call 
- *  @param inode The node opened by the user 
- *  @param file  The file pointer to open
- *  @return 0 on success, error code otherwise
- *  @ingroup altro_driver 
- */
-static int 
-altro_open(struct inode *inode, struct file *file)
-{
-  struct altro_device*    dev = NULL;
-  struct usb_interface* interface;
-  int                   subminor;
-  int                   retval = 0;
-  kdebug(("called"));
-
-  // the below is if we have more than one USB device.
-  subminor = iminor(inode);
-  kdebug(("minor number = %d\n", subminor));
-
-  /* prevent disconnects */
-  down(&disconnect_sem);
-
-  interface = usb_find_interface (&altro_driver, subminor);
-  if (!interface) {
-    err ("%s - error, can't find device for minor %d", __FUNCTION__, subminor);
-    retval = -ENODEV;
-    goto exit_no_device;
-  }
-
-  dev = usb_get_intfdata(interface);
-  if (!dev) {
-    retval = -ENODEV;
-    goto exit_no_device;
-  }
-
-  /* lock this device */
-  down(&dev->sem);
-  
-  /* increment our usage count for the driver */
-  ++dev->open;
-
-  /* save our object in the file's private structure */
-  file->private_data = dev;
-
-  /* unlock this device */
-  up (&dev->sem);
-
- exit_no_device:
-  up (&disconnect_sem);
-  return retval;
-}
-
-/*__________________________________________________________________*/
-/** Call-back for @c close system call 
- *  @param inode the node to close
- *  @param file  The file descriptor to close 
- *  @return 0 on success, error code otherwise
- *  @ingroup altro_driver 
- */
-static int 
-altro_release(struct inode *inode, struct file *file)
-{
-  int retval = 0;
-  // The below is if we have more than one device 
-  struct altro_device* dev;
-
-  dev = (struct altro_device *)file->private_data;
-  if (dev == NULL) {
-    dbg ("%s - object is NULL", __FUNCTION__);
-    return -ENODEV;
-  }
-  kdebug(("minor %d\n", dev->minor));
-
-  /* lock our device */
-  down (&dev->sem);
-  if (dev->open <= 0) {
-    kdebug(("device not opened"));
-    retval = -ENODEV;
-    goto exit_not_opened;
-  }
-
-  /* wait for any bulk writes that might be going on to finish up */
-  if (atomic_read (&dev->write_busy))
-    wait_for_completion (&dev->write_finished);
-
-  --dev->open;
-
-  if (!dev->present && !dev->open) {
-    /* the device was unplugged before the file was released */
-    up (&dev->sem);
-    altro_delete (dev);
-    return 0;
-  }
-
- exit_not_opened:
-  up (&dev->sem);
-  return retval;
-}
-
-/*__________________________________________________________________*/
-/** Print out debug data. 
- *  @param function The function that called this 
- *  @param size the size of @a data 
- *  @param data The data to write out
- *  @ingroup altro_driver 
- */
-static inline void 
-altro_debug_data(const char *function, int size, const unsigned char *data)
-{
-  int i;
-  if (!debug) return;
-  printk(KERN_DEBUG __FILE__": %s - length = %d, data = ", function, size);
-  for (i = 0; i < size; ++i) printk ("%.2x ", data[i]);
-  printk ("\n");
-}
-
-/*__________________________________________________________________*/
-/** Call-back of @c read system call 
- *
- *   @param file File the user is reading from 
- *   @param buffer On return, the data read
- *   @param count On input, the size of @a buffer in bytes. 
- *   @param ppos Not used. 
- *   @return The actual number of bytes read, or negative error
- *   code on failure
- *  @ingroup altro_driver 
- */
-static ssize_t 
-altro_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
-{
-  struct altro_device *dev;
-  int retval = 0;
-
-  dev = (struct altro_device *)file->private_data;
-  kdebug(("minor %d, count = %d", dev->minor, count));
-
-  /* lock this object */
-  down (&dev->sem);
-
-  /* verify that the device wasn't unplugged */
-  if (!dev->present) {
-    kdebug(("Error: Device was unplugged!\n"));
-    up (&dev->sem);
-    return -ENODEV;
-  }
-
-  kdebug(("function called for end-point 0x%08x\n"
-	  "  bulk_in_size: %d", dev->bulk_in_endpointAddr, dev->bulk_in_size));
-  
-  /* do a blocking bulk read to get data from the device */ 
-  retval = usb_bulk_msg(dev->udev,
-			usb_rcvbulkpipe (dev->udev, 
-					 dev->bulk_in_endpointAddr),
-			dev->bulk_in_buffer,
-			min (dev->bulk_in_size, count),
-			&count, HZ*10);
-
-  /* if the read was successful, copy the data to userspace */
-  if (!retval) {
-    if (copy_to_user (buffer, dev->bulk_in_buffer, count)) {
-      kdebug(("error from copy_to_user"));
-      retval = -EFAULT;
-    }
-    else
-      retval = count;
-  }
-  else 
-    kdebug(("No data recivied"));
-  
-  /* unlock the device */
-  up (&dev->sem);
-  return retval;
-}
-
-
-/*__________________________________________________________________*/
-/** Call-back of @c write system call 
- * 
- *  A device driver has to decide how to report I/O errors back to the
- *  user.  The safest course is to wait for the transfer to finish
- *  before returning so that any errors will be reported reliably.
- *  altro_read() works like this.  But waiting for I/O is slow, so many
- *  drivers only check for errors during I/O initiation and do not
- *  report problems that occur during the actual transfer.  That's
- *  what we will do here.
- *
- *  A driver concerned with maximum I/O throughput would use double-
- *  buffering: Two urbs would be devoted to write transfers, so that
- *  one URB could always be active while the other was waiting for the
- *  user to send more data.
- *
- *  @param file File the user is writing to 
- *  @param buffer The data the user is writing 
- *  @param count The size of @a buffer in bytes 
- *  @param ppos Not used. 
- *  @return The actual number of bytes written, or negative error code
- *  on failure 
- *  @ingroup altro_driver 
- */
-static ssize_t 
-altro_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) 
-{
-  struct altro_device* dev;
-  ssize_t            bytes_written = 0;
-  int                retval        = 0;
-
-  dev = (struct altro_device *)file->private_data;
-  kdebug(("minor %d, count = %d\n", dev->minor, count)); 
-
-  /* lock this object */ 
-  down (&dev->sem); 
-
-  /* verify that the device wasn't unplugged */ 
-  if (!dev->present) { 
-    kdebug(("Error: Device was unplugged!\n")); 
-    retval = -ENODEV; 
-    goto exit; 
-  }
-
-  kdebug(("function called for end-point 0x%08x\n"
-	  "  bulk_in_size: %d", dev->bulk_in_endpointAddr, dev->bulk_in_size));
-
-  /* verify that we actually have some data to write */ 
-  if (count == 0) { 
-    kdebug(("write request of 0 bytes\n")); 
-    goto exit; 
-  } 
-
-  /* wait for a previous write to finish up; we don't use a timeout
-   * and so a nonresponsive device can delay us indefinitely.
-   */
-  if (atomic_read (&dev->write_busy))
-    wait_for_completion (&dev->write_finished);
-
-  /* we can only write as much as our buffer will hold */
-  bytes_written = min (dev->bulk_out_size, count);
-
-  /* copy the data from userspace into our transfer buffer;
-   * this is the only copy required.
-   */
-  if (copy_from_user(dev->write_urb->transfer_buffer, buffer, bytes_written)) {
-    kdebug(("error from copy_from_user"));
-    retval = -EFAULT;
-    goto exit;
-  }
-
-  altro_debug_data (__FUNCTION__, bytes_written, 
-		  dev->write_urb->transfer_buffer);
-
-  /* this urb was already set up, except for this write size */
-  dev->write_urb->transfer_buffer_length = bytes_written;
-
-  /* send the data out the bulk port */
-  /* a character device write uses GFP_KERNEL, unless a spinlock is held */
-  init_completion (&dev->write_finished);
-  atomic_set (&dev->write_busy, 1);
-  retval = usb_submit_urb(dev->write_urb, GFP_KERNEL);
-  if (retval) {
-    atomic_set (&dev->write_busy, 0);
-    kdebug(("No data sent"));
-    err("%s - failed submitting write urb, error %d", __FUNCTION__, retval); 
-  } else {
-    kdebug(("%d bytes sent", bytes_written));
-    retval = bytes_written; 
-  }
-
- exit:
-  /* unlock the device */
-  up (&dev->sem);
-
-  return retval;
-}
-
-/*__________________________________________________________________*/
-
-// Turn Jiffies into milliseconds.  Since 2.6.12, the time-out
-// parameter of usb_bulk_msg should be in seconds, not jiffies. 
-#if HZ == 1000
-# define JIFFIES_TO_MSECS(x) (x)
-# define MSECS_TO_JIFFIES(x) (x)
-#elif HZ == 100
-# define JIFFIES_TO_MSECS(x) ((x) * 10)
-# define MSECS_TO_JIFFIES(x) (((x) + 9) / 10)
-#else
-# define JIFFIES_TO_MSECS(x) (((x) * 1000) / HZ)
-# define MSECS_TO_JIFFIES(x) (((x) * HZ + 999) / 1000)
-#endif
-#if  LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11) 
-# if HZ == 1000
-#  define TIMEOUT(x) (x)
-# elif HZ == 100
-#  define TIMEOUT(x) ((x) * 10)
-# else 
-#  define TIMEOUT(x) (((x)  * 1000) / HZ)
-# endif
-#else 
-# define  TIMEOUT(x) (x)
-#endif
-
-/** Call-back for the @c ioctl system call.  This driver understands
- *  three commands 
- *  <dl>
- *    <dt> @c SEND_DATA </dt>
- *    <dd> Send data to the ALTRO device.  In this case, the input
- *      parameter @a arg is taken to be a pointer to an @c
- *      altro_bulk_out_t variable allocated by the user. </dd>
- *    <dt> @c GET_DATA </dt>
- *    <dd> Get data from the ALTRO device.  In this case, the input
- *      parameter @a arg is taken to be a pointer to an @c
- *      altro_bulk_in_t variable allocated by the user. </dd>
- *    <dt> @c CONTROL </dt>
- *    <dd> Control message to the ALTRO device.  In this case, the input
- *      parameter @a arg is taken to be a pointer to an @c
- *      altro_control_t variable allocated by the user. </dd>
- *  </dl>
- *  @param inode Node doing the I/O control on 
- *  @param file File doing the I/O control on 
- *  @param cmd The command word 
- *  @param arg Arguments to the command 
- *  @return 0 on success, error code otherwise 
- *  @ingroup altro_driver 
- */
-static int 
-altro_ioctl(struct inode *inode, struct file *file, 
-	  unsigned int cmd, unsigned long arg)
-{
-  struct altro_device *dev;
-  int retval = 0, pipe;
-  kdebug(("function called %s\n", 
-	  (cmd == GET_DATA ? "GET_DATA" :
-	   (cmd == SEND_DATA ? "SEND_DATA" : 
-	    (cmd == CONTROL ? "CONTROL" : "unknown")))));
-  
-  // Get the device 
-  dev = (struct altro_device*)file->private_data;
-  kdebug(("test is %d\n", dev->test));
-  
-  /* lock this object */
-  down (&dev->sem);
-
-  /* verify that the device wasn't unplugged */
-  if (!dev->present) {
-    kdebug(("Error: Device was unplugged!\n"));
-    retval = -ENODEV;
-    goto ioctl_return;
-  }
-  kdebug(("minor %d, cmd 0x%.4x, arg %ld\n", dev->minor, cmd, arg));
-
-  /* fill in your device specific stuff here */
-  switch (cmd) {
-  case GET_DATA: {
-    altro_bulk_in_t params;
-    kdebug(("GET_DATA called for endpoint 0x%08x\n", 
-	    dev->bulk_in_endpointAddr));
-    kdebug(("in bulk size is %d\n", dev->bulk_in_size));
-
-#if 0
-    /* see if we alread in the middle of a write */
-    if (dev->read_urb->status == -EINPROGRESS) {
-      kdebug(("The bulk in URB is current in use\n"));
-      up(&dev->sem);
-      return (-ALTRO_EFAULT);
-    }
-#endif
-
-    /* Set up our URB */
-    pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr);
-    kdebug(("writing on pipe %d\n", pipe));
-    
-    /* do an immediate bulk read to get data from the device */
-    retval = usb_bulk_msg(dev->udev, pipe, &(params.data[0]), 
-			  dev->bulk_in_size, &(params.nbytes), 
-			  TIMEOUT(HZ * 10));
-    kdebug(("USB bulk message returns %d\n",retval));
-    if (retval) {
-      kdebug(("no data recieved!\n"));
-      params.nbytes = 0;
-    }
-    else 
-      kdebug(("%d bytes recieved\n", params.nbytes));
-    
-    /** Copy data to user */
-    if (copy_to_user((void*)arg, &params, sizeof(altro_bulk_in_t)) != 0){
-      kdebug(("error when copying to user\n"));
-      retval = -ALTRO_EFAULT;
-    }
-    break;
-  }
-  case SEND_DATA: {
-    altro_bulk_out_t params;
-    int maxp, ndone;
-    kdebug(("SEND_DATA called for endpoint 0x%08x\n", 
-	    dev->bulk_out_endpointAddr));
-    kdebug(("in bulk size is %d\n", dev->bulk_out_size));
-
-    /** Copy data from user */
-    if (copy_from_user(&params, (void*)arg, sizeof(altro_bulk_out_t))!= 0){
-      kdebug(("error when copying from user\n"));
-      retval = -ALTRO_EFAULT;
-      goto ioctl_return;
-    }
-
-    /* Set up our URB */
-    pipe = usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr); 
-    kdebug(("reading from pipe %d\n", pipe));
-    maxp = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
-    if (maxp > dev->bulk_out_size) maxp = dev->bulk_out_size;
-    kdebug(("it is possible to send %d bytes\n", maxp));
-    
-    /* Check if we would write more data than possible */
-    if (params.nbytes > maxp) {
-      kdebug(("cannot write %d bytes to pipe of %d bytes\n", 
-		params.nbytes, maxp));
-      retval = -ALTRO_EFAULT;
-      goto ioctl_return;
-    }
-
-    kdebug(("trying to sen %d bytes\n", params.nbytes));
-    /* do an immediate bulk write to send data to the device */
-    retval = usb_bulk_msg(dev->udev, pipe, &(params.data[0]), 
-			  params.nbytes, &ndone, 
-			  TIMEOUT(HZ * 10));
-    kdebug(("USB bulk message returns %d\n",retval));
-    if (retval) {
-      kdebug(("no data sent!\n"));
-      params.nbytes = 0;
-    }
-    else 
-      kdebug(("%d bytes sent\n", params.nbytes));
-  } // SEND_DATA
-    break;
-  case CONTROL: {
-    altro_control_t params;
-    kdebug(("CONTROL called"));
-    
-    /** Copy data from user */
-    if (copy_from_user(&params, (void*)arg, sizeof(altro_control_t)) != 0){
-      kdebug(("error when copying from user\n"));
-      retval = -ALTRO_EFAULT;
-      goto ioctl_return;
-    }
-    
-    kdebug(("CONTROL: bRequest      = %d\n", params.bRequest));   
-    kdebug(("CONTROL: bmRequestType = %d\n", params.bmRequestType));
-    kdebug(("CONTROL: wValue        = %d\n", params.wValue));
-    kdebug(("CONTROL: wIndex        = %d\n", params.wIndex));
-    kdebug(("CONTROL: data[0]       = %d\n", params.data[0]));
-    kdebug(("CONTROL: wLength       = %d\n", params.wLength));
-    
-    retval = usb_control_msg(dev->udev, 
-			     usb_rcvctrlpipe(dev->udev, 0),
-			     params.bRequest, 
-			     params.bmRequestType,
-			     params.wValue,
-			     params.wIndex,
-			     &(params.data[0]),  
-			     params.wLength, TIMEOUT(HZ));	  
-    if (retval) {
-      kdebug(("error when sending control word: %d\n", retval));
-      retval = -ALTRO_EFAULT;
-    }
-    break;
-  }// case CONTROL:
-  default:
-    retval = -ENOTTY;
-    break;
-  } // switch (cmd)
-  
- ioctl_return:  
-  /* unlock the device */
-  up (&dev->sem);
-
-  /* return that we did not understand this ioctl call */
-  return retval; /* (retval ? -ENOTTY : 0); */
-}
-
-
-/*__________________________________________________________________*/
-/** Call back when writing and URB bulk message 
- *  @param urb The URB (USB Request Block) that was sent 
- *  @param regs 
- *  @ingroup altro_driver 
- */
-static void
-altro_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
-{
-  struct altro_device *dev = (struct altro_device *)urb->context;
-
-  kdebug(("minor %d\n", dev->minor));
-
-  /* sync/async unlink faults aren't errors */
-  if (urb->status && !(urb->status == -ENOENT ||
-		       urb->status == -ECONNRESET)) {
-    kdebug(("nonzero write bulk status received: %d", urb->status));
-  }
-  
-  /* notify anyone waiting that the write has finished */
-  atomic_set (&dev->write_busy, 0);
-  complete (&dev->write_finished);
-}
-
-/*__________________________________________________________________*/
-/** Called by the usb core when a new device is connected that it
- *  thinks this driver might be interested in. 
- * 
- *  @param interface The interface that the driver may want to handle 
- *  @param id USB device ID of the device recently plugged in.
- *  @return 0 if the driver want's to handle the device plugged in;
- *  otherwise an error code. 
- *  @ingroup altro_driver 
- */
-static int 
-altro_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
-  struct usb_device *udev                   = interface_to_usbdev(interface);
-  struct altro_device *dev                    = NULL;
-  struct usb_host_interface *iface_desc     = 0;
-  struct usb_endpoint_descriptor *endpoint  = 0;
-  size_t buffer_size;
-  int i;
-  int retval = -ENOMEM;
-
-  kdebug(("checking if we want to handle this device %d:%d (%d:%d)",
-	  udev->descriptor.idVendor, udev->descriptor.idProduct,
-	  USB_ALTRO_VENDOR_ID, USB_ALTRO_PRODUCT_ID));
-  /* See if the device offered us matches what we can accept */
-  if ((udev->descriptor.idVendor != USB_ALTRO_VENDOR_ID)) 
-    return -ENODEV;
-  /* See if the device offered us matches what we can accept */
-  switch (udev->descriptor.idProduct) {
-  case USB_ALTRO_U2F_ID:    break;
-  case USB_ALTRO_GOFFIE_ID: break; 
-  case USB_ALTRO_MPT_ID:    break;
-  default: 
-    return -ENODEV;
-  }
-  kdebug(("got a %s card (%X,%X)", 
-	  (char*)(id->driver_info),
-	  udev->descriptor.idVendor, udev->descriptor.idProduct));
-  
-  /* allocate memory for our device state and initialize it */
-  dev = kmalloc (sizeof(struct altro_device), GFP_KERNEL);
-  if (dev == NULL) {
-    err ("Out of memory");
-    return -ENOMEM;
-  }
-  memset (dev, 0x00, sizeof (*dev));
-
-  dev->name = (char*)id->driver_info;
-  init_MUTEX (&dev->sem);
-  dev->udev      = udev;
-  dev->interface = interface;
-
-  /* set up the endpoint information */
-  iface_desc = &interface->altsetting[0];
-  if (iface_desc->desc.bNumEndpoints != 2) {
-    kdebug(("Error: number of endpoints is %d (should be 2)", 
-	    iface_desc->desc.bNumEndpoints));
-    goto error;
-  }
-  
-  /* check out the endpoints */
-  /* use only the first bulk-in and bulk-out endpoints */
-  for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
-    endpoint = &iface_desc->endpoint[i].desc;
-
-    if (/* !dev->bulk_in_endpointAddr && */
-	(endpoint->bEndpointAddress & USB_DIR_IN) &&
-	((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-	 == USB_ENDPOINT_XFER_BULK)) {
-      /* we found a bulk in endpoint */
-      if (!dev->bulk_in_endpointAddr) {
-	kdebug(("we found first bulk in endpoint\n"));
-	buffer_size               = endpoint->wMaxPacketSize;
-	dev->bulk_in_size         = buffer_size;
-	dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
-	dev->bulk_in_buffer       = kmalloc(buffer_size, GFP_KERNEL);
-	kdebug(("bulk in endpoint address: %d\n", dev->bulk_in_endpointAddr));
-	if (!dev->bulk_in_buffer) {
-	  err("Couldn't allocate bulk_in_buffer");
-	  goto error;
-	}
-      }
-      else 
-	kdebug(("we found yet another bulk in endpoint!\n"));
-    }
-    else if (/* !dev->bulk_out_endpointAddr && */
-	     !(endpoint->bEndpointAddress & USB_DIR_IN) &&
-	     ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-	      == USB_ENDPOINT_XFER_BULK)) {
-      /* we found a bulk out endpoint */
-      if (!dev->bulk_out_endpointAddr) {
-	/* a probe() may sleep and has no restrictions on memory
-	   allocations */ 
-	dev->write_urb             = usb_alloc_urb(0, GFP_KERNEL);
-	if (!dev->write_urb) {
-	  err("No free urbs available");
-	  goto error;
-	}
-	dev->bulk_out_endpointAddr     = endpoint->bEndpointAddress;
-	buffer_size                    = endpoint->wMaxPacketSize;
-	dev->bulk_out_size             = buffer_size;
-	dev->write_urb->transfer_flags = (URB_NO_TRANSFER_DMA_MAP 
-					  /* | URB_ASYNC_UNLINK*/);
-	dev->bulk_out_buffer           = 
-	  usb_buffer_alloc(udev, buffer_size, GFP_KERNEL,
-			   &dev->write_urb->transfer_dma);
-	if (!dev->bulk_out_buffer) {
-	  err("Couldn't allocate bulk_out_buffer");
-	  goto error;
-	}
-	usb_fill_bulk_urb(dev->write_urb, udev,
-			  usb_sndbulkpipe(udev, endpoint->bEndpointAddress),
-			  dev->bulk_out_buffer, buffer_size,
-			  altro_write_bulk_callback, dev);
-      }
-      else 
-	kdebug(("we found yet another bulk out endpoint!\n"));
-    }
-    else 
-      kdebug(("we found an unidentifiable endpoint!\n"));
-  }
-  if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
-    err("Couldn't find both bulk-in and bulk-out endpoints");
-    goto error;
-  }
-
-  /* allow device read, write and ioctl */
-  dev->present = 1;
-
-  /* we can register the device now, as it is ready */
-  usb_set_intfdata(interface, dev);
-  retval = usb_register_dev(interface, &altro_class);
-  if (retval) {
-    /* something prevented us from registering this driver */
-    err ("Not able to get a minor for this device.");
-    usb_set_intfdata (interface, NULL);
-    goto error;
-  }
-
-  dev->minor = interface->minor;
-  /* _altro = 0; */
-  add_our_device(dev);
-  /* let the user know what node this device is now attached to */
-  info ("USB ALICE ALTRO device now attached to USB ALICE ALTRO-%d", 
-	dev->minor);
-  return 0;
-
- error:
-  altro_delete (dev);
-  return retval;
-}
-
-
-/*__________________________________________________________________*/
-/** Called by the Usb core when the device is removed from the
- *  system (the plug is pulled out, or the reset switch is pushed on
- *  the board, or the power is cut to the board). 
- *
- *  This routine guarantees that the driver will not submit any more
- *  URBS by clearing dev->udev.  It is also supposed to terminate any
- *  currently active urbs.  Unfortunately, @c usb_bulk_msg(), used in
- *  @c altro_read(), does not provide any way to do this.  But at least
- *  we can cancel an active write.
- *
- *  @param interface The interface that was disconnected. 
- *  @ingroup altro_driver 
- */
-static void 
-altro_disconnect(struct usb_interface *interface)
-{
-  struct altro_device *dev;
-  int minor;
-
-  /* prevent races with open() */
-  down(&disconnect_sem);
-
-  dev = usb_get_intfdata(interface);
-  usb_set_intfdata(interface, NULL);
-
-  down(&dev->sem);
-  remove_our_device(dev);
-  
-  minor = dev->minor;
-
-  /* give back our minor */
-  usb_deregister_dev(interface, &altro_class);
-
-  /* terminate an ongoing write */
-  if (atomic_read(&dev->write_busy)) {
-    usb_unlink_urb(dev->write_urb);
-    wait_for_completion(&dev->write_finished);
-  }
-
-  /* prevent device read, write and ioctl */
-  dev->present = 0;
-
-  up(&dev->sem);
-
-  /* if the device is opened, altro_release will clean this up */
-  if (!dev->open)
-    altro_delete(dev);
-
-  up (&disconnect_sem);
-
-  info("USB ALICE ALTRO #%d now disconnected", minor);
-}
-
-/*********************************************************************/
-/** User writing to the ALTRO proc entry 
- *  @param file The file descriptor
- *  @param buffer Buffer of @a count size 
- *  @param count The size of buffer (max 99)
- *  @param data The data 
- *  @ingroup altro_driver 
- *  @return  
- */
-static int 
-altro_proc_write(struct file *file, const char *buffer, 
-	       unsigned long count, void *data)
-{
-  int len;
-  struct altro_proc_data_t *fb_data = (struct altro_proc_data_t *)data;
-  
-  kdebug(("user is writing to /proc/altro\n"));
-
-  if(count > 99) len = 99;
-  else           len = count;
-
-  if (copy_from_user(fb_data->value, buffer, len)) {
-    kdebug(("error when copying from user\n"));
-    return(-EFAULT);
-  }
-
-  kdebug(("length is %d\n", len));
-  fb_data->value[len - 1] = '\0';
-  kdebug(("text passed is \"%s\"\n", fb_data->value));
- 
-  if (!strcmp(fb_data->value, "debug")) {
-    debug = 1;
-    kdebug(("debugging enabled\n")); 
-  }
- 
-  if (!strcmp(fb_data->value, "nodebug")) {
-    kdebug(("debugging disabled\n")); 
-    debug = 0; 
-  }
-  
-  if (!strcmp(fb_data->value, "dec")) {
-    module_put(THIS_MODULE);
-    /* MOD_DEC_USE_COUNT; */
-    kdebug(("Use count decremented\n"));
-  }
-
-  if (!strcmp(fb_data->value, "inc")) {
-    try_module_get(THIS_MODULE);
-    /* MOD_INC_USE_COUNT; */
-    kdebug(("Use count incremented\n"));
-  }
-  return len;
-}
-
-/*__________________________________________________________________*/
-/** User Reading from the ALTRO proc entry
- *  @param page   Page to read into 
- *  @param start  Points to begining of text on output
- *  @param off    Points to offset of the text in the page 
- *  @param count  Size of page 
- *  @param eof    Wheter to set end of file 
- *  @param data   The data 
- *  @ingroup altro_driver 
- *  @return The length 
- */
-static int
-altro_proc_read(char *page, char **start, off_t off, 
-	      int count, int *eof, void *data)
-{
-  int len;
-  u_int i;
-  
-  kdebug(("user is reading /proc/altro\n"));
-
-  len =  sprintf(page, "ALICE USB-ALTRO driver\n\n");
-  len += sprintf(page + len, "Minor device number:\t0x%x\n", 
-		 USB_ALTRO_MINOR_BASE);
-  len += sprintf(page + len, "Vendor/product ID:\t0x%x/0x%x\n\n", 
-		 USB_ALTRO_VENDOR_ID, USB_ALTRO_PRODUCT_ID);
-  for (i = 0; i < n_our_devices; i++) {
-    len += sprintf(page + len, "\tDevice:\t %s (0x%x)\n", 
-		   our_devices[i]->name, our_devices[i]->minor);
-  }
-  len += sprintf(page + len, " \n");
-  len += sprintf(page + len, "The command 'echo <action> > /proc/altro', "
-		 "executed as root,\n");
-  len += sprintf(page + len, "allows you to interact with the driver. "
-		 "Possible actions are:\n");
-  len += sprintf(page + len, "debug   -> enable debugging\n");
-  len += sprintf(page + len, "nodebug -> disable debugging\n");
-  len += sprintf(page + len, "dec     -> Decrement use count\n");
-  len += sprintf(page + len, "inc     -> Increment use count\n");
-
-  *eof = 1;
-  *start = page + off;
-  len -= off;
-
-  if (len > count) len = count;
-  return (len);
-}
-
-/*__________________________________________________________________*/
-/** Function called when the driver is loaded. 
- *  @return 0 on success or error code otherwise 
- *  @ingroup altro_driver 
- */
-static int __init 
-usb_altro_init(void)
-{
-  int result;
-  // Install `/proc' entry 
-  altro_proc_file = create_proc_entry("altro", 0644, NULL);
-  if (altro_proc_file == NULL) {
-    err("create_proc_entry failed");
-    return -ENOMEM;
-  }
-  strcpy(altro_proc_data.name, "altro");
-  strcpy(altro_proc_data.value, "altro");
-  altro_proc_file->data       = &altro_proc_data;
-  altro_proc_file->read_proc  = altro_proc_read;
-  altro_proc_file->write_proc = altro_proc_write;
-  altro_proc_file->owner      = THIS_MODULE;
-
-  /* register this driver with the USB subsystem */
-  result = usb_register(&altro_driver);
-  if (result) {
-    err("usb_register failed. Error number %d", result);
-    return result;
-  }
-  
-  info(DRIVER_DESC " " DRIVER_VERSION);
-  info("ALTRO: debug is %d", debug);
-  return 0;
-}
-
-
-/*__________________________________________________________________*/
-/** Function called when the driver is unloaded via @c rmmod or
- *  otherwise.
- *  @ingroup altro_driver 
- */
-static void __exit 
-usb_altro_exit(void)
-{
-  /* deregister this driver with the PROC subsystem */
-  remove_proc_entry("altro", NULL);
-  
-  /* deregister this driver with the USB subsystem */
-  usb_deregister(&altro_driver);
-}
-  
-/*__________________________________________________________________*/
-module_init(usb_altro_init);
-module_exit(usb_altro_exit);
-// int init_module() 
-// {
-//   return usb_altro_init();
-// }
-// void cleanup_module() 
-// {
-//   usb_altro_exit();
-// }
-
-
-/*__________________________________________________________________*/
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-/*__________________________________________________________________
- *
- * EOF
- */
diff -u -r -N -xCVS u2f.cern/altro/unused_24.c u2f/altro/unused_24.c
--- u2f.cern/altro/unused_24.c	2005-03-20 08:45:12.000000000 +0100
+++ u2f/altro/unused_24.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,424 +0,0 @@
-/*********************************************************************
- *
- * Prototypes 
- */
-static void rcu_irq(struct urb *urb);
-static void rcu_write_irq(struct urb *urb);
-static void rcu_read_irq(struct urb *urb);
-
-/*********************************************************************
- * 
- * Handler for data sent in by the device. The function is called by
- * the USB kernel subsystem whenever a device spits out new data 
- */
-static void rcu_irq(struct urb *urb)
-{
-  struct rcu_device *rcu = urb->context;
-  char *pos = rcu->output;
-  int i;
-  
-  kdebug(("rcu_drv(rcu_irq): function called\n"));
-  
-  if (urb->status != USB_ST_NOERROR) { 
-    kdebug(("rcu_drv(rcu_irq): ERROR urb->status != USB_ST_NOERROR\n"));
-    return;
-  }
-
-  pos += sprintf(pos, "rcu: data from %-8s =", rcu->name);
-  for (i=0; i<rcu->maxp; i++) 
-    pos += sprintf(pos, " %02x", rcu->data[i]);
-  
-  kdebug(("rcu_drv(rcu_irq): %s\n", rcu->output));
-}
-
-
-/*********************************************************************
- * 
- * Handler for error checking after data das been sent out to the device 
- */
-static void rcu_write_irq(struct urb *urb)
-{
-  struct rcu_device *rcu = (struct rcu_device *)urb->context;
-
-  kdebug(("rcu_drv(rcu_write_irq): function called\n"));
-
-  //usb-skeleton: if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) 
-  if (urb->status) {
-    kdebug(("rcu_drv(rcu_write_irq): nonzero write bulk status received: %d\n",  urb->status));
-    return;
-  }
-
-  urbdone = 1;
-  kdebug(("rcu_drv(rcu_write_irq): function done\n"));
-  return;
-}
-
-
-/*********************************************************************
- * 
- * Handler for error checking after data das been sent out to the
- * device 
- */
-static void rcu_read_irq(struct urb *urb)
-{
-  struct rcu_device *rcu = (struct rcu_device *)urb->context;
-
-  kdebug(("rcu_drv(rcu_read_irq): function called\n"));
-
-  if (urb->status) {
-    kdebug(("rcu_drv(rcu_read_irq): nonzero write bulk status received: %d\n",  urb->status));
-    return;
-  }
-
-  urbdone = 1;
-  kdebug(("rcu_drv(rcu_read_irq): function done\n"));
-  return;
-}
-
-/*********************************************************************
- * 
- * These two callbacks are invoked when an USB device is detached or
- * attached to the bus
- */ 
-static void *rcu_probe(struct usb_device *udev, unsigned int ifnum, 
-		       const struct usb_device_id *id)
-{
-  /* The probe procedure is pretty standard. Device matching has already */
-  /* been performed based on the id_table structure */
-
-  struct usb_interface *iface;
-  struct usb_interface_descriptor *interface;
-  struct usb_endpoint_descriptor *endpoint;
-  struct rcu_device *rcu;
-  char name[10];
-  int ecode, i, buffer_size, inok, outok;
-
-  kdebug(("rcu_drv(rcu_probe): probe called for %s device\n", (char *)id->driver_info));
-  kdebug(("rcu_drv(rcu_probe): ifnum = %d\n", ifnum));
-
-  /* allocate and zero a new data structure for the new device */
-  rcu = kmalloc(sizeof(struct rcu_device), GFP_KERNEL);
-  if (!rcu) { 
-    kdebug(("rcu_drv(rcu_probe): ERROR failed to kmalloc rcu_device\n"));
-    return NULL; /* failure */
-  }
-  
-  memset(rcu, 0, sizeof(*rcu));
-  rcu->name = (char *)id->driver_info;
-  init_MUTEX(&rcu->sem);
-
-  iface = &udev->actconfig->interface[ifnum];
-  interface = &iface->altsetting[iface->act_altsetting];
-
-  if (interface->bNumEndpoints != 2) {
-    kdebug(("rcu_drv(rcu_probe): ERROR interface->bNumEndpoints "
-	    "!= 3 (number = %d)\n", interface->bNumEndpoints));
-    return NULL;
-  }
-  
-  inok = 0;
-  outok = 0;
-    
-  for (i = 0; i < interface->bNumEndpoints; ++i) {
-    kdebug(("rcu_drv(rcu_probe): Processing endpoint %d ...\n", i));
-    endpoint = &interface->endpoint[i];
-    
-    if ((endpoint->bEndpointAddress & 0x80) && 
-	((endpoint->bmAttributes & 3) == 0x02)) {
-      if (!inok) {
-        kdebug(("rcu_drv(rcu_probe): we found the first bulk in endpoint\n"));
-	buffer_size = endpoint->wMaxPacketSize;
-	kdebug(("rcu_drv(rcu_probe): buffer_size = %d\n", buffer_size));
-	rcu->bulk_in_size = buffer_size;
-	rcu->bulk_in_endpointAddr = endpoint->bEndpointAddress;
-	kdebug(("rcu_drv(rcu_probe): bulk_in_endpointAddr = %d\n", rcu->bulk_in_endpointAddr));
-	rcu->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
-	if (!rcu->bulk_in_buffer) {
-          kdebug(("rcu_drv(rcu_probe): Couldn't allocate bulk_in_buffer"));
-          return NULL;
-	}
-	inok = 1;
-      }
-      else
-        kdebug(("rcu_drv(rcu_probe): we found another bulk in endpoint\n"));
-    }
-    
-    else if (((endpoint->bEndpointAddress & 0x80) == 0x00) && 
-	     ((endpoint->bmAttributes & 3) == 0x02)) {
-      if (!outok) {
-	kdebug(("rcu_drv(rcu_probe): we found the first bulk out endpoint\n"));
-	rcu->write_urb = usb_alloc_urb(0);
-	if (!rcu->write_urb) {
-          kdebug(("rcu_drv(rcu_probe): No free urbs available"));
-          return NULL;
-	}
-	buffer_size = endpoint->wMaxPacketSize;
-	kdebug(("rcu_drv(rcu_probe): buffer_size = %d\n", buffer_size));
-	rcu->bulk_out_size = buffer_size;
-	rcu->bulk_out_endpointAddr = endpoint->bEndpointAddress;
-	kdebug(("rcu_drv(rcu_probe): bulk_out_endpointAddr = %d\n", rcu->bulk_out_endpointAddr));
-	rcu->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
-	if (!rcu->bulk_out_buffer) {
-          kdebug(("rcu_drv(rcu_probe): Couldn't allocate bulk_out_buffer"));
-          return NULL;
-	}
-	outok = 1;
-      }	
-
-      else
-        kdebug(("rcu_drv(rcu_probe): we found another bulk out endpoint\n"));
-    }
-    else
-      {
-	kdebug(("rcu_drv(rcu_probe): we found an unidentifiable endpoint\n"));
-	return NULL;
-    }
-  }
-  
-  kdebug(("rcu_drv(rcu_probe): Setting protocol\n"));
-  usb_set_protocol(udev, interface->bInterfaceNumber, 0);
-  kdebug(("rcu_drv(rcu_probe): Setting idle\n"));
-  usb_set_idle(udev, interface->bInterfaceNumber, 0, 0);
-  
-  kdebug(("rcu_drv(rcu_probe): Preparing URB\n"));
-  /* fill the URB data structure using the FILL_INT_URB macro */
-  {
-    int pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
-    int maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
-    kdebug(("rcu_drv(rcu_probe): pipe = %d\n", pipe));
-    kdebug(("rcu_drv(rcu_probe): maxp = %d\n", maxp));
-    
-    if (maxp > 512) maxp = 512; 
-    rcu->maxp = maxp; /* remember for later */
-    kdebug(("rcu_drv(rcu_probe): maxp(2) = %d\n", maxp));
-    kdebug(("rcu_drv(rcu_probe): endpoint->bInterval = %d\n", endpoint->bInterval));
-    FILL_INT_URB(&rcu->urb, udev, pipe, rcu->data, maxp, rcu_irq, rcu, endpoint->bInterval);
-  }
-  
-  kdebug(("rcu_drv(rcu_probe): Registering URB\n"));
-  /* register the URB within the USB subsystem */
-  ecode = usb_submit_urb(&rcu->urb);
-  if (ecode) {
-    kfree(rcu);
-    kdebug(("rcu_drv(rcu_probe): ERROR  failed to register URB (ecode = %d)\n", ecode));
-    return NULL;
-  }
-  kdebug(("rcu_drv(rcu_probe): Probe successful for %s (maxp is %i)\n", rcu->name, rcu->maxp));
-  
-  rcu->udev = udev;
-
-
-  //  This code is from the usb-skeleton.c template. It seems however,
-  //  that CERN Linux kernels do not offer the CONFIG_DEVFS_FS
-  //  option. Therefore we cannot use it
-
-  /* initialize the devfs node for this device and register it */
-  sprintf(name, "rcu");
-  /* MJ: So far we can only support one RCU card. For multiple cards
-     the node name has to have an occurence number */
-  kdebug(("rcu_drv(rcu_probe): calling devfs_register\n"));
-  rcu->devfs = devfs_register (usb_devfs_handle, name, 
-			       DEVFS_FL_DEFAULT, USB_MAJOR, 
-			       RCU_MINOR_BASE + rcu->minor,
-			       S_IFCHR | S_IRUSR | S_IWUSR | 
-			       S_IRGRP | S_IWGRP | S_IROTH, 
-			       &rcu_fops, NULL);
-  kdebug(("rcu_drv(rcu_probe): devfs_register done\n"));
-  /* let the user know what node this device is now attached to */
-  kdebug(("rcu_drv(rcu_probe): RCU device now attached to "
-	  "major number=%d, minor number=%d\n", 
-	  USB_MAJOR, RCU_MINOR_BASE + rcu->minor));
-
-  rcu->test = 1; 
-  rcup = rcu;
-  kdebug(("rcu_drv(rcu_probe): End of function\n"));
-  
-  return rcu;
-}
-
-/*********************************************************************
- * 
- */ 
-static int rcu_ioctl (struct inode *inode, struct file *file, 
-		      unsigned int cmd, unsigned long arg)
-{
-  struct rcu_device *rcu;
-  int pipe, maxp, retval;
-  
-  kdebug(("rcu_drv(rcu_ioctl): function called\n")); 
-  kdebug(("rcu_drv(rcu_ioctl): minor number = %d\n", MINOR (inode->i_rdev)));
-
-  rcu = (struct rcu_device *)file->private_data;
-  kdebug(("rcu_drv(rcu_ioctl): rcu->test = %d\n", rcu->test)); 
-
-  /* lock this object */
-  down (&rcu->sem);
-  kdebug(("rcu_drv(rcu_ioctl): semaphore locked\n")); 
-
-  /* verify that the device wasn't unplugged */
-  if (rcu->udev == NULL) 
-  {
-    up (&rcu->sem);
-    kdebug(("rcu_drv(rcu_ioctl): ERROR device was unplugged\n"));
-    return -ENODEV;
-  }
-  kdebug(("rcu_drv(rcu_ioctl): The device is still connected\n")); 
-
-  switch (cmd)
-  {    
-  case SEND_DATA: {
-    rcu_bulk_out_t params;
-    
-    kdebug(("rcu_drv(ioctl:SEND_DATA): start of function\n"));
-    kdebug(("rcu_drv(ioctl:SEND_DATA): function called for endpoint "
-	    "0x%08x\n", rcu->bulk_out_endpointAddr));
-    
-     /* see if we are already in the middle of a write */
-     if (rcu->write_urb->status == -EINPROGRESS) {
-       kdebug(("rcu_drv(ioctl:SEND_DATA): the BULK out URB is in use\n"));
-       up (&rcu->sem);
-       return(-RCU_EFAULT);
-     }
-
-     if (copy_from_user(&params, (void *)arg, 
-			sizeof(rcu_bulk_out_t)) !=0 ) {
-       kdebug(("rcu_drv(ioctl:SEND_DATA): error from " "copy_from_user\n"));
-       up (&rcu->sem);
-       return(-RCU_EFAULT);
-     }
-
-     /* set up our urb */
-     pipe = usb_sndbulkpipe(rcu->udev, rcu->bulk_out_endpointAddr);
-     maxp = usb_maxpacket(rcu->udev, pipe, usb_pipeout(pipe));
-     
-     if (maxp > rcu->bulk_out_size) maxp = rcu->bulk_out_size; 
-     rcu->maxp = maxp; /* remember for later */
-     kdebug(("rcu_drv(ioctl:SEND_DATA): it is possible to send %d bytes\n", 
-	     maxp));
-    
-     /* check if we would write more data than possible */
-     if (params.nbytes > maxp) {	
-       kdebug(("rcu_drv(ioctl:SEND_DATA): Cannot write %d bytes to "
-	       "pipe of %d bytes\n", params.nbytes, maxp));
-       up (&rcu->sem);
-       return(-RCU_EFAULT);
-     }
-     kdebug(("rcu_drv(ioctl:SEND_DATA): trying to send %d bytes\n", 
-	     params.nbytes));
-     kdebug(("rcu_drv(ioctl:SEND_DATA): dumping first four bytes\n"));
-     kdebug(("rcu_drv(ioctl:SEND_DATA): 1. byte = 0x%02x\n", params.data[0]));
-     kdebug(("rcu_drv(ioctl:SEND_DATA): 2. byte = 0x%02x\n", params.data[1]));
-     kdebug(("rcu_drv(ioctl:SEND_DATA): 3. byte = 0x%02x\n", params.data[2]));
-     kdebug(("rcu_drv(ioctl:SEND_DATA): 4. byte = 0x%02x\n", params.data[3]));
-     
-     usb_fill_bulk_urb(&rcu->urb, rcu->udev, pipe, &params.data[0], 
-		       params.nbytes, rcu_write_irq, rcu);
-     kdebug(("rcu_drv(ioctl:SEND_DATA): URB has beed filled\n"));
-     
-     /* register the URB within the USB subsystem */
-     retval = usb_submit_urb(&rcu->urb); 
-     if (retval) {
-       kdebug(("rcu_drv(ioctl:SEND_DATA): ERROR  failed to register URB. "
-	       "Error code = %d\n", retval));
-       up (&rcu->sem);
-       return(-RCU_EFAULT);
-     }
-     kdebug(("rcu_drv(ioctl:SEND_DATA): URB has beed submitted\n"));
-     break;
-  }
-  case GET_DATA: {   
-    rcu_bulk_in_t params;
-    
-    kdebug(("rcu_drv(ioctl:GET_DATA): start of function\n"));
-    kdebug(("rcu_drv(ioctl:GET_DATA): function called for endpoint "
-	    "0x%08x\n", rcu->bulk_in_endpointAddr));
-    
-    /* see if we are already in the middle of a write */
-    if (rcu->read_urb->status == -EINPROGRESS)  {
-      kdebug(("rcu_drv(ioctl:GET_DATA): the BULK in URB is in use\n"));
-      up (&rcu->sem); 
-      return(-RCU_EFAULT);
-    }
-
-    /* set up our urb */
-    pipe = usb_rcvbulkpipe(rcu->udev, rcu->bulk_in_endpointAddr);
-    maxp = usb_maxpacket(rcu->udev, pipe, usb_pipeout(pipe));
-    
-    if (maxp > rcu->bulk_in_size) 
-      maxp = rcu->bulk_in_size; 
-    rcu->maxp = maxp; /* remember for later */
-    kdebug(("rcu_drv(ioctl:GET_DATA): it is possible to receive %d bytes\n", 
-	    maxp));
-
-    usb_fill_bulk_urb(&rcu->urb, rcu->udev, pipe, &params.data[0], 
-		      BULK_IN_SIZE, rcu_read_irq, rcu);
-    kdebug(("rcu_drv(ioctl:GET_DATA): URB has beed filled\n"));
-     
-    /* register the URB within the USB subsystem */
-    retval = usb_submit_urb(&rcu->urb); 
-    if (retval) {
-      kdebug(("rcu_drv(ioctl:GET_DATA): ERROR  failed to register "
-	      "URB. Error code = %d\n", retval));
-      params.nbytes = 0;
-      up (&rcu->sem);
-      return(-RCU_EFAULT);
-    }
-    kdebug(("rcu_drv(ioctl:GET_DATA): URB has beed submitted\n"));
-
-    /// MJ: How does one best detect the end of a transfer?
-    kdebug(("rcu_drv(ioctl:GET_DATA): URB has beed completed\n"));
-    if (copy_to_user ((void *)arg, &params, 
-		      sizeof(rcu_bulk_in_t)) != 0)  {
-       kdebug(("rcu_drv(ioctl:GET_DATA): error from copy_to_user\n"));
-       up (&rcu->sem);
-       return(-RCU_EFAULT);
-    }
-    kdebug(("rcu_drv(ioctl:GET_DATA): data has been copied\n"));
-    
-    break;          
-  }    
-  case CONTROL: {
-    rcu_control_t params;
-    
-    kdebug(("rcu_drv(ioctl:CONTROL): function called\n"));
-    
-    if (copy_from_user(&params, (void *)arg, sizeof(rcu_control_t)) !=0 )  {
-      kdebug(("rcu_drv(ioctl:CONTROL): error from copy_from_user\n"));
-      up (&rcu->sem);
-      return(-RCU_EFAULT);
-    }
-
-    kdebug(("rcu_drv(ioctl:CONTROL): params.bRequest      = %d\n", 
-	    params.bRequest));
-    kdebug(("rcu_drv(ioctl:CONTROL): params.bmRequestType = %d\n", 
-	    params.bmRequestType));
-    kdebug(("rcu_drv(ioctl:CONTROL): params.wValue        = %d\n", 
-	    params.wValue));
-    kdebug(("rcu_drv(ioctl:CONTROL): params.wIndex        = %d\n", 
-	    params.wIndex));
-    kdebug(("rcu_drv(ioctl:CONTROL): params.data[0]       = %d\n", 
-	    params.data[0]));
-    kdebug(("rcu_drv(ioctl:CONTROL): params.wLength       = %d\n", 
-	    params.wLength));
-    
-    retval = usb_control_msg(rcu->udev, usb_rcvctrlpipe(rcu->udev,0), 
-			     params.bRequest, 
-			     params.bmRequestType, 
-			     params.wValue, 
-			     params.wIndex, 
-			     &params.data[0], 
-			     params.wLength, HZ);
-    if (retval) {
-      kdebug(("rcu_drv(ioctl:CONTROL): ERROR  failed to register control URB. "
-	      "Error code = %d\n", retval));
-      up (&rcu->sem);
-      return(-RCU_EFAULT);
-    }
-    break;
-  }
-  }
-  
-  /* unlock the device */
-  up (&rcu->sem);
-  return(0);
-}
diff -u -r -N -xCVS u2f.cern/altro/unused_26.c u2f/altro/unused_26.c
--- u2f.cern/altro/unused_26.c	2005-03-20 08:45:12.000000000 +0100
+++ u2f/altro/unused_26.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,275 +0,0 @@
-//____________________________________________________________________
-/* local function prototypes */
-static ssize_t alice_rcu_read(struct file *file, char *buffer, 
-			      size_t count, loff_t *ppos);
-static ssize_t alice_rcu_write(struct file *file, const char *buffer, 
-			       size_t count, loff_t *ppos);
-static void alice_rcu_write_bulk_callback(struct urb *urb, 
-					  struct pt_regs *regs);
-
-
-//____________________________________________________________________
-/*
- * File operations needed when we register this driver.
- * This assumes that this driver NEEDS file operations,
- * of course, which means that the driver is expected
- * to have a node in the /dev directory. If the USB
- * device were for a network interface then the driver
- * would use "struct net_driver" instead, and a serial
- * device would use "struct tty_driver".
- */
-static struct file_operations alice_rcu_fops = {
-  /*
-   * The owner field is part of the module-locking
-   * mechanism. The idea is that the kernel knows
-   * which module to increment the use-counter of
-   * BEFORE it calls the device's open() function.
-   * This also means that the kernel can decrement
-   * the use-counter again before calling release()
-   * or should the open() function fail.
-   */
-  .read =	alice_rcu_read,
-  .write =	alice_rcu_write,
-};
-
-//____________________________________________________________________
-/**
- * usb_alice_rcu_debug_data
- */
-static inline void 
-usb_alice_rcu_debug_data(const char *function, int size, 
-			 const unsigned char *data)
-{
-  int i;
-  if (!debug) return;
-  printk(KERN_DEBUG __FILE__": %s - length = %d, data = ", function, size);
-  for (i = 0; i < size; ++i) printk ("%.2x ", data[i]);
-  printk ("\n");
-}
-
-
-//____________________________________________________________________
-/**
- * alice_rcu_read
- */
-static ssize_t 
-alice_rcu_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
-{
-  struct usb_alice_rcu *dev;
-  int retval = 0;
-
-  dev = (struct usb_alice_rcu *)file->private_data;
-  kdebug(("minor %d, count = %d", dev->minor, count));
-
-  /* lock this object */
-  down (&dev->sem);
-
-  /* verify that the device wasn't unplugged */
-  if (!dev->present) {
-    kdebug(("Error: Device was unplugged!\n"));
-    up (&dev->sem);
-    return -ENODEV;
-  }
-
-  /* do a blocking bulk read to get data from the device */
-  retval = usb_bulk_msg(dev->udev,
-			usb_rcvbulkpipe (dev->udev, dev->bulk_in_endpointAddr),
-			dev->bulk_in_buffer,
-			min (dev->bulk_in_size, count),
-			&count, HZ*10);
-
-  /* if the read was successful, copy the data to userspace */
-  if (!retval) {
-    if (copy_to_user (buffer, dev->bulk_in_buffer, count))
-      retval = -EFAULT;
-    else
-      retval = count;
-  }
-
-  /* unlock the device */
-  up (&dev->sem);
-  return retval;
-}
-
-
-//____________________________________________________________________
-/**
- *	alice_rcu_write
- *
- *	A device driver has to decide how to report I/O errors back to
- *	the user.  The safest course is to wait for the transfer to
- *	finish before returning so that any errors will be reported
- *	reliably.  alice_rcu_read() works like this.  But waiting for
- *	I/O is slow, so many drivers only check for errors during I/O
- *	initiation and do not report problems that occur during the
- *	actual transfer.  That's what we will do here.
- *
- *	A driver concerned with maximum I/O throughput would use
- *	double- buffering: Two urbs would be devoted to write
- *	transfers, so that one urb could always be active while the
- *	other was waiting for the user to send more data.
- */
-static ssize_t 
-alice_rcu_write(struct file *file, const char *buffer, 
-		size_t count, loff_t *ppos)
-{
-  struct usb_alice_rcu *dev;
-  ssize_t bytes_written = 0;
-  int retval = 0;
-
-  dev = (struct usb_alice_rcu *)file->private_data;
-  kdebug(("minor %d, count = %d\n", dev->minor, count));
-
-  /* lock this object */
-  down (&dev->sem);
-
-  /* verify that the device wasn't unplugged */
-  if (!dev->present) {
-    kdebug(("Error: Device was unplugged!\n"));
-    retval = -ENODEV;
-    goto exit;
-  }
-
-  /* verify that we actually have some data to write */
-  if (count == 0) {
-    kdebug(("write request of 0 bytes\n"));
-    goto exit;
-  }
-
-  /* wait for a previous write to finish up; we don't use a timeout
-   * and so a nonresponsive device can delay us indefinitely.
-   */
-  if (atomic_read (&dev->write_busy))
-    wait_for_completion (&dev->write_finished);
-
-  /* we can only write as much as our buffer will hold */
-  bytes_written = min (dev->bulk_out_size, count);
-
-  /* copy the data from userspace into our transfer buffer;
-   * this is the only copy required.
-   */
-  if (copy_from_user(dev->write_urb->transfer_buffer, buffer,
-		     bytes_written)) {
-    retval = -EFAULT;
-    goto exit;
-  }
-
-  usb_alice_rcu_debug_data (__FUNCTION__, bytes_written,
-			    dev->write_urb->transfer_buffer);
-
-  /* this urb was already set up, except for this write size */
-  dev->write_urb->transfer_buffer_length = bytes_written;
-
-  /* send the data out the bulk port */
-  /* a character device write uses GFP_KERNEL,
-     unless a spinlock is held */
-  init_completion (&dev->write_finished);
-  atomic_set (&dev->write_busy, 1);
-  retval = usb_submit_urb(dev->write_urb, GFP_KERNEL);
-  if (retval) {
-    atomic_set (&dev->write_busy, 0);
-    err("%s - failed submitting write urb, error %d",
-	__FUNCTION__, retval);
-  } else {
-    retval = bytes_written;
-  }
-
- exit:
-  /* unlock the device */
-  up (&dev->sem);
-
-  return retval;
-}
-
-//____________________________________________________________________
-/**
- *	alice_rcu_write_bulk_callback
- */
-static void 
-alice_rcu_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
-{
-  struct usb_alice_rcu *dev = (struct usb_alice_rcu *)urb->context;
-
-  kdebug(("minor %d\n", dev->minor));
-
-  /* sync/async unlink faults aren't errors */
-  if (urb->status && !(urb->status == -ENOENT ||
-		       urb->status == -ECONNRESET)) {
-    kdebug(("nonzero write bulk status received: %d", urb->status));
-  }
-  
-  /* notify anyone waiting that the write has finished */
-  atomic_set (&dev->write_busy, 0);
-  complete (&dev->write_finished);
-}
-
-//____________________________________________________________________
-/** Handler for data sent in by the device. The function is called by  
-    the USB kernel subsystem whenever a device spits out new data
-    @param urb 
-*/
-static void rcu_irq(struct urb *urb)
-{
-  struct rcu_device *rcu = urb->context;
-  char *pos = rcu->output;
-  int i;
-  
-  kdebug(("rcu_drv(rcu_irq): function called\n"));
-
-  if (urb->status != USB_ST_NOERROR) { 
-    kdebug(("rcu_drv(rcu_irq): ERROR urb->status != USB_ST_NOERROR\n"));
-    return;
-  }
-
-  pos += sprintf(pos, "rcu: data from %-8s =", rcu->name);
-  for (i=0; i<rcu->maxp; i++) 
-    pos += sprintf(pos, " %02x", rcu->data[i]);
-  
-  kdebug(("rcu_drv(rcu_irq): %s\n", rcu->output));
-}
-
-//____________________________________________________________________
-/** Handler for error checking after data das been sent out to the
-    device  
-    @param urb 
-*/
-static void rcu_write_irq(struct urb *urb)
-{
-  struct rcu_device *rcu = (struct rcu_device *)urb->context;
-
-  kdebug(("rcu_drv(rcu_write_irq): function called\n"));
-
-  //usb-skeleton: 
-  //   if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) 
-  if (urb->status) {
-    kdebug(("rcu_drv(rcu_write_irq): nonzero write bulk status received: %d\n",
-	    urb->status));
-    return;
-  }
-  
-  urbdone = 1;
-  kdebug(("rcu_drv(rcu_write_irq): function done\n"));
-  return;
-}
-
-
-//____________________________________________________________________
-/** Handler for error checking after data das been sent out to the
-    device  
-    @param urb  */
-static void rcu_read_irq(struct urb *urb)
-{
-  struct rcu_device *rcu = (struct rcu_device *)urb->context;
-  
-  kdebug(("rcu_drv(rcu_read_irq): function called\n"));
-  
-  if (urb->status) {
-    kdebug(("rcu_drv(rcu_read_irq): nonzero write bulk status received: %d\n",
-	    urb->status));
-    return;
-  }
-  
-  urbdone = 1;
-  kdebug(("rcu_drv(rcu_read_irq): function done\n"));
-  return;
-}
diff -u -r -N -xCVS u2f.cern/autogen.sh u2f/autogen.sh
--- u2f.cern/autogen.sh	1970-01-01 01:00:00.000000000 +0100
+++ u2f/autogen.sh	2006-01-27 01:32:44.000000000 +0100
@@ -0,0 +1,150 @@
+#!/usr/bin/make -f
+# -*- mode: makefile -*- 
+# $Id: autogen.sh,v 1.1.1.1 2006/01/26 03:03:42 cholm Exp $
+#
+#   General C++ parser and lexer
+#   Copyright (C) 2002  Christian Holm Christensen <cholm@nbi.dk>
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public License 
+#   as published by the Free Software Foundation; either version 2 of 
+#   the License, or (at your option) any later version.  
+#
+#   This library 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
+#   Lesser General Public License for more details. 
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free
+#   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+#   MA 02111-1307  USA  
+#
+CXX		= g++
+CC		= gcc
+PREFIX		= $(HOME)/tmp
+CONFFLAGS	= --prefix=$(PREFIX) 
+PACKAGE		:= $(strip $(shell grep AC_INIT configure.ac |\
+			sed 's/.*([^,]*,\([^,]*\),[^,]*,\(.*\)).*/\2/'))
+VERSION		:= $(strip $(shell grep AC_INIT configure.ac |\
+			sed 's/.*([^,]*,\([^,]*\),[^,]*,\(.*\)).*/\1/'))
+AUTOMAKEVERSION := -1.9
+
+all:	setup
+	./configure 
+
+config/ltmain.sh:
+	libtoolize --automake 
+
+aclocal.m4: configure.ac config/ltmain.sh
+	aclocal$(AUTOMAKEVERSION) -I . 
+
+Makefile.in:	Makefile.am aclocal.m4
+	automake$(AUTOMAKEVERSION) --add-missing --copy 
+
+configure:	Makefile.in 
+	autoconf 
+
+setup: 	configure 
+
+make:	all
+	$(MAKE) -f Makefile 
+
+ChangeLog:
+	rm -f $@
+	touch $@
+	rcs2log > $@
+
+dists:  
+	$(MAKE) dist
+	$(MAKE) tar-ball -C doc
+
+
+show:
+	@echo "$(PACKAGE) version $(VERSION)"
+clean: 
+	find . -name "*~" 		| xargs rm -f 
+	find . -name core 		| xargs rm -f 
+	find . -name .libs 		| xargs rm -rf 
+	find . -name .deps 		| xargs rm -rf 
+	find . -name "*.lo" 		| xargs rm -f 
+	find . -name "*.o" 		| xargs rm -f 
+	find . -name "*.la" 		| xargs rm -f
+	find . -name "*.log" 		| xargs rm -f
+	find . -name "TAGS" 		| xargs rm -f
+	find . -name "semantic.cache" 	| xargs rm -f
+	find . -name "Makefile" 	| xargs rm -f 
+	find . -name "Makefile.in" -a \
+	  -not -wholename "./driver/Makefile.in" | xargs rm -f 
+
+	rm -f 	driver/altro_driver.ko		\
+		driver/altro_driver.kmod	\
+		driver/altro_driver.mod		\
+		driver/altro_driver.mod.c	\
+		driver/altro_driver.c		\
+		driver/rcu_common.h		\
+		driver/.altro_driver.*		\
+		scripts/altro			\
+		scripts/altro-config	
+
+	rm -f 	altro/altroscope		\
+		goofie/goofiescope		\
+		u2f/read_fec_fm			\
+		u2f/u2f_acq			\
+		u2f/u2fscope			\
+		u2f/write_fec_fm		
+
+	rm -f 	config/missing       	\
+	  	config/mkinstalldirs 	\
+	  	config/ltmain.sh     	\
+	  	config/config.guess 	\
+		config/config.rpath	\
+		config/config.sub 	\
+		config/depcomp		\
+		config/install-sh 	\
+		config/ltconfig 	\
+		config/config.hh 	\
+		config/config.hh.in 	\
+		config/stamp-h		\
+		config/stamp-h.in	\
+		config/stamp-h1	
+
+	rm -rf 	aclocal.m4 		\
+		autom4te.cache		\
+		config.cache 		\
+		config.status  		\
+		config.log 		\
+		configure 		\
+		INSTALL 		\
+		ChangeLog		\
+		configure-stamp		\
+		build-stamp		\
+		libtool			\
+		libtool.m4		\
+		ltoptions.m4		\
+		ltsugar.m4		\
+		ltversion.m4		\
+		ABOUT-NLS		
+
+	rm -f 	missing       		\
+	  	mkinstalldirs 		\
+	  	ltmain.sh     		\
+	  	config.guess 		\
+		config.sub 		\
+		depcomp			\
+		install-sh 		\
+		ltconfig 		\
+		config.hh 		\
+		config.hh.in 		\
+		stamp-h*		\
+		*.dat 			\
+		stamp-driver
+
+	rm -rf  *.tar.gz		\
+		*.deb *.rpm		\
+		$(PACKAGE)-?.?
+
+
+#
+# EOF
+#
diff -u -r -N -xCVS u2f.cern/config/.cvsignore u2f/config/.cvsignore
--- u2f.cern/config/.cvsignore	1970-01-01 01:00:00.000000000 +0100
+++ u2f/config/.cvsignore	2006-01-26 04:03:48.000000000 +0100
@@ -0,0 +1,6 @@
+config.*
+mkinstalldirs
+litmain*
+depcomp
+install-sh
+missing
diff -u -r -N -xCVS u2f.cern/configure.ac u2f/configure.ac
--- u2f.cern/configure.ac	1970-01-01 01:00:00.000000000 +0100
+++ u2f/configure.ac	2006-01-26 04:03:42.000000000 +0100
@@ -0,0 +1,129 @@
+dnl -*- mode: autoconf -*- 
+dnl
+dnl $Id: configure.ac,v 1.1.1.1 2006/01/26 03:03:42 cholm Exp $
+dnl
+dnl ------------------------------------------------------------------
+AC_INIT([ALICE RCU/U2F], [0.5], [Luciano.Musa@cern.ch], altro)
+AC_PREREQ(2.53)
+AC_COPYRIGHT(GNU Lesser General Public License)
+AC_REVISION($Revision: 1.1.1.1 $)
+AC_CONFIG_SRCDIR(u2f/u2f_lib.c)
+AC_CONFIG_AUX_DIR(config)
+AC_PREFIX_DEFAULT(${HOME})
+AM_INIT_AUTOMAKE([$PACKAGE_TARNAME], [$PACKAGE_VERSION])
+
+dnl ------------------------------------------------------------------
+dnl 
+dnl Check host type
+dnl  
+AC_CANONICAL_HOST
+
+dnl
+case "$host" in
+*-*-linux*) 
+  # OK, we're on GNU/Linux - do we need to check the kernel version?
+  KVERS=`uname -r` 
+  ;;
+*) 
+  # this doesn 't run on anything but Linux
+  AC_MSG_ERROR([librcu is only supported on GNU/Linux for the time being])
+  ;;
+esac
+AC_MSG_CHECKING([for Linux kernel version])
+AC_ARG_WITH([kernel-version],
+	    [AC_HELP_STRING([--with-kernel-version=VERS],
+	                    [Compile driver for kernel version VERS])])
+if test "x$with_kernel_version" != "x" && 
+   test "x$with_kernel_version" != "xno" ;then
+   KVERS=$with_kernel_version
+fi
+
+case $KVERS in 
+2.2*|2.4*)
+   old_build=yes
+   MODEXT=o
+   ;;
+*)
+   old_build=no
+   MODEXT=ko
+   ;;
+esac
+AM_CONDITIONAL(OLD_MODULE_BUILD, test "x$old_build" = "xyes")
+AC_MSG_RESULT($KVERS)
+AC_SUBST(KVERS)
+AC_SUBST(MODEXT)
+AC_MSG_CHECKING(for kernel sources)
+KSRC=/lib/modules/$KVERS/build
+if test ! -d  $KSRC/include/linux ; then 
+   AC_MSG_RESULT(no)
+   AC_MSG_ERROR(Kernel sources not found in $KSRC)
+else 
+   AC_MSG_RESULT($KSRC)
+fi
+AC_SUBST(KSRC)
+   
+dnl ------------------------------------------------------------------
+dnl
+dnl Minor node number 
+dnl
+AC_MSG_CHECKING(for minor node number of /dev/rcu)
+MINOR=192
+AC_ARG_WITH([rcu-minor],
+	    [AC_HELP_STRING([--with-rcu-minor=NUMBER],
+	                    [Minor node number of /dev/usb/rcu])])
+if test "x$with_rcu_minor" != "x" && 
+   test "x$with_rcu_minor" != "xno" ;then
+   MINOR=$with_rcu_minor
+fi
+AC_SUBST(MINOR)
+AC_MSG_RESULT($MINOR)
+
+dnl ------------------------------------------------------------------
+dnl
+dnl Dummy RCU library
+dnl
+AH_TEMPLATE([RCU_BANKS_HAVE_DATA], [Whether to include a data member in rcu_banks_t])
+AC_MSG_CHECKING(whether to use dummy RCU library)
+AC_ARG_ENABLE([dummy], 
+	    [AC_HELP_STRING([--enable-dummy],
+	                    [Make dummy RCU library])])
+if test "x$enable_dummy" = "xyes" ; then
+   AC_DEFINE([RCU_BANKS_HAVE_DATA])
+fi
+AM_CONDITIONAL(USE_DUMMY, test "x$enable_dummy" = "xyes")
+AC_MSG_RESULT($enable_dummy)
+		       
+
+dnl ------------------------------------------------------------------
+dnl
+dnl Check for C compiler 
+dnl
+AC_PROG_CC
+
+dnl
+dnl Check for libtool
+dnl
+AC_PROG_LIBTOOL 
+
+dnl ------------------------------------------------------------------
+dnl
+dnl Various flags
+dnl
+AC_DEBUG
+AC_OPTIMIZATION
+CFLAGS="$CFLAGS -Wall -Werror"
+
+dnl ------------------------------------------------------------------
+AC_OUTPUT([Makefile 
+           driver/Makefile
+	   altro/Makefile
+	   tools/Makefile
+	   u2f/Makefile
+	   goofie/Makefile
+	   scripts/Makefile
+	   scripts/altro
+	   scripts/altro-config], [])
+
+dnl
+dnl EOF
+dnl
diff -u -r -N -xCVS u2f.cern/driver/.cvsignore u2f/driver/.cvsignore
--- u2f.cern/driver/.cvsignore	1970-01-01 01:00:00.000000000 +0100
+++ u2f/driver/.cvsignore	2006-01-26 04:03:43.000000000 +0100
@@ -0,0 +1,17 @@
+.rcu_driver.*
+rcu_driver.c
+Makefile
+rcu_common.h
+rcu_driver.ko
+rcu_driver.kmod
+rcu_driver.mod
+rcu_driver.mod.c
+.altro_driver.ko.cmd
+.altro_driver.mod.o.cmd
+.altro_driver.o.cmd
+altro_common.h
+altro_driver.c
+altro_driver.ko
+altro_driver.mod
+altro_driver.mod.c
+semantic.cache
diff -u -r -N -xCVS u2f.cern/driver/Makefile.in u2f/driver/Makefile.in
--- u2f.cern/driver/Makefile.in	1970-01-01 01:00:00.000000000 +0100
+++ u2f/driver/Makefile.in	2006-01-27 09:44:23.000000000 +0100
@@ -0,0 +1,37 @@
+prefix			= @prefix@
+exec_prefix		= @exec_prefix@
+datadir			= @datadir@
+pkgdatadir 		= $(datadir)/@PACKAGE@
+libdir			= @libdir@
+pkglibdir 		= $(libdir)/@PACKAGE@
+includedir		= @includedir@
+pkgincludedir 		= $(includedir)/@PACKAGE@
+modlibdir		= $(pkglibdir)/modules/$(KVERS)
+TOP_SRCDIR		= $(MODVERDIR)/$(top_srcdir)
+MODEXT			= @MODEXT@
+KVERS			= @KVERS@
+INSTALL 		= @INSTALL@
+
+top_srcdir		=  @top_srcdir@
+
+CPPFLAGS		+= -I$(TOP_SRCDIR) \
+			   -DUSB_ALTRO_MINOR_BASE=@MINOR@ \
+			   -DALTRO_KERNEL_DEBUG=1 -DALTRO_BUILD
+EXTRA_CFLAGS		+= -I$(TOP_SRCDIR) \
+			   -DUSB_ALTRO_MINOR_BASE=@MINOR@ \
+			   -DALTRO_KERNEL_DEBUG=1 -DALTRO_BUILD
+
+obj-m			+= altro_driver.o 
+
+modules:		$(obj-m)
+
+install:
+	mkdir -p $(DESTDIR)$(modlibdir)
+	$(INSTALL) altro_driver.$(MODEXT) $(DESTDIR)$(modlibdir)
+
+clean:
+	rm -rf 	altro_driver*.o		altro_driver*.ko	\
+		altro_driver*.mod	altro_driver*.mod.o	\
+		altro_driver*.mod.c	.altro_driver*		\
+		*~ 			.tmp_versions		\
+		altro_driver.c		altro_common.h
diff -u -r -N -xCVS u2f.cern/driver/altro_driver_24.c u2f/driver/altro_driver_24.c
--- u2f.cern/driver/altro_driver_24.c	1970-01-01 01:00:00.000000000 +0100
+++ u2f/driver/altro_driver_24.c	2006-01-26 04:03:45.000000000 +0100
@@ -0,0 +1,636 @@
+/********************************************************/
+/*  This is the driver for the ALICE ALTRO USB core	*/
+/*							*/
+/*  Markus Joos, CERN-PH-ESS 15.3.2004			*/		
+/*							*/
+/*** C 2004 - The software with that certain something **/
+
+/****************************************************************************************/
+/* This dirver works for kernels from 2.4 onwards					*/
+/*											*/
+/* Currently only one ALTRO card is supported. Extending the driver for multiple cards	*/
+/* would require to introduce a "minor" array as done in the usb-skeleton driver	*/
+/****************************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/proc_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/uaccess.h>
+#include "altro_common.h"
+
+MODULE_PARM (debug, "i");
+MODULE_PARM_DESC(debug, "1 = enable debugging   0 = disable debugging");
+MODULE_PARM (timeout, "i");
+MODULE_PARM_DESC(timeout, "timeout for usb_bulk_msg in units of jiffies");
+MODULE_PARM (ddump, "i");
+MODULE_PARM_DESC(ddump, "1 = enable data dumping   0 = disable data dumping");
+MODULE_DESCRIPTION("USB driver for the ALICE ALTRO USB core");
+MODULE_AUTHOR("Markus Joos, CERN/EP");
+MODULE_LICENSE("Private: Contact markus.joos@cern.ch");
+
+
+#ifndef USB_ALTRO_MINOR_BASE
+# define USB_ALTRO_MINOR_BASE 192
+#endif
+#ifdef ALTRO_KERNEL_DEBUG
+# define kdebug(x) {if (debug) printk x;}
+#else
+# define kdebug(x)
+#endif
+
+static int altro_open (struct inode *inode, struct file *file);
+static int altro_release(struct inode *inode, struct file *file);
+static int proc_write_altro(struct file *file, const char *buffer, unsigned long count, void *data);
+static int proc_read_altro(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int altro_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static void altro_disconnect(struct usb_device *udev, void *clientdata);
+static void *altro_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id);
+int altro_init(void);
+void altro_exit(void);
+
+/* Globals */ 
+static int cardtype, debug = 1, timeout = HZ * 10, ddump = 0;
+static struct proc_dir_entry *altro_file;
+struct altro_proc_data_t altro_proc_data;
+struct altro_device *altrop = NULL;
+int urbdone;
+
+/* Externals */
+extern devfs_handle_t usb_devfs_handle;
+
+/*We need a local data structure, as it must be allocated for each*/
+/*new device plugged in the USB bus*/ 
+struct altro_device 
+{
+  char data [10];
+  char *name;                          /* the name of the device */
+  struct urb urb;                      /* USB Request block, to get USB data*/
+  int maxp;                            /* packet len */
+  char output[80];                     /* used for printk at irq time */
+  unsigned char minor;                 /* the starting minor number for this device */
+  devfs_handle_t devfs;                /* devfs device node */
+  struct usb_device *udev;             /* save off the usb device pointer */
+  struct semaphore sem;                /* locks this structure */
+  unsigned char *bulk_in_buffer;       /* the buffer to receive data */
+  int bulk_in_size;                    /* the size of the receive buffer */
+  __u8 bulk_in_endpointAddr;           /* the address of the bulk in endpoint */
+  unsigned char *bulk_out_buffer;      /* the buffer to send data */
+  int bulk_out_size;                   /* the size of the send buffer */
+  struct urb *write_urb;               /* the urb used to send data */
+  __u8 bulk_out_endpointAddr;          /* the address of the bulk out endpoint */
+};
+
+/* Data in /proc file system */
+struct altro_proc_data_t
+{
+  char name[10];
+  char value[100];
+};
+
+/* The id_table, lists all devices that can be handled by this driver. */
+/* The three numbers are class, subclass, protocol. <linux/usb.h> has */
+/* more details about interface matches and vendor/device matches. */
+/* Here we use a fake usb_device_id structure defined in ./usb-sysdep.h */
+
+/*The parameters for the ALTRO are*/
+/*Class    = */
+/*Subclass = */
+/*Protocol = */
+
+static struct usb_device_id altro_id_table [] = 
+{
+  { 
+    USB_DEVICE(0x1556, 0x0350),
+    driver_info: (unsigned long)"altro_by_vendor (invalid device id)"
+  },
+  {
+    USB_DEVICE(0x1556, 0x15e),
+    driver_info: (unsigned long)"ALICE U2F"
+  },
+  { 
+    USB_DEVICE(0x1556, 0x15f),
+    driver_info: (unsigned long)"ALICE GOOFIE"
+  },
+  {
+    USB_DEVICE(0x1556, 0x163),
+    driver_info: (unsigned long)"ALICE MPT"
+  },
+  {
+    0, /* no more matches */
+  }
+};
+
+MODULE_DEVICE_TABLE (usb, altro_id_table);
+
+/* file operations supported */
+static struct file_operations altro_fops = 
+{
+  owner:       THIS_MODULE,
+  ioctl:       altro_ioctl,
+  open:        altro_open,
+  release:     altro_release,
+};
+
+/* The callbacks are registered within the USB subsystem using the */
+/* usb_driver data structure */
+static struct usb_driver altro_usb_driver = 
+{
+  owner:       THIS_MODULE,
+  name:        "altro",
+  probe:       altro_probe,
+  disconnect:  altro_disconnect,
+  fops:        &altro_fops,
+  minor:       USB_ALTRO_MINOR_BASE,
+  id_table:    altro_id_table,
+};
+
+
+/************************************************************/
+static int altro_open (struct inode *inode, struct file *file)
+/************************************************************/
+{
+  int retval = 0;
+  
+  kdebug(("altro_drv(altro_open): function called\n"));
+  if (altrop == NULL) 
+  {
+    kdebug(("altro_drv(altro_open): Sorry. So far no ALTRO has been connected\n"));
+    return -ENODEV;
+  }
+  
+  kdebug(("altro_drv(altro_open): minor number = %d\n", MINOR(inode->i_rdev)));
+  
+  /* save our object in the file's private structure */
+  /*MJ: assigning altrop to private_data does not make sense. We use it nowhere. Instead*/
+  /*MJ: we should define a proper "private_stuff" structure (a la cmem_rcc)*/
+  file->private_data = altrop;
+  
+  kdebug(("altro_drv(altro_open): function done\n"));
+  return retval;
+}
+
+
+/**************************************************************/
+static int altro_release(struct inode *inode, struct file *file)
+/**************************************************************/
+{
+  kdebug(("altro_drv(altro_release): function called\n"));
+
+  return(0);
+}
+
+
+/* This callback is invoked when a USB device is detached from the bus*/
+/*********************************************************************/
+static void altro_disconnect(struct usb_device *udev, void *clientdata)
+/*********************************************************************/
+{
+  /* the clientdata is the altro_device we passed originally */
+  struct altro_device *altro = clientdata;
+
+  kdebug(("altro_drv(altro_disconnect): function called\n"));
+
+  /* remove the URB, remove the input device, free memory */
+  usb_unlink_urb(&altro->urb);
+
+  /* remove our devfs node */
+  devfs_unregister(altro->devfs);
+
+  kfree(altro);
+  kdebug(("altro_drv(altro_disconnect): USB %s disconnected\n", altro->name));
+
+  return;
+}
+
+
+/*This callback is invoked when a USB device is attached to the bus */ 
+/***************************************************************************************************/
+static void *altro_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
+/***************************************************************************************************/
+{
+  /* The probe procedure is pretty standard. Device matching has already */
+  /* been performed based on the id_table structure */
+
+  struct usb_interface *iface;
+  struct usb_interface_descriptor *interface;
+  struct usb_endpoint_descriptor *endpoint;
+  struct altro_device *altro;
+  int i, buffer_size, inok, outok;
+
+  kdebug(("altro_drv(altro_probe): probe called for %s device\n", (char *)id->driver_info));
+  kdebug(("altro_drv(altro_probe): ifnum = %d\n", ifnum));
+
+  /* allocate and zero a new data structure for the new device */
+  altro = kmalloc(sizeof(struct altro_device), GFP_KERNEL);
+  if (!altro) 
+  { 
+    kdebug(("altro_drv(altro_probe): ERROR failed to kmalloc altro_device\n"));
+    return NULL; /* failure */
+  }
+  
+  memset(altro, 0, sizeof(*altro));
+  altro->name = (char *)id->driver_info;
+  init_MUTEX(&altro->sem);
+
+  kdebug(("altro_drv(altro_probe): udev->descriptor.idVendor = 0x%08x\n", udev->descriptor.idVendor));
+  kdebug(("altro_drv(altro_probe): udev->descriptor.idProduct = 0x%08x\n", udev->descriptor.idProduct));
+  cardtype = udev->descriptor.idProduct;
+  
+  iface = &udev->actconfig->interface[ifnum];
+  interface = &iface->altsetting[iface->act_altsetting];
+
+  if (interface->bNumEndpoints != 2) 
+  {
+    kdebug(("altro_drv(altro_probe): ERROR interface->bNumEndpoints != 2 (number = %d)\n", interface->bNumEndpoints));
+    return NULL;
+  }
+  
+  inok = 0;
+  outok = 0;
+    
+  for (i = 0; i < interface->bNumEndpoints; ++i) 
+  {
+    kdebug(("altro_drv(altro_probe): Processing endpoint %d ...\n", i));
+    endpoint = &interface->endpoint[i];
+    
+    if ((endpoint->bEndpointAddress & 0x80) && ((endpoint->bmAttributes & 3) == 0x02)) 
+    {
+      if (!inok) 
+      {
+        kdebug(("altro_drv(altro_probe): we found the first bulk in endpoint\n"));
+	buffer_size = endpoint->wMaxPacketSize;
+	kdebug(("altro_drv(altro_probe): buffer_size = %d\n", buffer_size));
+	altro->bulk_in_size = buffer_size;
+	altro->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+	kdebug(("altro_drv(altro_probe): bulk_in_endpointAddr = %d\n", altro->bulk_in_endpointAddr));
+	altro->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+	if (!altro->bulk_in_buffer) 
+	{
+          kdebug(("altro_drv(altro_probe): Couldn't allocate bulk_in_buffer"));
+          return NULL;
+	}
+	inok = 1;
+      }
+      else
+        kdebug(("altro_drv(altro_probe): we found another bulk in endpoint\n"));
+    }
+    
+    else if (((endpoint->bEndpointAddress & 0x80) == 0x00) && ((endpoint->bmAttributes & 3) == 0x02)) 
+    {
+      if (!outok) 
+      {
+	kdebug(("altro_drv(altro_probe): we found the first bulk out endpoint\n"));
+	altro->write_urb = usb_alloc_urb(0);
+	if (!altro->write_urb) 
+	{
+          kdebug(("altro_drv(altro_probe): No free urbs available"));
+          return NULL;
+	}
+	buffer_size = endpoint->wMaxPacketSize;
+	kdebug(("altro_drv(altro_probe): buffer_size = %d\n", buffer_size));
+	altro->bulk_out_size = buffer_size;
+	altro->bulk_out_endpointAddr = endpoint->bEndpointAddress;
+	kdebug(("altro_drv(altro_probe): bulk_out_endpointAddr = %d\n", altro->bulk_out_endpointAddr));
+	altro->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
+	if (!altro->bulk_out_buffer) 
+	{
+          kdebug(("altro_drv(altro_probe): Couldn't allocate bulk_out_buffer"));
+          return NULL;
+	}
+	outok = 1;
+      }	
+
+      else
+        kdebug(("altro_drv(altro_probe): we found another bulk out endpoint\n"));
+    }
+    else
+      {
+	kdebug(("altro_drv(altro_probe): we found an unidentifiable endpoint\n"));
+	return NULL;
+    }
+  }
+  
+  altro->udev = udev;
+  altrop = altro;
+  kdebug(("altro_drv(altro_probe): End of function\n"));
+
+  return altro;
+}
+
+
+/* Function called at module load time: only register the USB callbacks */
+/******************/
+int altro_init(void)
+/******************/
+{
+  kdebug(("altro_drv(altro_init): function called\n"));
+
+  /* Install /proc entry */
+  altro_file = create_proc_entry("altro", 0644, NULL);
+  if (altro_file == NULL) 
+  {
+    kdebug(("altro_drv(altro_init): ERROR from call to create_proc_entry\n"));
+    return (-ENOMEM);
+  }
+
+  strcpy(altro_proc_data.name, "altro");
+  strcpy(altro_proc_data.value, "altro");
+  altro_file->data = &altro_proc_data;
+  altro_file->read_proc = proc_read_altro;
+  altro_file->write_proc = proc_write_altro;
+  altro_file->owner = THIS_MODULE;
+    
+  return usb_register(&altro_usb_driver);
+}
+
+
+/* Function called at module unload time: only unregister the USB callbacks */ 
+/*******************/
+void altro_exit(void)
+/*******************/
+{
+  kdebug(("altro_drv(altro_exit): function called\n"));
+
+  /* Remove /proc entry */
+  remove_proc_entry("altro", NULL);
+  
+  usb_deregister(&altro_usb_driver);
+}
+
+
+/**********************/
+module_init(altro_init);
+/**********************/
+
+
+/**********************/
+module_exit(altro_exit);
+/**********************/
+
+
+/*************************************************************************************************/
+static int proc_write_altro(struct file *file, const char *buffer, unsigned long count, void *data)
+/*************************************************************************************************/
+{
+  int len;
+  struct altro_proc_data_t *fb_data = (struct altro_proc_data_t *)data;
+
+  kdebug(("altro_drv(proc_write_altro): proc_write_altro called\n"));
+  
+  if(count > 99)
+    len = 99;
+  else
+    len = count;
+  
+  if (copy_from_user(fb_data->value, buffer, len)) 
+  {
+    kdebug(("altro_drv(proc_write_altro): error from copy_from_user\n"));
+    return(-EFAULT);
+  }
+
+  kdebug(("altro_drv(proc_write_altro): len = %d\n", len));
+  fb_data->value[len - 1] = '\0';
+  kdebug(("altro_drv(proc_write_altro): text passed = %s\n", fb_data->value));
+  
+  if (!strcmp(fb_data->value, "debug")) 
+  {
+    debug = 1;
+    kdebug(("altro_drv(proc_write_altro): debugging enabled\n")); 
+  }
+ 
+  if (!strcmp(fb_data->value, "nodebug")) 
+  {
+    kdebug(("altro_drv(proc_write_altro): debugging disabled\n")); 
+    debug = 0; 
+  }
+  
+  if (!strcmp(fb_data->value, "datadump")) 
+  {
+    ddump = 1;
+    kdebug(("altro_drv(proc_write_altro): data dumping enabled\n")); 
+  }
+ 
+  if (!strcmp(fb_data->value, "nodatadump")) 
+  {
+    ddump = 0; 
+    kdebug(("altro_drv(proc_write_altro): data dumping disabled\n")); 
+  }
+  
+  if (!strcmp(fb_data->value, "dec")) 
+  {
+    MOD_DEC_USE_COUNT;
+    kdebug(("altro_drv(proc_write_altro): Use count decremented\n"));
+  }
+
+  if (!strcmp(fb_data->value, "inc")) 
+  {
+    MOD_INC_USE_COUNT;
+    kdebug(("altro_drv(proc_write_altro): Use count incremented\n"));
+  }
+ 
+  return len;
+}
+
+
+/**********************************************************************************************/
+static int proc_read_altro(char *page, char **start, off_t off, int count, int *eof, void *data)
+/**********************************************************************************************/
+{
+  int len;
+
+  kdebug(("altro_drv(proc_read_altro): proc_read_altro called\n"));
+
+  len = sprintf(page, "ALICE ALTRO USB driver\n");
+  len += sprintf(page + len, " \n");
+  len += sprintf(page + len, "Type of card connected: ");
+  if (cardtype == 0x15e || cardtype == 0x350)
+    len += sprintf(page + len, "ALICE U2F\n");
+  else if (cardtype == 0x15f)
+    len += sprintf(page + len, "ALICE GOOFIE\n");
+  else if (cardtype == 0x163)
+    len += sprintf(page + len, "ALICE MPT\n");
+  else
+    len += sprintf(page + len, "UNKNOWN (maybe your card is using an invalid device ID\n");
+  len += sprintf(page + len, "\n");
+  len += sprintf(page + len, "The time-out of usb_bulk_msg() is %d jiffies (usually: 1 jiffie = 10 ms)\n", timeout);
+  len += sprintf(page + len, "\n");
+  len += sprintf(page + len, "The command 'echo <action> > /proc/altro', executed as root,\n");
+  len += sprintf(page + len, "allows you to interact with the driver. Possible actions are:\n");
+  len += sprintf(page + len, "debug      -> enable debugging\n");
+  len += sprintf(page + len, "nodebug    -> disable debugging\n");
+  len += sprintf(page + len, "datadump   -> enable data dumping (use with care)\n");
+  len += sprintf(page + len, "nodatadump -> disable data dumping\n");
+  len += sprintf(page + len, "dec        -> Decrement use count\n");
+  len += sprintf(page + len, "inc        -> Increment use count\n");
+
+  *eof = 1;
+  *start = page + off;
+  len -= off;
+
+  if (len > count)
+    len = count;
+  return (len);
+}
+
+
+/**************************************************************************************************/
+static int altro_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+/**************************************************************************************************/
+{
+  struct altro_device *altro;
+  int pipe, retval, loop;
+  
+  kdebug(("altro_drv(altro_ioctl): function called\n")); 
+  kdebug(("altro_drv(altro_ioctl): minor number = %d\n", MINOR (inode->i_rdev)));
+
+  altro = (struct altro_device *)file->private_data;
+  
+  /* lock this object */
+  down (&altro->sem);
+  kdebug(("altro_drv(altro_ioctl): semaphore locked\n")); 
+  
+  /* verify that the device wasn't unplugged */
+  if (altro->udev == NULL) 
+  {
+    up (&altro->sem);
+    kdebug(("altro_drv(altro_ioctl): ERROR device was unplugged\n"));
+    return -ENODEV;
+  }
+  kdebug(("altro_drv(altro_ioctl): The device is still connected\n")); 
+  
+  switch (cmd) 
+  {    
+    case GET_DATA: 
+    {   
+      altro_bulk_in_t params; /*MJ: this memory gets allocated on the stack. Better move it to the private data*/
+      kdebug(("altro_drv(ioctl:GET_DATA): function called for endpoint 0x%08x\n", altro->bulk_in_endpointAddr));
+      kdebug(("altro_drv(ioctl:GET_DATA): altro->bulk_in_size = %d\n", altro->bulk_in_size));
+
+      pipe = usb_rcvbulkpipe(altro->udev, altro->bulk_in_endpointAddr);
+      kdebug(("altro_drv(ioctl:GET_DATA): reading from pipe %d\n", pipe));
+
+      /* do an immediate bulk read to get data from the device */
+      /* MJ: The parameter altro->bulk_in_size requests as much data as the ALTRO can actually send */
+      /* MJ: The real amount of data may be less than that.*/
+      /* MJ: The constant BULK_IN_SIZE in the header file has to be tuned to the value of endpoint->wMaxPacketSize*/ 
+      retval = usb_bulk_msg(altro->udev, pipe, &params.data[0], altro->bulk_in_size, &params.nbytes, timeout);
+      kdebug(("altro_drv(ioctl:GET_DATA): usb_bulk_msg returns %d\n", retval));
+
+      if (retval)  
+      {
+	kdebug(("altro_drv(ioctl:GET_DATA): No data received\n"));
+	params.nbytes = 0;
+      }
+      else
+	kdebug(("altro_drv(ioctl:GET_DATA): %d bytes received\n", params.nbytes));
+
+      if (ddump)
+      {
+	kdebug(("altro_drv(ioctl:GET_DATA): Now dumping newly received data.......\n"));
+        for (loop = 0; loop < params.nbytes; loop++)
+	  kdebug(("altro_drv(ioctl:GET_DATA): Byte #%d = 0x%02x\n", loop, params.data[loop]));
+      } 
+
+      if (copy_to_user ((void *)arg, &params, sizeof(altro_bulk_in_t)) != 0) 
+      {
+	kdebug(("altro_drv(ioctl:GET_DATA): error from copy_to_user\n"));
+	up (&altro->sem);
+	return(-ALTRO_EFAULT);
+      }
+      break;
+    }    
+
+    case SEND_DATA: 
+    {   
+      altro_bulk_out_t params;  /*MJ: this memory gets allocated on the stack. Better move it to the private data*/
+      int maxp, ndone;
+
+      kdebug(("altro_drv(ioctl:SEND_DATA): function called for endpoint 0x%08x\n", altro->bulk_out_endpointAddr));
+      kdebug(("altro_drv(ioctl:SEND_DATA): altro->bulk_in_size = %d\n", altro->bulk_out_size));
+
+      if (copy_from_user(&params, (void *)arg, sizeof(altro_bulk_out_t)) !=0) 
+      {
+	kdebug(("altro_drv(ioctl:SEND_DATA): error from copy_from_user\n"));
+	up (&altro->sem);
+	return(-ALTRO_EFAULT);
+      }
+
+      pipe = usb_sndbulkpipe(altro->udev, altro->bulk_out_endpointAddr);
+      kdebug(("altro_drv(ioctl:SEND_DATA): reading from pipe %d\n", pipe));
+
+      maxp = usb_maxpacket(altro->udev, pipe, usb_pipeout(pipe));
+      if (maxp > altro->bulk_out_size) 
+	maxp = altro->bulk_out_size; 
+      kdebug(("altro_drv(ioctl:SEND_DATA): it is possible to send %d bytes\n", maxp));
+
+      /* check if we would write more data than possible */
+      if (params.nbytes > maxp) 
+      {	
+	kdebug(("altro_drv(ioctl:SEND_DATA): Cannot write %d bytes to pipe of %d bytes\n", params.nbytes, maxp));
+	up (&altro->sem);
+	return(-ALTRO_EFAULT);
+      }
+      kdebug(("altro_drv(ioctl:SEND_DATA): trying to send %d bytes\n", params.nbytes));
+
+      if (ddump)
+      {
+	kdebug(("altro_drv(ioctl:SEND_DATA): Dumping data berfore sending it.......\n"));
+        for (loop = 0; loop < params.nbytes; loop++)
+	  kdebug(("altro_drv(ioctl:SEND_DATA): Byte #%d = 0x%02x\n", loop, params.data[loop]));
+      } 
+
+      /* do an immediate bulk write to send data to the device */
+      retval = usb_bulk_msg(altro->udev, pipe, &params.data[0], params.nbytes, &ndone, timeout);
+      kdebug(("altro_drv(ioctl:SEND_DATA): usb_bulk_msg returns %d\n", retval));
+      if (retval) 
+      {
+	kdebug(("altro_drv(ioctl:SEND_DATA): No data sent\n"));
+	up (&altro->sem);
+	return(-ALTRO_EFAULT);
+      }
+      else
+	kdebug(("altro_drv(ioctl:SEND_DATA): %d bytes sent\n", ndone));
+
+      break;
+    }     
+
+    case CONTROL: 
+    {
+      altro_control_t params;  /*MJ: this memory gets allocated on the stack. Better move it to the private data*/
+
+      kdebug(("altro_drv(ioctl:CONTROL): function called\n"));
+
+      if (copy_from_user(&params, (void *)arg, sizeof(altro_control_t)) !=0 ) 
+      {
+	kdebug(("altro_drv(ioctl:CONTROL): error from copy_from_user\n"));
+	up (&altro->sem);
+	return(-ALTRO_EFAULT);
+      }
+
+      kdebug(("altro_drv(ioctl:CONTROL): params.bRequest      = %d\n", params.bRequest));
+      kdebug(("altro_drv(ioctl:CONTROL): params.bmRequestType = %d\n", params.bmRequestType));
+      kdebug(("altro_drv(ioctl:CONTROL): params.wValue        = %d\n", params.wValue));
+      kdebug(("altro_drv(ioctl:CONTROL): params.wIndex        = %d\n", params.wIndex));
+      kdebug(("altro_drv(ioctl:CONTROL): params.data[0]       = %d\n", params.data[0]));
+      kdebug(("altro_drv(ioctl:CONTROL): params.wLength       = %d\n", params.wLength));
+
+      retval = usb_control_msg(altro->udev, usb_rcvctrlpipe(altro->udev,0), params.bRequest, params.bmRequestType, 
+			       params.wValue, params.wIndex, &params.data[0], params.wLength, HZ);
+      if (retval) 
+      {
+	kdebug(("altro_drv(ioctl:CONTROL): ERROR  failed to register control URB. Error code = %d\n", retval));
+	up (&altro->sem); 
+	return(-ALTRO_EFAULT);
+      }
+      break;
+    }
+  }
+  /* unlock the device */
+  up (&altro->sem);
+  return(0);
+}
diff -u -r -N -xCVS u2f.cern/driver/altro_driver_26.c u2f/driver/altro_driver_26.c
--- u2f.cern/driver/altro_driver_26.c	1970-01-01 01:00:00.000000000 +0100
+++ u2f/driver/altro_driver_26.c	2006-01-26 04:03:44.000000000 +0100
@@ -0,0 +1,1274 @@
+/*
+ * This diver based on:
+ (
+ * USB Skeleton driver - 1.1
+ *
+ * Copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation, version 2.
+ */
+/** @file    altro_driver_26.c
+ *  @author  Markus Joos, CERN-PH-ESS 15.3.2004
+ *  @date    Mon Jan 17 22:28:58 2005
+ *  @brief   This is the driver for the ALICE RCU card
+ *
+ *  This driver works for kernels from 2.4 onwards
+ *
+ *  Currently only one RCU card is supported. Extending the driver for
+ *  multiple cards would require to introduce a "minor" array as done
+ *  in the usb-skeleton driver 
+ *
+ *  @par open issues:  
+ *
+ *  1) The memory read functions do not work because the IN
+ *  transaction is executed before the OUT transaction 
+ *
+ *  2) If one repeats the same memory write two times
+ *  (e.g. IMEM_Write) the first transaction has an ACK,   
+ *  the second a NYet, the third URB does not complete and the
+ *  fourth creates the error mentioned in issue 1) above  
+ *
+ *  3) The memory read/write calls in the U2F library need an offset
+ *  parameter relative to the respective memory
+*/
+/** @defgroup altro_driver RCU driver code  */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/completion.h>
+#include <asm/uaccess.h>
+#include <linux/usb.h>
+#include <linux/proc_fs.h>
+#include "altro_common.h"
+
+/********************************************************************/
+/** @name Debug 
+ *  @ingroup altro_driver 
+ */
+#ifdef CONFIG_USB_DEBUG
+/** @var debug 
+ *  @brief Debug flag 
+ */
+static int debug = 1;
+#else
+static int debug;
+#endif
+
+#undef kdebug
+/** @def kdebug 
+ *  @brief macro to print debug information to system log */
+#define kdebug(x) \
+  do { if (debug) { printk("ALTRO [%s]: ", __FUNCTION__); printk x; } } while (0)
+
+/********************************************************************/
+/*  @name Version Information 
+ *  @ingroup altro_driver 
+ */
+/** @def DRIVER_VERSION
+ *  @ingroup altro_driver 
+ *  @brief v1.0
+ */
+#define DRIVER_VERSION "v1.0"
+/** @def DRIVER_AUTHOR
+ *  @ingroup altro_driver 
+ *  @brief Markus Joos, CERN/PH
+ */
+#define DRIVER_AUTHOR  "Markus Joos, CERN/PH"
+/** @def DRIVER_DESC
+ *  @ingroup altro_driver 
+ *  @brief USB driver for the ALICE ALTRO card
+ */
+#define DRIVER_DESC    "USB driver for the ALICE ALTRO card"
+/** @def DRIVER_LICENSE
+ *  @ingroup altro_driver 
+ *  @brief Private: Contact markus.joos@cern.ch
+ */
+#define DRIVER_LICENSE "Private: Contact markus.joos@cern.ch"
+
+/********************************************************************/
+/*  @name Module parameters
+ *  @ingroup altro_driver 
+ */
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
+/********************************************************************/
+/*  @name Device information
+ *  @ingroup altro_driver 
+ */
+/** @def USB_ALTRO_VENDOR_ID
+ *  @ingroup altro_driver 
+ *  @brief The vendor identifier 
+ */
+#define USB_ALTRO_VENDOR_ID	 0x1556
+/** @def USB_ALTRO_PRODUCT_ID
+ *  @ingroup altro_driver 
+ *  @brief The product identifier 
+ */
+#define USB_ALTRO_PRODUCT_ID 	0x0350
+/** @def USB_ALTRO_U2F_ID 
+ *  @ingroup altro_driver
+ *  @brief Product identifier for the U2F board 
+ */
+#define USB_ALTRO_U2F_ID          0x15e
+/** @def USB_ALTRO_GOFFIE_ID 
+ *  @ingroup altro_driver
+ *  @brief Product identifier for the GOFFIE board 
+ */
+#define USB_ALTRO_GOFFIE_ID       0x15f
+/** @def USB_ALTRO_MPT_ID 
+ *  @ingroup altro_driver
+ *  @brief Product identifier for the MPT board 
+ */
+#define USB_ALTRO_MPT_ID          0x163
+
+
+/** @var altro_table
+ *  @ingroup altro_driver 
+ *  @brief  table of devices that work with this driver 
+ */
+static struct usb_device_id altro_table [] = {
+  { USB_DEVICE(USB_ALTRO_VENDOR_ID, USB_ALTRO_PRODUCT_ID),
+    driver_info: (unsigned long)"altro_by_vendor (Old id)" },
+  { USB_DEVICE(USB_ALTRO_VENDOR_ID, USB_ALTRO_U2F_ID), 
+    driver_info: (unsigned long)"ALICE U2F" },
+  { USB_DEVICE(USB_ALTRO_VENDOR_ID, USB_ALTRO_GOFFIE_ID), 
+    driver_info: (unsigned long)"ALICE GOFFIE" },
+  { USB_DEVICE(USB_ALTRO_VENDOR_ID, USB_ALTRO_MPT_ID), 
+    driver_info: (unsigned long)"ALICE MPT" },
+  { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, altro_table);
+
+
+/********************************************************************/
+/*  @name Driver information 
+ *  @ingroup altro_driver 
+ */ 
+#ifndef USB_ALTRO_MINOR_BASE
+/** @def  USB_ALTRO_MINOR_BASE
+ *  @ingroup altro_driver 
+ *  @brief Get a minor range for your devices from the usb maintainer
+ */ 
+# define USB_ALTRO_MINOR_BASE	192
+#endif
+
+//____________________________________________________________________
+/** @struct altro_device 
+ *  @brief Structure to hold all of our device specific stuff 
+ *  @ingroup altro_driver 
+ */
+struct altro_device {
+  /** save off the usb device pointer */ 
+  struct usb_device*	udev;			
+  /** the interface for this device */ 
+  struct usb_interface*	interface;		
+  /** the starting minor number for this device */ 
+  unsigned char minor;			
+  /** the number of ports this device has */ 
+  unsigned char	num_ports;		
+  /** number of interrupt in endpoints we have */ 
+  char num_interrupt_in;	
+  /** number of bulk in endpoints we have */
+  char num_bulk_in;		
+  /** number of bulk out endpoints we have */ 
+  char	num_bulk_out;		
+  
+  /** the buffer to receive data */ 
+  unsigned char* bulk_in_buffer;		
+  /** the size of the receive buffer */ 
+  size_t bulk_in_size;		
+  /** the urb used to recieve data */ 
+  struct urb* read_urb;		
+  /** the address of the bulk in endpoint */
+  __u8	bulk_in_endpointAddr;	
+
+  /** the buffer to send data */ 
+  unsigned char* bulk_out_buffer;	
+  /** the size of the send buffer */ 
+  size_t bulk_out_size;		
+  /** the urb used to send data */ 
+  struct urb* write_urb;		
+  /** the address of the bulk out endpoint */ 
+  __u8	bulk_out_endpointAddr;	
+  /** true iff write urb is busy */ 
+  atomic_t write_busy;		
+  /** wait for the write to finish */ 
+  struct completion write_finished;		
+
+  /** if the port is open or not */ 
+  int open;			
+  /** if the device is not disconnected */ 
+  int present;		
+  /** locks this structure */ 
+  struct semaphore sem;			
+
+  /** Test data */ 
+  int test;
+  /** Name */
+  char* name;
+};
+
+static u_int    n_our_devices = 0;
+static struct altro_device* our_devices[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+static void add_our_device(struct altro_device* dev) 
+{
+  if (n_our_devices >= 10) {
+    kdebug(("Cannot add the 11th device to internal table"));
+    return;
+  }
+  our_devices[n_our_devices] = dev;
+  kdebug(("Added device %s at %d", dev->name, n_our_devices));
+  n_our_devices++;
+}
+
+static void remove_our_device(struct altro_device* dev) 
+{
+  u_int i = 0;
+  for (i = 0; i < n_our_devices; i++) {
+    if (dev == our_devices[i]) {
+      our_devices[i] = 0;
+      n_our_devices--;
+      kdebug(("Removed device %s at %d", dev->name, i));
+      break;
+    }
+  }
+  for (; i < n_our_devices + 1; i++) 
+    our_devices[i] = our_devices[i+1];
+  if (i >=  n_our_devices + 1)
+    our_devices[i] = 0;
+}
+  
+
+/** @brief Semaphore to prevent races between open() and disconnect() 
+ *  @ingroup altro_driver 
+ */
+static DECLARE_MUTEX (disconnect_sem);
+
+/* static struct altro_device*     _altro = NULL; */
+
+/********************************************************************/
+/*  @name PROC node
+ *  @ingroup altro_driver 
+ */ 
+/** @struct altro_proc_data_t
+ *  @ingroup altro_driver 
+ *  @brief Data structure for the @c /proc file system node 
+ */
+struct altro_proc_data_t
+{
+  /** Name */
+  char name[10];
+  /** Values */
+  char value[100];
+};
+/** @var altro_proc_file
+ *  @ingroup altro_driver 
+ *  @brief @c /proc file system node 
+ */
+static struct proc_dir_entry* altro_proc_file;
+/** @var altro_proc_data
+ *  @ingroup altro_driver 
+ *  @brief Data of the @c /proc file system node 
+ */
+static struct altro_proc_data_t altro_proc_data;
+
+/********************************************************************/
+/* local function prototypes  - the functions are documented at thier
+ * definition 
+ */
+static int altro_ioctl(struct inode *inode, struct file *file, 
+			   unsigned int cmd, unsigned long arg);
+static int altro_open(struct inode *inode, struct file *file);
+static int altro_release(struct inode *inode, struct file *file);
+static int altro_probe(struct usb_interface *interface, 
+		     const struct usb_device_id *id);
+static void altro_disconnect(struct usb_interface *interface);
+static ssize_t altro_read(struct file *file, char *buffer, 
+			size_t count, loff_t *ppos);
+static ssize_t altro_write(struct file *file, const char *buffer, 
+			 size_t count, loff_t *ppos);
+static void altro_write_bulk_callback(struct urb *urb, 
+				    struct pt_regs *regs);
+
+static int  altro_proc_write(struct file *file, const char *buffer, 
+			   unsigned long count, void *data);
+static int  altro_proc_read(char *page, char **start, off_t off, 
+			  int count, int *eof, void *data);
+
+
+/********************************************************************/
+/*  @name Driver structures used by USB layer in kernel
+ *  @ingroup altro_driver 
+ */ 
+/** @var altro_fops
+ *  @brief Call-backs when doing I/O on this device 
+ *  @ingroup altro_driver 
+ *
+ *  File operations needed when we register this driver.  This assumes
+ *  that this driver @e needs file operations, of course, which means
+ *  that the driver is expected to have a node in the @c /dev
+ *  directory. If the USB device were for a network interface then the
+ *  driver would use @c struct @c net_driver instead, and a serial
+ *  device would use @c struct @c tty_driver.
+ */
+static struct file_operations altro_fops = {
+  /*
+   * The owner field is part of the module-locking mechanism. The idea
+   * is that the kernel knows which module to increment the
+   * use-counter of BEFORE it calls the device's open() function.
+   * This also means that the kernel can decrement the use-counter
+   * again before calling release() or should the open() function
+   * fail.
+   */
+  .owner =	THIS_MODULE,
+  .ioctl =	altro_ioctl,
+  .open =	altro_open,
+  .release =	altro_release,
+  .read =	altro_read,
+  .write =	altro_write
+};
+
+/** @var altro_class 
+ *  @brief The type of the USB device 
+ *  @ingroup altro_driver 
+ * 
+ *  USB class driver info in order to get a minor number from the USB
+ *  core, and to have the device registered with devfs and the driver
+ *  core
+ */
+static struct usb_class_driver altro_class = {
+  .name = "altro%d",
+  .fops = &altro_fops,
+  /* .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
+     |  S_IWOTH, */
+  .minor_base =	USB_ALTRO_MINOR_BASE,
+};
+
+/** @var altro_driver 
+ *  @brief Driver call backs 
+ *  @ingroup altro_driver 
+ * 
+ *  USB specific object needed to register this driver with the USB
+ *  subsystem
+ */ 
+static struct usb_driver altro_driver = {
+  .owner =	THIS_MODULE,
+  .name =	"altro",
+  .probe =	altro_probe,
+  .disconnect =	altro_disconnect,
+  .id_table =	altro_table,
+};
+
+/********************************************************************/
+/*  @name Functions
+ *  @ingroup altro_driver 
+ */ 
+/*__________________________________________________________________*/
+/** Delete the ALTRO driver structures 
+ *  @param dev The device to free memory for 
+ *  @ingroup altro_driver 
+ */
+static inline void 
+altro_delete(struct altro_device *dev)
+{
+  kfree (dev->bulk_in_buffer);
+  usb_buffer_free(dev->udev, dev->bulk_out_size,
+		  dev->bulk_out_buffer,
+		  dev->write_urb->transfer_dma);
+  usb_free_urb(dev->write_urb);
+  kfree(dev);
+}
+
+/*__________________________________________________________________*/
+/** Call-back for @c open system call 
+ *  @param inode The node opened by the user 
+ *  @param file  The file pointer to open
+ *  @return 0 on success, error code otherwise
+ *  @ingroup altro_driver 
+ */
+static int 
+altro_open(struct inode *inode, struct file *file)
+{
+  struct altro_device*    dev = NULL;
+  struct usb_interface* interface;
+  int                   subminor;
+  int                   retval = 0;
+  kdebug(("called"));
+
+  // the below is if we have more than one USB device.
+  subminor = iminor(inode);
+  kdebug(("minor number = %d\n", subminor));
+
+  /* prevent disconnects */
+  down(&disconnect_sem);
+
+  interface = usb_find_interface (&altro_driver, subminor);
+  if (!interface) {
+    err ("%s - error, can't find device for minor %d", __FUNCTION__, subminor);
+    retval = -ENODEV;
+    goto exit_no_device;
+  }
+
+  dev = usb_get_intfdata(interface);
+  if (!dev) {
+    retval = -ENODEV;
+    goto exit_no_device;
+  }
+
+  /* lock this device */
+  down(&dev->sem);
+  
+  /* increment our usage count for the driver */
+  ++dev->open;
+
+  /* save our object in the file's private structure */
+  file->private_data = dev;
+
+  /* unlock this device */
+  up (&dev->sem);
+
+ exit_no_device:
+  up (&disconnect_sem);
+  return retval;
+}
+
+/*__________________________________________________________________*/
+/** Call-back for @c close system call 
+ *  @param inode the node to close
+ *  @param file  The file descriptor to close 
+ *  @return 0 on success, error code otherwise
+ *  @ingroup altro_driver 
+ */
+static int 
+altro_release(struct inode *inode, struct file *file)
+{
+  int retval = 0;
+  // The below is if we have more than one device 
+  struct altro_device* dev;
+
+  dev = (struct altro_device *)file->private_data;
+  if (dev == NULL) {
+    dbg ("%s - object is NULL", __FUNCTION__);
+    return -ENODEV;
+  }
+  kdebug(("minor %d\n", dev->minor));
+
+  /* lock our device */
+  down (&dev->sem);
+  if (dev->open <= 0) {
+    kdebug(("device not opened"));
+    retval = -ENODEV;
+    goto exit_not_opened;
+  }
+
+  /* wait for any bulk writes that might be going on to finish up */
+  if (atomic_read (&dev->write_busy))
+    wait_for_completion (&dev->write_finished);
+
+  --dev->open;
+
+  if (!dev->present && !dev->open) {
+    /* the device was unplugged before the file was released */
+    up (&dev->sem);
+    altro_delete (dev);
+    return 0;
+  }
+
+ exit_not_opened:
+  up (&dev->sem);
+  return retval;
+}
+
+/*__________________________________________________________________*/
+/** Print out debug data. 
+ *  @param function The function that called this 
+ *  @param size the size of @a data 
+ *  @param data The data to write out
+ *  @ingroup altro_driver 
+ */
+static inline void 
+altro_debug_data(const char *function, int size, const unsigned char *data)
+{
+  int i;
+  if (!debug) return;
+  printk(KERN_DEBUG __FILE__": %s - length = %d, data = ", function, size);
+  for (i = 0; i < size; ++i) printk ("%.2x ", data[i]);
+  printk ("\n");
+}
+
+/*__________________________________________________________________*/
+/** Call-back of @c read system call 
+ *
+ *   @param file File the user is reading from 
+ *   @param buffer On return, the data read
+ *   @param count On input, the size of @a buffer in bytes. 
+ *   @param ppos Not used. 
+ *   @return The actual number of bytes read, or negative error
+ *   code on failure
+ *  @ingroup altro_driver 
+ */
+static ssize_t 
+altro_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+  struct altro_device *dev;
+  int retval = 0;
+
+  dev = (struct altro_device *)file->private_data;
+  kdebug(("minor %d, count = %d", dev->minor, count));
+
+  /* lock this object */
+  down (&dev->sem);
+
+  /* verify that the device wasn't unplugged */
+  if (!dev->present) {
+    kdebug(("Error: Device was unplugged!\n"));
+    up (&dev->sem);
+    return -ENODEV;
+  }
+
+  kdebug(("function called for end-point 0x%08x\n"
+	  "  bulk_in_size: %d", dev->bulk_in_endpointAddr, dev->bulk_in_size));
+  
+  /* do a blocking bulk read to get data from the device */ 
+  retval = usb_bulk_msg(dev->udev,
+			usb_rcvbulkpipe (dev->udev, 
+					 dev->bulk_in_endpointAddr),
+			dev->bulk_in_buffer,
+			min (dev->bulk_in_size, count),
+			&count, HZ*10);
+
+  /* if the read was successful, copy the data to userspace */
+  if (!retval) {
+    if (copy_to_user (buffer, dev->bulk_in_buffer, count)) {
+      kdebug(("error from copy_to_user"));
+      retval = -EFAULT;
+    }
+    else
+      retval = count;
+  }
+  else 
+    kdebug(("No data recivied"));
+  
+  /* unlock the device */
+  up (&dev->sem);
+  return retval;
+}
+
+
+/*__________________________________________________________________*/
+/** Call-back of @c write system call 
+ * 
+ *  A device driver has to decide how to report I/O errors back to the
+ *  user.  The safest course is to wait for the transfer to finish
+ *  before returning so that any errors will be reported reliably.
+ *  altro_read() works like this.  But waiting for I/O is slow, so many
+ *  drivers only check for errors during I/O initiation and do not
+ *  report problems that occur during the actual transfer.  That's
+ *  what we will do here.
+ *
+ *  A driver concerned with maximum I/O throughput would use double-
+ *  buffering: Two urbs would be devoted to write transfers, so that
+ *  one URB could always be active while the other was waiting for the
+ *  user to send more data.
+ *
+ *  @param file File the user is writing to 
+ *  @param buffer The data the user is writing 
+ *  @param count The size of @a buffer in bytes 
+ *  @param ppos Not used. 
+ *  @return The actual number of bytes written, or negative error code
+ *  on failure 
+ *  @ingroup altro_driver 
+ */
+static ssize_t 
+altro_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) 
+{
+  struct altro_device* dev;
+  ssize_t            bytes_written = 0;
+  int                retval        = 0;
+
+  dev = (struct altro_device *)file->private_data;
+  kdebug(("minor %d, count = %d\n", dev->minor, count)); 
+
+  /* lock this object */ 
+  down (&dev->sem); 
+
+  /* verify that the device wasn't unplugged */ 
+  if (!dev->present) { 
+    kdebug(("Error: Device was unplugged!\n")); 
+    retval = -ENODEV; 
+    goto exit; 
+  }
+
+  kdebug(("function called for end-point 0x%08x\n"
+	  "  bulk_in_size: %d", dev->bulk_in_endpointAddr, dev->bulk_in_size));
+
+  /* verify that we actually have some data to write */ 
+  if (count == 0) { 
+    kdebug(("write request of 0 bytes\n")); 
+    goto exit; 
+  } 
+
+  /* wait for a previous write to finish up; we don't use a timeout
+   * and so a nonresponsive device can delay us indefinitely.
+   */
+  if (atomic_read (&dev->write_busy))
+    wait_for_completion (&dev->write_finished);
+
+  /* we can only write as much as our buffer will hold */
+  bytes_written = min (dev->bulk_out_size, count);
+
+  /* copy the data from userspace into our transfer buffer;
+   * this is the only copy required.
+   */
+  if (copy_from_user(dev->write_urb->transfer_buffer, buffer, bytes_written)) {
+    kdebug(("error from copy_from_user"));
+    retval = -EFAULT;
+    goto exit;
+  }
+
+  altro_debug_data (__FUNCTION__, bytes_written, 
+		  dev->write_urb->transfer_buffer);
+
+  /* this urb was already set up, except for this write size */
+  dev->write_urb->transfer_buffer_length = bytes_written;
+
+  /* send the data out the bulk port */
+  /* a character device write uses GFP_KERNEL, unless a spinlock is held */
+  init_completion (&dev->write_finished);
+  atomic_set (&dev->write_busy, 1);
+  retval = usb_submit_urb(dev->write_urb, GFP_KERNEL);
+  if (retval) {
+    atomic_set (&dev->write_busy, 0);
+    kdebug(("No data sent"));
+    err("%s - failed submitting write urb, error %d", __FUNCTION__, retval); 
+  } else {
+    kdebug(("%d bytes sent", bytes_written));
+    retval = bytes_written; 
+  }
+
+ exit:
+  /* unlock the device */
+  up (&dev->sem);
+
+  return retval;
+}
+
+/*__________________________________________________________________*/
+
+// Turn Jiffies into milliseconds.  Since 2.6.12, the time-out
+// parameter of usb_bulk_msg should be in seconds, not jiffies. 
+#if HZ == 1000
+# define JIFFIES_TO_MSECS(x) (x)
+# define MSECS_TO_JIFFIES(x) (x)
+#elif HZ == 100
+# define JIFFIES_TO_MSECS(x) ((x) * 10)
+# define MSECS_TO_JIFFIES(x) (((x) + 9) / 10)
+#else
+# define JIFFIES_TO_MSECS(x) (((x) * 1000) / HZ)
+# define MSECS_TO_JIFFIES(x) (((x) * HZ + 999) / 1000)
+#endif
+#if  LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11) 
+# if HZ == 1000
+#  define TIMEOUT(x) (x)
+# elif HZ == 100
+#  define TIMEOUT(x) ((x) * 10)
+# else 
+#  define TIMEOUT(x) (((x)  * 1000) / HZ)
+# endif
+#else 
+# define  TIMEOUT(x) (x)
+#endif
+
+/** Call-back for the @c ioctl system call.  This driver understands
+ *  three commands 
+ *  <dl>
+ *    <dt> @c SEND_DATA </dt>
+ *    <dd> Send data to the ALTRO device.  In this case, the input
+ *      parameter @a arg is taken to be a pointer to an @c
+ *      altro_bulk_out_t variable allocated by the user. </dd>
+ *    <dt> @c GET_DATA </dt>
+ *    <dd> Get data from the ALTRO device.  In this case, the input
+ *      parameter @a arg is taken to be a pointer to an @c
+ *      altro_bulk_in_t variable allocated by the user. </dd>
+ *    <dt> @c CONTROL </dt>
+ *    <dd> Control message to the ALTRO device.  In this case, the input
+ *      parameter @a arg is taken to be a pointer to an @c
+ *      altro_control_t variable allocated by the user. </dd>
+ *  </dl>
+ *  @param inode Node doing the I/O control on 
+ *  @param file File doing the I/O control on 
+ *  @param cmd The command word 
+ *  @param arg Arguments to the command 
+ *  @return 0 on success, error code otherwise 
+ *  @ingroup altro_driver 
+ */
+static int 
+altro_ioctl(struct inode *inode, struct file *file, 
+	  unsigned int cmd, unsigned long arg)
+{
+  struct altro_device *dev;
+  int retval = 0, pipe;
+  kdebug(("function called %s\n", 
+	  (cmd == GET_DATA ? "GET_DATA" :
+	   (cmd == SEND_DATA ? "SEND_DATA" : 
+	    (cmd == CONTROL ? "CONTROL" : "unknown")))));
+  
+  // Get the device 
+  dev = (struct altro_device*)file->private_data;
+  kdebug(("test is %d\n", dev->test));
+  
+  /* lock this object */
+  down (&dev->sem);
+
+  /* verify that the device wasn't unplugged */
+  if (!dev->present) {
+    kdebug(("Error: Device was unplugged!\n"));
+    retval = -ENODEV;
+    goto ioctl_return;
+  }
+  kdebug(("minor %d, cmd 0x%.4x, arg %ld\n", dev->minor, cmd, arg));
+
+  /* fill in your device specific stuff here */
+  switch (cmd) {
+  case GET_DATA: {
+    altro_bulk_in_t params;
+    kdebug(("GET_DATA called for endpoint 0x%08x\n", 
+	    dev->bulk_in_endpointAddr));
+    kdebug(("in bulk size is %d\n", dev->bulk_in_size));
+
+#if 0
+    /* see if we alread in the middle of a write */
+    if (dev->read_urb->status == -EINPROGRESS) {
+      kdebug(("The bulk in URB is current in use\n"));
+      up(&dev->sem);
+      return (-ALTRO_EFAULT);
+    }
+#endif
+
+    /* Set up our URB */
+    pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr);
+    kdebug(("writing on pipe %d\n", pipe));
+    
+    /* do an immediate bulk read to get data from the device */
+    retval = usb_bulk_msg(dev->udev, pipe, &(params.data[0]), 
+			  dev->bulk_in_size, &(params.nbytes), 
+			  TIMEOUT(HZ * 10));
+    kdebug(("USB bulk message returns %d\n",retval));
+    if (retval) {
+      kdebug(("no data recieved!\n"));
+      params.nbytes = 0;
+    }
+    else 
+      kdebug(("%d bytes recieved\n", params.nbytes));
+    
+    /** Copy data to user */
+    if (copy_to_user((void*)arg, &params, sizeof(altro_bulk_in_t)) != 0){
+      kdebug(("error when copying to user\n"));
+      retval = -ALTRO_EFAULT;
+    }
+    break;
+  }
+  case SEND_DATA: {
+    altro_bulk_out_t params;
+    int maxp, ndone;
+    kdebug(("SEND_DATA called for endpoint 0x%08x\n", 
+	    dev->bulk_out_endpointAddr));
+    kdebug(("in bulk size is %d\n", dev->bulk_out_size));
+
+    /** Copy data from user */
+    if (copy_from_user(&params, (void*)arg, sizeof(altro_bulk_out_t))!= 0){
+      kdebug(("error when copying from user\n"));
+      retval = -ALTRO_EFAULT;
+      goto ioctl_return;
+    }
+
+    /* Set up our URB */
+    pipe = usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr); 
+    kdebug(("reading from pipe %d\n", pipe));
+    maxp = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
+    if (maxp > dev->bulk_out_size) maxp = dev->bulk_out_size;
+    kdebug(("it is possible to send %d bytes\n", maxp));
+    
+    /* Check if we would write more data than possible */
+    if (params.nbytes > maxp) {
+      kdebug(("cannot write %d bytes to pipe of %d bytes\n", 
+		params.nbytes, maxp));
+      retval = -ALTRO_EFAULT;
+      goto ioctl_return;
+    }
+
+    kdebug(("trying to sen %d bytes\n", params.nbytes));
+    /* do an immediate bulk write to send data to the device */
+    retval = usb_bulk_msg(dev->udev, pipe, &(params.data[0]), 
+			  params.nbytes, &ndone, 
+			  TIMEOUT(HZ * 10));
+    kdebug(("USB bulk message returns %d\n",retval));
+    if (retval) {
+      kdebug(("no data sent!\n"));
+      params.nbytes = 0;
+    }
+    else 
+      kdebug(("%d bytes sent\n", params.nbytes));
+  } // SEND_DATA
+    break;
+  case CONTROL: {
+    altro_control_t params;
+    kdebug(("CONTROL called"));
+    
+    /** Copy data from user */
+    if (copy_from_user(&params, (void*)arg, sizeof(altro_control_t)) != 0){
+      kdebug(("error when copying from user\n"));
+      retval = -ALTRO_EFAULT;
+      goto ioctl_return;
+    }
+    
+    kdebug(("CONTROL: bRequest      = %d\n", params.bRequest));   
+    kdebug(("CONTROL: bmRequestType = %d\n", params.bmRequestType));
+    kdebug(("CONTROL: wValue        = %d\n", params.wValue));
+    kdebug(("CONTROL: wIndex        = %d\n", params.wIndex));
+    kdebug(("CONTROL: data[0]       = %d\n", params.data[0]));
+    kdebug(("CONTROL: wLength       = %d\n", params.wLength));
+    
+    retval = usb_control_msg(dev->udev, 
+			     usb_rcvctrlpipe(dev->udev, 0),
+			     params.bRequest, 
+			     params.bmRequestType,
+			     params.wValue,
+			     params.wIndex,
+			     &(params.data[0]),  
+			     params.wLength, TIMEOUT(HZ));	  
+    if (retval) {
+      kdebug(("error when sending control word: %d\n", retval));
+      retval = -ALTRO_EFAULT;
+    }
+    break;
+  }// case CONTROL:
+  default:
+    retval = -ENOTTY;
+    break;
+  } // switch (cmd)
+  
+ ioctl_return:  
+  /* unlock the device */
+  up (&dev->sem);
+
+  /* return that we did not understand this ioctl call */
+  return retval; /* (retval ? -ENOTTY : 0); */
+}
+
+
+/*__________________________________________________________________*/
+/** Call back when writing and URB bulk message 
+ *  @param urb The URB (USB Request Block) that was sent 
+ *  @param regs 
+ *  @ingroup altro_driver 
+ */
+static void
+altro_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+{
+  struct altro_device *dev = (struct altro_device *)urb->context;
+
+  kdebug(("minor %d\n", dev->minor));
+
+  /* sync/async unlink faults aren't errors */
+  if (urb->status && !(urb->status == -ENOENT ||
+		       urb->status == -ECONNRESET)) {
+    kdebug(("nonzero write bulk status received: %d", urb->status));
+  }
+  
+  /* notify anyone waiting that the write has finished */
+  atomic_set (&dev->write_busy, 0);
+  complete (&dev->write_finished);
+}
+
+/*__________________________________________________________________*/
+/** Called by the usb core when a new device is connected that it
+ *  thinks this driver might be interested in. 
+ * 
+ *  @param interface The interface that the driver may want to handle 
+ *  @param id USB device ID of the device recently plugged in.
+ *  @return 0 if the driver want's to handle the device plugged in;
+ *  otherwise an error code. 
+ *  @ingroup altro_driver 
+ */
+static int 
+altro_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+  struct usb_device *udev                   = interface_to_usbdev(interface);
+  struct altro_device *dev                    = NULL;
+  struct usb_host_interface *iface_desc     = 0;
+  struct usb_endpoint_descriptor *endpoint  = 0;
+  size_t buffer_size;
+  int i;
+  int retval = -ENOMEM;
+
+  kdebug(("checking if we want to handle this device %d:%d (%d:%d)",
+	  udev->descriptor.idVendor, udev->descriptor.idProduct,
+	  USB_ALTRO_VENDOR_ID, USB_ALTRO_PRODUCT_ID));
+  /* See if the device offered us matches what we can accept */
+  if ((udev->descriptor.idVendor != USB_ALTRO_VENDOR_ID)) 
+    return -ENODEV;
+  /* See if the device offered us matches what we can accept */
+  switch (udev->descriptor.idProduct) {
+  case USB_ALTRO_PRODUCT_ID: break; // Old card
+  case USB_ALTRO_U2F_ID:     break;
+  case USB_ALTRO_GOFFIE_ID:  break; 
+  case USB_ALTRO_MPT_ID:     break;
+  default: 
+    return -ENODEV;
+  }
+  kdebug(("got a %s card (%X,%X)", 
+	  (char*)(id->driver_info),
+	  udev->descriptor.idVendor, udev->descriptor.idProduct));
+  
+  /* allocate memory for our device state and initialize it */
+  dev = kmalloc (sizeof(struct altro_device), GFP_KERNEL);
+  if (dev == NULL) {
+    err ("Out of memory");
+    return -ENOMEM;
+  }
+  memset (dev, 0x00, sizeof (*dev));
+
+  dev->name = (char*)id->driver_info;
+  init_MUTEX (&dev->sem);
+  dev->udev      = udev;
+  dev->interface = interface;
+
+  /* set up the endpoint information */
+  iface_desc = &interface->altsetting[0];
+  if (iface_desc->desc.bNumEndpoints != 2) {
+    kdebug(("Error: number of endpoints is %d (should be 2)", 
+	    iface_desc->desc.bNumEndpoints));
+    goto error;
+  }
+  
+  /* check out the endpoints */
+  /* use only the first bulk-in and bulk-out endpoints */
+  for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+    endpoint = &iface_desc->endpoint[i].desc;
+
+    if (/* !dev->bulk_in_endpointAddr && */
+	(endpoint->bEndpointAddress & USB_DIR_IN) &&
+	((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+	 == USB_ENDPOINT_XFER_BULK)) {
+      /* we found a bulk in endpoint */
+      if (!dev->bulk_in_endpointAddr) {
+	kdebug(("we found first bulk in endpoint\n"));
+	buffer_size               = endpoint->wMaxPacketSize;
+	dev->bulk_in_size         = buffer_size;
+	dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+	dev->bulk_in_buffer       = kmalloc(buffer_size, GFP_KERNEL);
+	kdebug(("bulk in endpoint address: %d\n", dev->bulk_in_endpointAddr));
+	if (!dev->bulk_in_buffer) {
+	  err("Couldn't allocate bulk_in_buffer");
+	  goto error;
+	}
+      }
+      else 
+	kdebug(("we found yet another bulk in endpoint!\n"));
+    }
+    else if (/* !dev->bulk_out_endpointAddr && */
+	     !(endpoint->bEndpointAddress & USB_DIR_IN) &&
+	     ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+	      == USB_ENDPOINT_XFER_BULK)) {
+      /* we found a bulk out endpoint */
+      if (!dev->bulk_out_endpointAddr) {
+	/* a probe() may sleep and has no restrictions on memory
+	   allocations */ 
+	dev->write_urb             = usb_alloc_urb(0, GFP_KERNEL);
+	if (!dev->write_urb) {
+	  err("No free urbs available");
+	  goto error;
+	}
+	dev->bulk_out_endpointAddr     = endpoint->bEndpointAddress;
+	buffer_size                    = endpoint->wMaxPacketSize;
+	dev->bulk_out_size             = buffer_size;
+	dev->write_urb->transfer_flags = (URB_NO_TRANSFER_DMA_MAP 
+					  /* | URB_ASYNC_UNLINK*/);
+	dev->bulk_out_buffer           = 
+	  usb_buffer_alloc(udev, buffer_size, GFP_KERNEL,
+			   &dev->write_urb->transfer_dma);
+	if (!dev->bulk_out_buffer) {
+	  err("Couldn't allocate bulk_out_buffer");
+	  goto error;
+	}
+	usb_fill_bulk_urb(dev->write_urb, udev,
+			  usb_sndbulkpipe(udev, endpoint->bEndpointAddress),
+			  dev->bulk_out_buffer, buffer_size,
+			  altro_write_bulk_callback, dev);
+      }
+      else 
+	kdebug(("we found yet another bulk out endpoint!\n"));
+    }
+    else 
+      kdebug(("we found an unidentifiable endpoint!\n"));
+  }
+  if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
+    err("Couldn't find both bulk-in and bulk-out endpoints");
+    goto error;
+  }
+
+  /* allow device read, write and ioctl */
+  dev->present = 1;
+
+  /* we can register the device now, as it is ready */
+  usb_set_intfdata(interface, dev);
+  retval = usb_register_dev(interface, &altro_class);
+  if (retval) {
+    /* something prevented us from registering this driver */
+    err ("Not able to get a minor for this device.");
+    usb_set_intfdata (interface, NULL);
+    goto error;
+  }
+
+  dev->minor = interface->minor;
+  /* _altro = 0; */
+  add_our_device(dev);
+  /* let the user know what node this device is now attached to */
+  info ("USB ALICE ALTRO device now attached to USB ALICE ALTRO-%d", 
+	dev->minor);
+  return 0;
+
+ error:
+  altro_delete (dev);
+  return retval;
+}
+
+
+/*__________________________________________________________________*/
+/** Called by the Usb core when the device is removed from the
+ *  system (the plug is pulled out, or the reset switch is pushed on
+ *  the board, or the power is cut to the board). 
+ *
+ *  This routine guarantees that the driver will not submit any more
+ *  URBS by clearing dev->udev.  It is also supposed to terminate any
+ *  currently active urbs.  Unfortunately, @c usb_bulk_msg(), used in
+ *  @c altro_read(), does not provide any way to do this.  But at least
+ *  we can cancel an active write.
+ *
+ *  @param interface The interface that was disconnected. 
+ *  @ingroup altro_driver 
+ */
+static void 
+altro_disconnect(struct usb_interface *interface)
+{
+  struct altro_device *dev;
+  int minor;
+
+  /* prevent races with open() */
+  down(&disconnect_sem);
+
+  dev = usb_get_intfdata(interface);
+  usb_set_intfdata(interface, NULL);
+
+  down(&dev->sem);
+  remove_our_device(dev);
+  
+  minor = dev->minor;
+
+  /* give back our minor */
+  usb_deregister_dev(interface, &altro_class);
+
+  /* terminate an ongoing write */
+  if (atomic_read(&dev->write_busy)) {
+    usb_unlink_urb(dev->write_urb);
+    wait_for_completion(&dev->write_finished);
+  }
+
+  /* prevent device read, write and ioctl */
+  dev->present = 0;
+
+  up(&dev->sem);
+
+  /* if the device is opened, altro_release will clean this up */
+  if (!dev->open)
+    altro_delete(dev);
+
+  up (&disconnect_sem);
+
+  info("USB ALICE ALTRO #%d now disconnected", minor);
+}
+
+/*********************************************************************/
+/** User writing to the ALTRO proc entry 
+ *  @param file The file descriptor
+ *  @param buffer Buffer of @a count size 
+ *  @param count The size of buffer (max 99)
+ *  @param data The data 
+ *  @ingroup altro_driver 
+ *  @return  
+ */
+static int 
+altro_proc_write(struct file *file, const char *buffer, 
+	       unsigned long count, void *data)
+{
+  int len;
+  struct altro_proc_data_t *fb_data = (struct altro_proc_data_t *)data;
+  
+  kdebug(("user is writing to /proc/altro\n"));
+
+  if(count > 99) len = 99;
+  else           len = count;
+
+  if (copy_from_user(fb_data->value, buffer, len)) {
+    kdebug(("error when copying from user\n"));
+    return(-EFAULT);
+  }
+
+  kdebug(("length is %d\n", len));
+  fb_data->value[len - 1] = '\0';
+  kdebug(("text passed is \"%s\"\n", fb_data->value));
+ 
+  if (!strcmp(fb_data->value, "debug")) {
+    debug = 1;
+    kdebug(("debugging enabled\n")); 
+  }
+ 
+  if (!strcmp(fb_data->value, "nodebug")) {
+    kdebug(("debugging disabled\n")); 
+    debug = 0; 
+  }
+  
+  if (!strcmp(fb_data->value, "dec")) {
+    module_put(THIS_MODULE);
+    /* MOD_DEC_USE_COUNT; */
+    kdebug(("Use count decremented\n"));
+  }
+
+  if (!strcmp(fb_data->value, "inc")) {
+    try_module_get(THIS_MODULE);
+    /* MOD_INC_USE_COUNT; */
+    kdebug(("Use count incremented\n"));
+  }
+  return len;
+}
+
+/*__________________________________________________________________*/
+/** User Reading from the ALTRO proc entry
+ *  @param page   Page to read into 
+ *  @param start  Points to begining of text on output
+ *  @param off    Points to offset of the text in the page 
+ *  @param count  Size of page 
+ *  @param eof    Wheter to set end of file 
+ *  @param data   The data 
+ *  @ingroup altro_driver 
+ *  @return The length 
+ */
+static int
+altro_proc_read(char *page, char **start, off_t off, 
+	      int count, int *eof, void *data)
+{
+  int len;
+  u_int i;
+  
+  kdebug(("user is reading /proc/altro\n"));
+
+  len =  sprintf(page, "ALICE USB-ALTRO driver\n\n");
+  len += sprintf(page + len, "Minor device number:\t0x%x\n", 
+		 USB_ALTRO_MINOR_BASE);
+  len += sprintf(page + len, "Vendor/product ID:\t0x%x/0x%x\n\n", 
+		 USB_ALTRO_VENDOR_ID, USB_ALTRO_PRODUCT_ID);
+  for (i = 0; i < n_our_devices; i++) {
+    len += sprintf(page + len, "\tDevice:\t %s (0x%x)\n", 
+		   our_devices[i]->name, our_devices[i]->minor);
+  }
+  len += sprintf(page + len, " \n");
+  len += sprintf(page + len, "The command 'echo <action> > /proc/altro', "
+		 "executed as root,\n");
+  len += sprintf(page + len, "allows you to interact with the driver. "
+		 "Possible actions are:\n");
+  len += sprintf(page + len, "debug   -> enable debugging\n");
+  len += sprintf(page + len, "nodebug -> disable debugging\n");
+  len += sprintf(page + len, "dec     -> Decrement use count\n");
+  len += sprintf(page + len, "inc     -> Increment use count\n");
+
+  *eof = 1;
+  *start = page + off;
+  len -= off;
+
+  if (len > count) len = count;
+  return (len);
+}
+
+/*__________________________________________________________________*/
+/** Function called when the driver is loaded. 
+ *  @return 0 on success or error code otherwise 
+ *  @ingroup altro_driver 
+ */
+static int __init 
+usb_altro_init(void)
+{
+  int result;
+  // Install `/proc' entry 
+  altro_proc_file = create_proc_entry("altro", 0644, NULL);
+  if (altro_proc_file == NULL) {
+    err("create_proc_entry failed");
+    return -ENOMEM;
+  }
+  strcpy(altro_proc_data.name, "altro");
+  strcpy(altro_proc_data.value, "altro");
+  altro_proc_file->data       = &altro_proc_data;
+  altro_proc_file->read_proc  = altro_proc_read;
+  altro_proc_file->write_proc = altro_proc_write;
+  altro_proc_file->owner      = THIS_MODULE;
+
+  /* register this driver with the USB subsystem */
+  result = usb_register(&altro_driver);
+  if (result) {
+    err("usb_register failed. Error number %d", result);
+    return result;
+  }
+  
+  info(DRIVER_DESC " " DRIVER_VERSION);
+  info("ALTRO: debug is %d", debug);
+  return 0;
+}
+
+
+/*__________________________________________________________________*/
+/** Function called when the driver is unloaded via @c rmmod or
+ *  otherwise.
+ *  @ingroup altro_driver 
+ */
+static void __exit 
+usb_altro_exit(void)
+{
+  /* deregister this driver with the PROC subsystem */
+  remove_proc_entry("altro", NULL);
+  
+  /* deregister this driver with the USB subsystem */
+  usb_deregister(&altro_driver);
+}
+  
+/*__________________________________________________________________*/
+module_init(usb_altro_init);
+module_exit(usb_altro_exit);
+// int init_module() 
+// {
+//   return usb_altro_init();
+// }
+// void cleanup_module() 
+// {
+//   usb_altro_exit();
+// }
+
+
+/*__________________________________________________________________*/
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
+
+/*__________________________________________________________________
+ *
+ * EOF
+ */
diff -u -r -N -xCVS u2f.cern/driver/load.sh u2f/driver/load.sh
--- u2f.cern/driver/load.sh	1970-01-01 01:00:00.000000000 +0100
+++ u2f/driver/load.sh	2006-01-26 04:03:43.000000000 +0100
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# set -e 
+export PATH=$PATH:/usr/sbin:/sbin
+
+if `grep -q altro_driver /proc/modules > /dev/null 2>&1` ; then 
+    echo -n "Removing driver ... "
+    rmmod -f altro_driver
+    sleep 1
+    echo "done"
+fi
+
+echo -n "Installing driver ... "
+insmod driver/altro_driver.ko debug=1
+if test $? -ne 0 ; then 
+	exit 1
+fi
+sleep 1
+echo "done"
+
+echo -n "Making devices ... "
+major=`grep usb /proc/devices | awk '{print $1}'`
+minors=`grep Device: /proc/altro | awk '{print $3}' | tr -d '()'`
+i=0
+for minor in $minors ; do 
+    if test ! -c /dev/altro$i ; then 
+	mknod /dev/altro$i c $major $minor 
+    fi
+    let i=$i+1
+done
+echo "done (total of $i devices)"
+
+echo -n "Changing permissions on device ... "
+for dev in /dev/altro? ; do 
+    if test -c $dev ; then
+	chmod 666 $dev 
+    fi
+done
+echo "done"
+
+#
+# EOF
+#
diff -u -r -N -xCVS u2f.cern/driver/unused_24.c u2f/driver/unused_24.c
--- u2f.cern/driver/unused_24.c	1970-01-01 01:00:00.000000000 +0100
+++ u2f/driver/unused_24.c	2006-01-26 04:03:43.000000000 +0100
@@ -0,0 +1,424 @@
+/*********************************************************************
+ *
+ * Prototypes 
+ */
+static void rcu_irq(struct urb *urb);
+static void rcu_write_irq(struct urb *urb);
+static void rcu_read_irq(struct urb *urb);
+
+/*********************************************************************
+ * 
+ * Handler for data sent in by the device. The function is called by
+ * the USB kernel subsystem whenever a device spits out new data 
+ */
+static void rcu_irq(struct urb *urb)
+{
+  struct rcu_device *rcu = urb->context;
+  char *pos = rcu->output;
+  int i;
+  
+  kdebug(("rcu_drv(rcu_irq): function called\n"));
+  
+  if (urb->status != USB_ST_NOERROR) { 
+    kdebug(("rcu_drv(rcu_irq): ERROR urb->status != USB_ST_NOERROR\n"));
+    return;
+  }
+
+  pos += sprintf(pos, "rcu: data from %-8s =", rcu->name);
+  for (i=0; i<rcu->maxp; i++) 
+    pos += sprintf(pos, " %02x", rcu->data[i]);
+  
+  kdebug(("rcu_drv(rcu_irq): %s\n", rcu->output));
+}
+
+
+/*********************************************************************
+ * 
+ * Handler for error checking after data das been sent out to the device 
+ */
+static void rcu_write_irq(struct urb *urb)
+{
+  struct rcu_device *rcu = (struct rcu_device *)urb->context;
+
+  kdebug(("rcu_drv(rcu_write_irq): function called\n"));
+
+  //usb-skeleton: if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) 
+  if (urb->status) {
+    kdebug(("rcu_drv(rcu_write_irq): nonzero write bulk status received: %d\n",  urb->status));
+    return;
+  }
+
+  urbdone = 1;
+  kdebug(("rcu_drv(rcu_write_irq): function done\n"));
+  return;
+}
+
+
+/*********************************************************************
+ * 
+ * Handler for error checking after data das been sent out to the
+ * device 
+ */
+static void rcu_read_irq(struct urb *urb)
+{
+  struct rcu_device *rcu = (struct rcu_device *)urb->context;
+
+  kdebug(("rcu_drv(rcu_read_irq): function called\n"));
+
+  if (urb->status) {
+    kdebug(("rcu_drv(rcu_read_irq): nonzero write bulk status received: %d\n",  urb->status));
+    return;
+  }
+
+  urbdone = 1;
+  kdebug(("rcu_drv(rcu_read_irq): function done\n"));
+  return;
+}
+
+/*********************************************************************
+ * 
+ * These two callbacks are invoked when an USB device is detached or
+ * attached to the bus
+ */ 
+static void *rcu_probe(struct usb_device *udev, unsigned int ifnum, 
+		       const struct usb_device_id *id)
+{
+  /* The probe procedure is pretty standard. Device matching has already */
+  /* been performed based on the id_table structure */
+
+  struct usb_interface *iface;
+  struct usb_interface_descriptor *interface;
+  struct usb_endpoint_descriptor *endpoint;
+  struct rcu_device *rcu;
+  char name[10];
+  int ecode, i, buffer_size, inok, outok;
+
+  kdebug(("rcu_drv(rcu_probe): probe called for %s device\n", (char *)id->driver_info));
+  kdebug(("rcu_drv(rcu_probe): ifnum = %d\n", ifnum));
+
+  /* allocate and zero a new data structure for the new device */
+  rcu = kmalloc(sizeof(struct rcu_device), GFP_KERNEL);
+  if (!rcu) { 
+    kdebug(("rcu_drv(rcu_probe): ERROR failed to kmalloc rcu_device\n"));
+    return NULL; /* failure */
+  }
+  
+  memset(rcu, 0, sizeof(*rcu));
+  rcu->name = (char *)id->driver_info;
+  init_MUTEX(&rcu->sem);
+
+  iface = &udev->actconfig->interface[ifnum];
+  interface = &iface->altsetting[iface->act_altsetting];
+
+  if (interface->bNumEndpoints != 2) {
+    kdebug(("rcu_drv(rcu_probe): ERROR interface->bNumEndpoints "
+	    "!= 3 (number = %d)\n", interface->bNumEndpoints));
+    return NULL;
+  }
+  
+  inok = 0;
+  outok = 0;
+    
+  for (i = 0; i < interface->bNumEndpoints; ++i) {
+    kdebug(("rcu_drv(rcu_probe): Processing endpoint %d ...\n", i));
+    endpoint = &interface->endpoint[i];
+    
+    if ((endpoint->bEndpointAddress & 0x80) && 
+	((endpoint->bmAttributes & 3) == 0x02)) {
+      if (!inok) {
+        kdebug(("rcu_drv(rcu_probe): we found the first bulk in endpoint\n"));
+	buffer_size = endpoint->wMaxPacketSize;
+	kdebug(("rcu_drv(rcu_probe): buffer_size = %d\n", buffer_size));
+	rcu->bulk_in_size = buffer_size;
+	rcu->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+	kdebug(("rcu_drv(rcu_probe): bulk_in_endpointAddr = %d\n", rcu->bulk_in_endpointAddr));
+	rcu->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+	if (!rcu->bulk_in_buffer) {
+          kdebug(("rcu_drv(rcu_probe): Couldn't allocate bulk_in_buffer"));
+          return NULL;
+	}
+	inok = 1;
+      }
+      else
+        kdebug(("rcu_drv(rcu_probe): we found another bulk in endpoint\n"));
+    }
+    
+    else if (((endpoint->bEndpointAddress & 0x80) == 0x00) && 
+	     ((endpoint->bmAttributes & 3) == 0x02)) {
+      if (!outok) {
+	kdebug(("rcu_drv(rcu_probe): we found the first bulk out endpoint\n"));
+	rcu->write_urb = usb_alloc_urb(0);
+	if (!rcu->write_urb) {
+          kdebug(("rcu_drv(rcu_probe): No free urbs available"));
+          return NULL;
+	}
+	buffer_size = endpoint->wMaxPacketSize;
+	kdebug(("rcu_drv(rcu_probe): buffer_size = %d\n", buffer_size));
+	rcu->bulk_out_size = buffer_size;
+	rcu->bulk_out_endpointAddr = endpoint->bEndpointAddress;
+	kdebug(("rcu_drv(rcu_probe): bulk_out_endpointAddr = %d\n", rcu->bulk_out_endpointAddr));
+	rcu->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
+	if (!rcu->bulk_out_buffer) {
+          kdebug(("rcu_drv(rcu_probe): Couldn't allocate bulk_out_buffer"));
+          return NULL;
+	}
+	outok = 1;
+      }	
+
+      else
+        kdebug(("rcu_drv(rcu_probe): we found another bulk out endpoint\n"));
+    }
+    else
+      {
+	kdebug(("rcu_drv(rcu_probe): we found an unidentifiable endpoint\n"));
+	return NULL;
+    }
+  }
+  
+  kdebug(("rcu_drv(rcu_probe): Setting protocol\n"));
+  usb_set_protocol(udev, interface->bInterfaceNumber, 0);
+  kdebug(("rcu_drv(rcu_probe): Setting idle\n"));
+  usb_set_idle(udev, interface->bInterfaceNumber, 0, 0);
+  
+  kdebug(("rcu_drv(rcu_probe): Preparing URB\n"));
+  /* fill the URB data structure using the FILL_INT_URB macro */
+  {
+    int pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+    int maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+    kdebug(("rcu_drv(rcu_probe): pipe = %d\n", pipe));
+    kdebug(("rcu_drv(rcu_probe): maxp = %d\n", maxp));
+    
+    if (maxp > 512) maxp = 512; 
+    rcu->maxp = maxp; /* remember for later */
+    kdebug(("rcu_drv(rcu_probe): maxp(2) = %d\n", maxp));
+    kdebug(("rcu_drv(rcu_probe): endpoint->bInterval = %d\n", endpoint->bInterval));
+    FILL_INT_URB(&rcu->urb, udev, pipe, rcu->data, maxp, rcu_irq, rcu, endpoint->bInterval);
+  }
+  
+  kdebug(("rcu_drv(rcu_probe): Registering URB\n"));
+  /* register the URB within the USB subsystem */
+  ecode = usb_submit_urb(&rcu->urb);
+  if (ecode) {
+    kfree(rcu);
+    kdebug(("rcu_drv(rcu_probe): ERROR  failed to register URB (ecode = %d)\n", ecode));
+    return NULL;
+  }
+  kdebug(("rcu_drv(rcu_probe): Probe successful for %s (maxp is %i)\n", rcu->name, rcu->maxp));
+  
+  rcu->udev = udev;
+
+
+  //  This code is from the usb-skeleton.c template. It seems however,
+  //  that CERN Linux kernels do not offer the CONFIG_DEVFS_FS
+  //  option. Therefore we cannot use it
+
+  /* initialize the devfs node for this device and register it */
+  sprintf(name, "rcu");
+  /* MJ: So far we can only support one RCU card. For multiple cards
+     the node name has to have an occurence number */
+  kdebug(("rcu_drv(rcu_probe): calling devfs_register\n"));
+  rcu->devfs = devfs_register (usb_devfs_handle, name, 
+			       DEVFS_FL_DEFAULT, USB_MAJOR, 
+			       RCU_MINOR_BASE + rcu->minor,
+			       S_IFCHR | S_IRUSR | S_IWUSR | 
+			       S_IRGRP | S_IWGRP | S_IROTH, 
+			       &rcu_fops, NULL);
+  kdebug(("rcu_drv(rcu_probe): devfs_register done\n"));
+  /* let the user know what node this device is now attached to */
+  kdebug(("rcu_drv(rcu_probe): RCU device now attached to "
+	  "major number=%d, minor number=%d\n", 
+	  USB_MAJOR, RCU_MINOR_BASE + rcu->minor));
+
+  rcu->test = 1; 
+  rcup = rcu;
+  kdebug(("rcu_drv(rcu_probe): End of function\n"));
+  
+  return rcu;
+}
+
+/*********************************************************************
+ * 
+ */ 
+static int rcu_ioctl (struct inode *inode, struct file *file, 
+		      unsigned int cmd, unsigned long arg)
+{
+  struct rcu_device *rcu;
+  int pipe, maxp, retval;
+  
+  kdebug(("rcu_drv(rcu_ioctl): function called\n")); 
+  kdebug(("rcu_drv(rcu_ioctl): minor number = %d\n", MINOR (inode->i_rdev)));
+
+  rcu = (struct rcu_device *)file->private_data;
+  kdebug(("rcu_drv(rcu_ioctl): rcu->test = %d\n", rcu->test)); 
+
+  /* lock this object */
+  down (&rcu->sem);
+  kdebug(("rcu_drv(rcu_ioctl): semaphore locked\n")); 
+
+  /* verify that the device wasn't unplugged */
+  if (rcu->udev == NULL) 
+  {
+    up (&rcu->sem);
+    kdebug(("rcu_drv(rcu_ioctl): ERROR device was unplugged\n"));
+    return -ENODEV;
+  }
+  kdebug(("rcu_drv(rcu_ioctl): The device is still connected\n")); 
+
+  switch (cmd)
+  {    
+  case SEND_DATA: {
+    rcu_bulk_out_t params;
+    
+    kdebug(("rcu_drv(ioctl:SEND_DATA): start of function\n"));
+    kdebug(("rcu_drv(ioctl:SEND_DATA): function called for endpoint "
+	    "0x%08x\n", rcu->bulk_out_endpointAddr));
+    
+     /* see if we are already in the middle of a write */
+     if (rcu->write_urb->status == -EINPROGRESS) {
+       kdebug(("rcu_drv(ioctl:SEND_DATA): the BULK out URB is in use\n"));
+       up (&rcu->sem);
+       return(-RCU_EFAULT);
+     }
+
+     if (copy_from_user(&params, (void *)arg, 
+			sizeof(rcu_bulk_out_t)) !=0 ) {
+       kdebug(("rcu_drv(ioctl:SEND_DATA): error from " "copy_from_user\n"));
+       up (&rcu->sem);
+       return(-RCU_EFAULT);
+     }
+
+     /* set up our urb */
+     pipe = usb_sndbulkpipe(rcu->udev, rcu->bulk_out_endpointAddr);
+     maxp = usb_maxpacket(rcu->udev, pipe, usb_pipeout(pipe));
+     
+     if (maxp > rcu->bulk_out_size) maxp = rcu->bulk_out_size; 
+     rcu->maxp = maxp; /* remember for later */
+     kdebug(("rcu_drv(ioctl:SEND_DATA): it is possible to send %d bytes\n", 
+	     maxp));
+    
+     /* check if we would write more data than possible */
+     if (params.nbytes > maxp) {	
+       kdebug(("rcu_drv(ioctl:SEND_DATA): Cannot write %d bytes to "
+	       "pipe of %d bytes\n", params.nbytes, maxp));
+       up (&rcu->sem);
+       return(-RCU_EFAULT);
+     }
+     kdebug(("rcu_drv(ioctl:SEND_DATA): trying to send %d bytes\n", 
+	     params.nbytes));
+     kdebug(("rcu_drv(ioctl:SEND_DATA): dumping first four bytes\n"));
+     kdebug(("rcu_drv(ioctl:SEND_DATA): 1. byte = 0x%02x\n", params.data[0]));
+     kdebug(("rcu_drv(ioctl:SEND_DATA): 2. byte = 0x%02x\n", params.data[1]));
+     kdebug(("rcu_drv(ioctl:SEND_DATA): 3. byte = 0x%02x\n", params.data[2]));
+     kdebug(("rcu_drv(ioctl:SEND_DATA): 4. byte = 0x%02x\n", params.data[3]));
+     
+     usb_fill_bulk_urb(&rcu->urb, rcu->udev, pipe, &params.data[0], 
+		       params.nbytes, rcu_write_irq, rcu);
+     kdebug(("rcu_drv(ioctl:SEND_DATA): URB has beed filled\n"));
+     
+     /* register the URB within the USB subsystem */
+     retval = usb_submit_urb(&rcu->urb); 
+     if (retval) {
+       kdebug(("rcu_drv(ioctl:SEND_DATA): ERROR  failed to register URB. "
+	       "Error code = %d\n", retval));
+       up (&rcu->sem);
+       return(-RCU_EFAULT);
+     }
+     kdebug(("rcu_drv(ioctl:SEND_DATA): URB has beed submitted\n"));
+     break;
+  }
+  case GET_DATA: {   
+    rcu_bulk_in_t params;
+    
+    kdebug(("rcu_drv(ioctl:GET_DATA): start of function\n"));
+    kdebug(("rcu_drv(ioctl:GET_DATA): function called for endpoint "
+	    "0x%08x\n", rcu->bulk_in_endpointAddr));
+    
+    /* see if we are already in the middle of a write */
+    if (rcu->read_urb->status == -EINPROGRESS)  {
+      kdebug(("rcu_drv(ioctl:GET_DATA): the BULK in URB is in use\n"));
+      up (&rcu->sem); 
+      return(-RCU_EFAULT);
+    }
+
+    /* set up our urb */
+    pipe = usb_rcvbulkpipe(rcu->udev, rcu->bulk_in_endpointAddr);
+    maxp = usb_maxpacket(rcu->udev, pipe, usb_pipeout(pipe));
+    
+    if (maxp > rcu->bulk_in_size) 
+      maxp = rcu->bulk_in_size; 
+    rcu->maxp = maxp; /* remember for later */
+    kdebug(("rcu_drv(ioctl:GET_DATA): it is possible to receive %d bytes\n", 
+	    maxp));
+
+    usb_fill_bulk_urb(&rcu->urb, rcu->udev, pipe, &params.data[0], 
+		      BULK_IN_SIZE, rcu_read_irq, rcu);
+    kdebug(("rcu_drv(ioctl:GET_DATA): URB has beed filled\n"));
+     
+    /* register the URB within the USB subsystem */
+    retval = usb_submit_urb(&rcu->urb); 
+    if (retval) {
+      kdebug(("rcu_drv(ioctl:GET_DATA): ERROR  failed to register "
+	      "URB. Error code = %d\n", retval));
+      params.nbytes = 0;
+      up (&rcu->sem);
+      return(-RCU_EFAULT);
+    }
+    kdebug(("rcu_drv(ioctl:GET_DATA): URB has beed submitted\n"));
+
+    /// MJ: How does one best detect the end of a transfer?
+    kdebug(("rcu_drv(ioctl:GET_DATA): URB has beed completed\n"));
+    if (copy_to_user ((void *)arg, &params, 
+		      sizeof(rcu_bulk_in_t)) != 0)  {
+       kdebug(("rcu_drv(ioctl:GET_DATA): error from copy_to_user\n"));
+       up (&rcu->sem);
+       return(-RCU_EFAULT);
+    }
+    kdebug(("rcu_drv(ioctl:GET_DATA): data has been copied\n"));
+    
+    break;          
+  }    
+  case CONTROL: {
+    rcu_control_t params;
+    
+    kdebug(("rcu_drv(ioctl:CONTROL): function called\n"));
+    
+    if (copy_from_user(&params, (void *)arg, sizeof(rcu_control_t)) !=0 )  {
+      kdebug(("rcu_drv(ioctl:CONTROL): error from copy_from_user\n"));
+      up (&rcu->sem);
+      return(-RCU_EFAULT);
+    }
+
+    kdebug(("rcu_drv(ioctl:CONTROL): params.bRequest      = %d\n", 
+	    params.bRequest));
+    kdebug(("rcu_drv(ioctl:CONTROL): params.bmRequestType = %d\n", 
+	    params.bmRequestType));
+    kdebug(("rcu_drv(ioctl:CONTROL): params.wValue        = %d\n", 
+	    params.wValue));
+    kdebug(("rcu_drv(ioctl:CONTROL): params.wIndex        = %d\n", 
+	    params.wIndex));
+    kdebug(("rcu_drv(ioctl:CONTROL): params.data[0]       = %d\n", 
+	    params.data[0]));
+    kdebug(("rcu_drv(ioctl:CONTROL): params.wLength       = %d\n", 
+	    params.wLength));
+    
+    retval = usb_control_msg(rcu->udev, usb_rcvctrlpipe(rcu->udev,0), 
+			     params.bRequest, 
+			     params.bmRequestType, 
+			     params.wValue, 
+			     params.wIndex, 
+			     &params.data[0], 
+			     params.wLength, HZ);
+    if (retval) {
+      kdebug(("rcu_drv(ioctl:CONTROL): ERROR  failed to register control URB. "
+	      "Error code = %d\n", retval));
+      up (&rcu->sem);
+      return(-RCU_EFAULT);
+    }
+    break;
+  }
+  }
+  
+  /* unlock the device */
+  up (&rcu->sem);
+  return(0);
+}
diff -u -r -N -xCVS u2f.cern/driver/unused_26.c u2f/driver/unused_26.c
--- u2f.cern/driver/unused_26.c	1970-01-01 01:00:00.000000000 +0100
+++ u2f/driver/unused_26.c	2006-01-26 04:03:43.000000000 +0100
@@ -0,0 +1,275 @@
+//____________________________________________________________________
+/* local function prototypes */
+static ssize_t alice_rcu_read(struct file *file, char *buffer, 
+			      size_t count, loff_t *ppos);
+static ssize_t alice_rcu_write(struct file *file, const char *buffer, 
+			       size_t count, loff_t *ppos);
+static void alice_rcu_write_bulk_callback(struct urb *urb, 
+					  struct pt_regs *regs);
+
+
+//____________________________________________________________________
+/*
+ * File operations needed when we register this driver.
+ * This assumes that this driver NEEDS file operations,
+ * of course, which means that the driver is expected
+ * to have a node in the /dev directory. If the USB
+ * device were for a network interface then the driver
+ * would use "struct net_driver" instead, and a serial
+ * device would use "struct tty_driver".
+ */
+static struct file_operations alice_rcu_fops = {
+  /*
+   * The owner field is part of the module-locking
+   * mechanism. The idea is that the kernel knows
+   * which module to increment the use-counter of
+   * BEFORE it calls the device's open() function.
+   * This also means that the kernel can decrement
+   * the use-counter again before calling release()
+   * or should the open() function fail.
+   */
+  .read =	alice_rcu_read,
+  .write =	alice_rcu_write,
+};
+
+//____________________________________________________________________
+/**
+ * usb_alice_rcu_debug_data
+ */
+static inline void 
+usb_alice_rcu_debug_data(const char *function, int size, 
+			 const unsigned char *data)
+{
+  int i;
+  if (!debug) return;
+  printk(KERN_DEBUG __FILE__": %s - length = %d, data = ", function, size);
+  for (i = 0; i < size; ++i) printk ("%.2x ", data[i]);
+  printk ("\n");
+}
+
+
+//____________________________________________________________________
+/**
+ * alice_rcu_read
+ */
+static ssize_t 
+alice_rcu_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+  struct usb_alice_rcu *dev;
+  int retval = 0;
+
+  dev = (struct usb_alice_rcu *)file->private_data;
+  kdebug(("minor %d, count = %d", dev->minor, count));
+
+  /* lock this object */
+  down (&dev->sem);
+
+  /* verify that the device wasn't unplugged */
+  if (!dev->present) {
+    kdebug(("Error: Device was unplugged!\n"));
+    up (&dev->sem);
+    return -ENODEV;
+  }
+
+  /* do a blocking bulk read to get data from the device */
+  retval = usb_bulk_msg(dev->udev,
+			usb_rcvbulkpipe (dev->udev, dev->bulk_in_endpointAddr),
+			dev->bulk_in_buffer,
+			min (dev->bulk_in_size, count),
+			&count, HZ*10);
+
+  /* if the read was successful, copy the data to userspace */
+  if (!retval) {
+    if (copy_to_user (buffer, dev->bulk_in_buffer, count))
+      retval = -EFAULT;
+    else
+      retval = count;
+  }
+
+  /* unlock the device */
+  up (&dev->sem);
+  return retval;
+}
+
+
+//____________________________________________________________________
+/**
+ *	alice_rcu_write
+ *
+ *	A device driver has to decide how to report I/O errors back to
+ *	the user.  The safest course is to wait for the transfer to
+ *	finish before returning so that any errors will be reported
+ *	reliably.  alice_rcu_read() works like this.  But waiting for
+ *	I/O is slow, so many drivers only check for errors during I/O
+ *	initiation and do not report problems that occur during the
+ *	actual transfer.  That's what we will do here.
+ *
+ *	A driver concerned with maximum I/O throughput would use
+ *	double- buffering: Two urbs would be devoted to write
+ *	transfers, so that one urb could always be active while the
+ *	other was waiting for the user to send more data.
+ */
+static ssize_t 
+alice_rcu_write(struct file *file, const char *buffer, 
+		size_t count, loff_t *ppos)
+{
+  struct usb_alice_rcu *dev;
+  ssize_t bytes_written = 0;
+  int retval = 0;
+
+  dev = (struct usb_alice_rcu *)file->private_data;
+  kdebug(("minor %d, count = %d\n", dev->minor, count));
+
+  /* lock this object */
+  down (&dev->sem);
+
+  /* verify that the device wasn't unplugged */
+  if (!dev->present) {
+    kdebug(("Error: Device was unplugged!\n"));
+    retval = -ENODEV;
+    goto exit;
+  }
+
+  /* verify that we actually have some data to write */
+  if (count == 0) {
+    kdebug(("write request of 0 bytes\n"));
+    goto exit;
+  }
+
+  /* wait for a previous write to finish up; we don't use a timeout
+   * and so a nonresponsive device can delay us indefinitely.
+   */
+  if (atomic_read (&dev->write_busy))
+    wait_for_completion (&dev->write_finished);
+
+  /* we can only write as much as our buffer will hold */
+  bytes_written = min (dev->bulk_out_size, count);
+
+  /* copy the data from userspace into our transfer buffer;
+   * this is the only copy required.
+   */
+  if (copy_from_user(dev->write_urb->transfer_buffer, buffer,
+		     bytes_written)) {
+    retval = -EFAULT;
+    goto exit;
+  }
+
+  usb_alice_rcu_debug_data (__FUNCTION__, bytes_written,
+			    dev->write_urb->transfer_buffer);
+
+  /* this urb was already set up, except for this write size */
+  dev->write_urb->transfer_buffer_length = bytes_written;
+
+  /* send the data out the bulk port */
+  /* a character device write uses GFP_KERNEL,
+     unless a spinlock is held */
+  init_completion (&dev->write_finished);
+  atomic_set (&dev->write_busy, 1);
+  retval = usb_submit_urb(dev->write_urb, GFP_KERNEL);
+  if (retval) {
+    atomic_set (&dev->write_busy, 0);
+    err("%s - failed submitting write urb, error %d",
+	__FUNCTION__, retval);
+  } else {
+    retval = bytes_written;
+  }
+
+ exit:
+  /* unlock the device */
+  up (&dev->sem);
+
+  return retval;
+}
+
+//____________________________________________________________________
+/**
+ *	alice_rcu_write_bulk_callback
+ */
+static void 
+alice_rcu_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+{
+  struct usb_alice_rcu *dev = (struct usb_alice_rcu *)urb->context;
+
+  kdebug(("minor %d\n", dev->minor));
+
+  /* sync/async unlink faults aren't errors */
+  if (urb->status && !(urb->status == -ENOENT ||
+		       urb->status == -ECONNRESET)) {
+    kdebug(("nonzero write bulk status received: %d", urb->status));
+  }
+  
+  /* notify anyone waiting that the write has finished */
+  atomic_set (&dev->write_busy, 0);
+  complete (&dev->write_finished);
+}
+
+//____________________________________________________________________
+/** Handler for data sent in by the device. The function is called by  
+    the USB kernel subsystem whenever a device spits out new data
+    @param urb 
+*/
+static void rcu_irq(struct urb *urb)
+{
+  struct rcu_device *rcu = urb->context;
+  char *pos = rcu->output;
+  int i;
+  
+  kdebug(("rcu_drv(rcu_irq): function called\n"));
+
+  if (urb->status != USB_ST_NOERROR) { 
+    kdebug(("rcu_drv(rcu_irq): ERROR urb->status != USB_ST_NOERROR\n"));
+    return;
+  }
+
+  pos += sprintf(pos, "rcu: data from %-8s =", rcu->name);
+  for (i=0; i<rcu->maxp; i++) 
+    pos += sprintf(pos, " %02x", rcu->data[i]);
+  
+  kdebug(("rcu_drv(rcu_irq): %s\n", rcu->output));
+}
+
+//____________________________________________________________________
+/** Handler for error checking after data das been sent out to the
+    device  
+    @param urb 
+*/
+static void rcu_write_irq(struct urb *urb)
+{
+  struct rcu_device *rcu = (struct rcu_device *)urb->context;
+
+  kdebug(("rcu_drv(rcu_write_irq): function called\n"));
+
+  //usb-skeleton: 
+  //   if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) 
+  if (urb->status) {
+    kdebug(("rcu_drv(rcu_write_irq): nonzero write bulk status received: %d\n",
+	    urb->status));
+    return;
+  }
+  
+  urbdone = 1;
+  kdebug(("rcu_drv(rcu_write_irq): function done\n"));
+  return;
+}
+
+
+//____________________________________________________________________
+/** Handler for error checking after data das been sent out to the
+    device  
+    @param urb  */
+static void rcu_read_irq(struct urb *urb)
+{
+  struct rcu_device *rcu = (struct rcu_device *)urb->context;
+  
+  kdebug(("rcu_drv(rcu_read_irq): function called\n"));
+  
+  if (urb->status) {
+    kdebug(("rcu_drv(rcu_read_irq): nonzero write bulk status received: %d\n",
+	    urb->status));
+    return;
+  }
+  
+  urbdone = 1;
+  kdebug(("rcu_drv(rcu_read_irq): function done\n"));
+  return;
+}
diff -u -r -N -xCVS u2f.cern/fec/.cvsignore u2f/fec/.cvsignore
--- u2f.cern/fec/.cvsignore	1970-01-01 01:00:00.000000000 +0100
+++ u2f/fec/.cvsignore	2006-01-26 04:03:45.000000000 +0100
@@ -0,0 +1,4 @@
+Makefile.am
+fec_lib.lo
+fec_test
+semantic.cache
diff -u -r -N -xCVS u2f.cern/fec/Makefile u2f/fec/Makefile
--- u2f.cern/fec/Makefile	2005-07-12 16:08:30.000000000 +0200
+++ u2f/fec/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,39 +0,0 @@
-CFLAGS = -DALTRODEBUG -I.. -I../u2f -c -g -O3 -pedantic -funsigned-char -Wall -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align
-LFLAGS = -L. -L../u2f -L../tools -L../altro -lu2f -laltro -ltools -lfec
-
-all: libfec.so fec_test backplane_test 
-
-fec_lib.o: fec_lib.c fec.h
-	gcc $(CFLAGS) fec_lib.c -o fec_lib.o
-	
-libfec.so: fec_lib.o
-	gcc -shared -L. -o libfec.so fec_lib.o
-
-fec_test.o: fec_test.c 
-	gcc $(CFLAGS) fec_test.c -o fec_test.o
-
-fec_test: fec_test.o libfec.so
-	gcc fec_test.o $(LFLAGS) -o fec_test	
-
-backplane_test.o: backplane_test.c 
-	gcc $(CFLAGS) backplane_test.c -o backplane_test.o
-
-backplane_test: backplane_test.o libfec.so
-	gcc backplane_test.o $(LFLAGS) -o backplane_test
-
-#write_fec_fm.o: write_fec_fm.c 
-#	gcc $(CFLAGS) write_fec_fm.c -o write_fec_fm.o
-
-#write_fec_fm: write_fec_fm.o libu2f.so	
-#	gcc write_fec_fm.o $(LFLAGS) -o write_fec_fm
-	
-#read_fec_fm.o: read_fec_fm.c 
-#	gcc $(CFLAGS) read_fec_fm.c -o read_fec_fm.o
-
-#read_fec_fm: read_fec_fm.o libu2f.so	
-#	gcc read_fec_fm.o $(LFLAGS) -o read_fec_fm
-
-clean:
-	rm -f *.so *.o *~ core fec_test backplane_test 
-
-
diff -u -r -N -xCVS u2f.cern/fec/altrobus_scope.c u2f/fec/altrobus_scope.c
--- u2f.cern/fec/altrobus_scope.c	1970-01-01 01:00:00.000000000 +0100
+++ u2f/fec/altrobus_scope.c	2006-01-26 04:03:45.000000000 +0100
@@ -0,0 +1,555 @@
+/****************************************************************/
+/*                                                              */
+/*  file: altrobus_scope.c                                     */
+/*                                                              */
+/*  Author: Luciano Musa, CERN-EP                               */
+/*                                                              */
+/*  20. Jul. 05  last  update                                   */
+/*                                                              */
+/****************************************************************/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <signal.h>
+#include <tools/get_input.h>
+#include <tools/rcc_time_stamp.h>
+#include "u2f.h"
+#include "fec.h"
+
+/*************/
+/* Externals */
+/*************/
+extern u_int traceLevel;
+
+
+/*************/
+/* Prototypes*/
+/*************/
+int mainhelp(void);
+int altrobus_menu(void);
+
+
+
+/****************/
+int mainhelp(void)
+/****************/
+{
+  printf("\nCall Luciano Musa, 7676261, 163119 if you need help\n");
+  return(0);
+}
+
+/****************/
+int debug_mode(void)
+/****************/
+{
+  printf("Setting the debugLevel:\n");
+  printf("0: No debug\n");
+  printf("1: messages from altrobus_scope\n");
+  printf("2: messages altrobus_scope and fec_lib\n");
+  printf("======================================\n");
+  printf("Your choice ");
+  traceLevel = getdecd(traceLevel);
+  return(0);
+}
+
+/******************************/
+int main(int argc, char *argv[])
+/******************************/
+{  
+  static int ret, fun = 1;
+  traceLevel =0;
+  
+  ret = ts_open(1, TS_DUMMY);
+  if (ret)
+    rcc_error_print(stdout, ret);
+ 
+  printf("\n\nThis is ALTRO BUS SCOPE\n");
+  while(fun != 0)
+  {
+    printf("\n");
+    printf("Select an option:\n");
+    printf("  1 Print help\n");
+    printf("  2 ALTROBUS menu\n");
+    printf("  3 Set debugging parameters\n");
+    printf("  0 Quit\n");
+    printf("Your choice ");
+    fun = getdecd(fun);
+    if (fun == 1) mainhelp();
+    if (fun == 2) altrobus_menu();
+    if (fun == 3) debug_mode();
+    
+  }
+
+  ts_close(TS_DUMMY);
+  exit(0);
+}
+
+
+/*******************/
+int altrobus_menu(void)
+/*******************/
+{  
+  static u_int ret, fun;
+
+  static u_int number_fec = 0, act_fec =0;
+  
+  static u_int channel_address =0, fec_address =0, fec_channel_address=0;
+  static u_int reg_address = 0, reg_data =0, read_data =0, num_cycles=1, num_samples =128;
+  
+  static u_int debug =0;
+  static u_int rcode=0, rdata=0, ccode =0, cdata =0;
+
+  u_int fec_status, hadd, error =0;
+  u_int loop, tick;
+  
+  static char fname[200] = "/home/rcu/NEW_U2F/altro_usb/log_files/backplane_test.log";
+  char data_fname[200] = "/home/rcu/NEW_U2F/altro_usb/data_files/test_data";
+  char finame[200] = "/home/rcu/NEW_U2F/altro_usb/pedestal/ped_in";
+  FILE *file;
+
+
+  /* Open U2F_LIB */
+  ret = U2F_Open(HW, DEFAULT_NODE);
+  if (ret)
+    rcc_error_print(stdout, ret);
+
+  if(traceLevel > 0)
+    debug =1;
+ 
+  fun = 1; 
+  while(fun != 0)
+  {
+    printf("\n");
+    printf("Select an option:\n");
+    printf("   1 CONFIGURE THE SYSTEM   	2 RESET FECs\n");
+    printf("   3 READ_ALTRO_REG         	4 WRITE_ALTRO_REG\n");
+    printf("   5 READ_BC_REG            	6 WRITE_BC_REG\n");
+    printf("   7 READ_FEC_ADD\n");
+    printf("   8 WRITE_READ_CHECK_ALTRO_REG\n");
+    printf("   9 WRITE_READ_CHECK_BC\n");
+    printf("  10 FEC_READOUT\n");
+    printf("  =========================================================\n");
+    printf("   0 Quit\n");
+    printf("Your choice ");
+    fun = getdecd(fun);
+    
+    if((fun < 0) || (fun > 10))
+    {
+      printf ("\n ERROR: your selection is out of range\n");  
+      return(-1);
+    }
+
+    if (fun ==1)
+    {
+      printf("\nNr of FECs ON ");
+      number_fec = getdecd(number_fec);
+
+      act_fec = 0;
+      for(loop = 0; loop < number_fec; loop++)
+      {
+        printf("Enter Addres of FEC nr. %d ", loop);
+        fec_address = getdecd(fec_address); 
+	act_fec = (act_fec) | (1 << fec_address);  
+      }
+      /* Switch on FEC with Address = 0  */
+      rcode = O_ACTFEC;
+      rdata = act_fec;
+      ret = U2F_Reg_Write(rcode, rdata);
+      if (ret)
+        rcc_error_print(stdout, ret);
+
+      /* Reading back the ACTFEC Register */
+      rcode = O_ACTFEC;
+      ret = U2F_Reg_Read(rcode, &rdata);
+      if (ret)
+        rcc_error_print(stdout, ret);
+  
+      printf("\nThe FECs have the following power status:\n");
+      for(loop = 0; loop < 13; loop++)
+      {
+        fec_status = (rdata >> loop) & 0x1;
+	if(fec_status)
+	  printf("FEC(0x%x)=ON\n", loop);
+	else
+	  printf("FEC(0x%x)=OFF\n", loop);
+      }
+      	  
+      /* delay 100ms */
+      ts_delay(100000);
+
+      /* Reset FECs */
+      ccode = C_FECRST;
+      cdata = 0;
+      ret = U2F_Exec_Command(ccode, cdata);
+      if (ret)
+        rcc_error_print(stdout, ret);
+
+      /* delay 1ms */
+      ts_delay(1000);
+    }
+    
+    if (fun ==2)
+    {
+      /* delay 1s */
+      ts_delay(1000000);
+
+      /* Reset FECs twice*/
+      ccode = C_FECRST;
+      cdata = 0;
+      ret = U2F_Exec_Command(ccode, cdata);
+      if (ret)
+        rcc_error_print(stdout, ret);
+
+      ret = U2F_Exec_Command(ccode, cdata);
+      if (ret)
+        rcc_error_print(stdout, ret);
+  
+      /* delay 1ms */
+      ts_delay(1000);
+    }
+
+
+    if (fun == 3) 
+    {
+      printf("Enter the FEC Address");
+      fec_address = getdecd(fec_address);
+
+      printf("Enter the Channel Address");
+      channel_address = getdecd(channel_address);
+      
+      printf("Enter the Register Address");
+      reg_address = gethexd(reg_address);
+
+      printf("Enter the Number of Read Cycles (0 -> infinite loop) ");
+      num_cycles = getdecd(num_cycles);
+
+      channel_address = ((fec_address << 7) & 0xf80) | (fec_channel_address & 0x7f);
+      if(traceLevel == 2)
+        printf("Channel Address = %x\n", channel_address);
+
+      if(num_cycles)
+      { 
+        for(loop = 0; loop < num_cycles; loop++)
+        {      
+          ret = Read_ALTRO_Reg(debug, channel_address, reg_address, &reg_data);
+          if(ret)
+            rcc_error_print(stdout, ret);
+	  printf("\nReg %x, of FEC Channel %d, of FEC %d, has value: 0x%x\n", reg_address, fec_channel_address, fec_address, reg_data);   
+        }
+      }
+    
+      else
+      {
+        tick = 0;
+        while(!num_cycles)
+	{
+           tick++;
+           ret = Read_ALTRO_Reg(debug, channel_address, reg_address, &reg_data);
+           if(ret)
+             rcc_error_print(stdout, ret);
+	   if(tick == 10000)
+	   {
+	     printf("\nLoop of 10000 Cycles Completed");
+             printf("\nReg %x, of FEC Channel %d, of FEC %d, has value: 0x%x\n", reg_address, fec_channel_address, fec_address, reg_data);   
+	     tick =0;
+	   }
+	 }
+       }  
+    }	
+
+
+
+    if (fun == 4) 
+    {
+      printf("Enter the FEC Address");
+      fec_address = getdecd(fec_address);
+
+      printf("Enter the Channel Address");
+      channel_address = getdecd(channel_address);
+      
+      printf("Enter the Register Address");
+      reg_address = gethexd(reg_address);
+
+      printf("Enter the Register Data");
+      reg_data = gethexd(reg_data);
+       	
+      printf("Enter the Number of Write Cycles (0 -> infinite loop) ");
+      num_cycles = getdecd(num_cycles);
+
+      channel_address = ((fec_address << 7) & 0xf80) | (fec_channel_address & 0x7f);
+      if(traceLevel == 2)
+        printf("Channel Address = %x\n", channel_address);
+
+      if(num_cycles)
+      { 
+        for(loop = 0; loop < num_cycles; loop++)
+        {      
+          ret = Write_ALTRO_Reg(debug, channel_address, reg_address, reg_data);
+          if(ret)
+            rcc_error_print(stdout, ret);
+        }
+      }
+    
+      else
+      {
+        tick = 0;
+        while(!num_cycles)
+	{
+           tick++;
+           ret = Write_ALTRO_Reg(debug, channel_address, reg_address, reg_data);
+           if(ret)
+             rcc_error_print(stdout, ret);
+	   if(tick == 10000)
+	   {
+	     printf("\nLoop of 10000 Cycles Completed\n");
+	     tick =0;
+	   }
+	 }
+       }  
+    }	
+
+
+    if (fun == 5) 
+    {
+      printf("Enter the FEC Address");
+      fec_address = getdecd(fec_address);
+    
+      printf("Enter the BC Register Address");
+      reg_address = gethexd(reg_address);
+
+      printf("Enter the Number of Read Cycles (0 -> infinite loop) ");
+      num_cycles = getdecd(num_cycles);
+
+      if(num_cycles)
+      { 
+        for(loop = 0; loop < num_cycles; loop++)
+        {      
+
+          ret = FEC_BC_Reg_Read(debug, fec_address, reg_address, &reg_data);
+          if(ret)
+            rcc_error_print(stdout, ret);
+	  printf("\nBC Reg %x, of FEC %d, has value: 0x%x\n", reg_address, fec_address, reg_data);   
+        }
+      }
+    
+      else
+      {
+        tick = 0;
+        while(!num_cycles)
+	{
+           tick++;
+           ret = FEC_BC_Reg_Read(debug, fec_address, reg_address, &reg_data);
+           if(ret)
+             rcc_error_print(stdout, ret);
+	   if(tick == 10000)
+	   {
+	     printf("\nLoop of 10000 Cycles Completed");
+             printf("\nBC Reg %x, of FEC %d, has value: 0x%x\n", reg_address, fec_address, reg_data);   
+	     tick =0;
+	   }
+	 }
+       }  
+    }	
+
+
+
+    if (fun == 6) 
+    {
+      printf("Enter the FEC Address");
+      fec_address = getdecd(fec_address);
+      
+      printf("Enter the BC Register Address");
+      reg_address = gethexd(reg_address);
+
+      printf("Enter the Register Data");
+      reg_data = gethexd(reg_data);
+       	
+      printf("Enter the Number of Write Cycles (0 -> infinite loop) ");
+      num_cycles = getdecd(num_cycles);
+
+      if(num_cycles)
+      { 
+        for(loop = 0; loop < num_cycles; loop++)
+        {      
+          ret = FEC_BC_Reg_Write(debug, fec_address, reg_address, reg_data);
+          if(ret)
+            rcc_error_print(stdout, ret);
+        }
+      }
+    
+      else
+      {
+        tick = 0;
+        while(!num_cycles)
+	{
+           tick++;
+           ret = FEC_BC_Reg_Write(debug, fec_address, reg_address, reg_data);
+           if(ret)
+             rcc_error_print(stdout, ret);
+	   if(tick == 10000)
+	   {
+	     printf("\nLoop of 10000 Cycles Completed\n");
+	     tick =0;
+	   }
+	 }
+       }  
+    }	
+
+
+
+    if (fun == 7) 
+    {
+      printf("Enter the FEC Address");
+      fec_address = getdecd(fec_address);
+    
+      printf("Enter the Number of Read Cycles (0 -> infinite loop) ");
+      num_cycles = getdecd(num_cycles);
+
+      if(num_cycles)
+      { 
+        for(loop = 0; loop < num_cycles; loop++)
+        {      
+
+          ret = FEC_BC_Reg_Read(debug, fec_address, 0x13, &reg_data);
+          if(ret)
+            rcc_error_print(stdout, ret);
+	  hadd = (reg_data & 0xf800) >> 11;
+	  printf("\nAt Address 0x%x respends FEC with HADD 0x%x\n", fec_address, hadd);   
+        }
+      }
+    
+      else
+      {
+        tick = 0;
+        while(!num_cycles)
+	{
+           tick++;
+           ret = FEC_BC_Reg_Read(debug, fec_address, 0x13, &reg_data);
+           if(ret)
+             rcc_error_print(stdout, ret);
+	   if(tick == 10000)
+	   {
+	     printf("\nLoop of 10000 Cycles Completed");
+             hadd = reg_data;
+	     printf("\nAt Address 0x%x respends FEC with HADD 0x%x\n", fec_address, hadd);   
+	     tick =0;
+	   }
+	 }
+       }  
+    }	
+
+
+    if (fun == 8) 
+    {
+      printf("Enter the FEC Address");
+      fec_address = getdecd(fec_address);
+
+      printf("Enter the Channel Address");
+      channel_address = getdecd(channel_address);
+      
+      printf("Enter the Register Address");
+      reg_address = gethexd(reg_address);
+
+      printf("Enter the Register Data");
+      reg_data = gethexd(reg_data);
+       	
+      printf("Enter the Number of Write/Read Cycles (0 -> infinite loop) ");
+      num_cycles = getdecd(num_cycles);
+
+      channel_address = ((fec_address << 7) & 0xf80) | (fec_channel_address & 0x7f);
+      if(traceLevel == 2)
+        printf("Channel Address = %x\n", channel_address);
+
+      if(num_cycles)
+      { 
+        for(loop = 0; loop < num_cycles; loop++)
+        {      
+          ret = Write_ALTRO_Reg(debug, channel_address, reg_address, reg_data);
+          if(ret)
+            rcc_error_print(stdout, ret);
+	    
+          ret = Read_ALTRO_Reg(debug, channel_address, reg_address, &read_data);
+          if(ret)
+            rcc_error_print(stdout, ret);
+
+          if(read_data != reg_data)
+          {
+	    printf("Test error\n");
+            file = fopen(fname,"a");
+            fprintf(file, "Error in cycle Nr. %d\n", loop);
+            fprintf(file, "Written: 0x%x;\t\tRead: %x\n", reg_data, read_data);
+	    fclose(file);
+          }	
+        }
+      }
+    
+      else
+      {
+        tick = 0;
+        while(!num_cycles)
+	{
+           tick++;
+	   
+           ret = Write_ALTRO_Reg(debug, channel_address, reg_address, reg_data);
+           if(ret)
+             rcc_error_print(stdout, ret);
+
+           ret = Read_ALTRO_Reg(debug, channel_address, reg_address, &read_data);
+           if(ret)
+             rcc_error_print(stdout, ret);
+
+           if(read_data != reg_data)
+           {
+      	     printf("Test error\n");
+             error++;
+             file = fopen(fname,"a");
+             fprintf(file, "Error in cycle Nr. %d\n", tick++);
+             fprintf(file, "Written: 0x%x;\t\tRead: %x\n", reg_data, read_data);
+           }	
+
+	   if(tick == 10000)
+	   {
+	     printf("\nLoop of 10000 Cycles Completed\n");
+	     tick =0;
+	   }
+	   
+	   if(error == 1000)
+	   {
+	     printf("\n\n THE SYSTEM IS MALFUNCTIONING\n\n");
+	     exit(0);
+	   } 
+	 }
+       }  
+    }  /* end of function */ 	
+
+
+    if (fun == 10) 
+    {
+      printf("Enter the FEC Address");
+      fec_address = getdecd(fec_address);
+
+      printf("Enter the Number of Events");
+      num_cycles = getdecd(num_cycles);
+      
+      printf("Enter the Number of Samples");
+      num_samples = getdecd(num_samples); 
+
+      ret = Write_ALTRO_PMEM(1, 1, 0, 128, finame);
+      if(ret)
+        rcc_error_print(stdout, ret);
+
+      printf("\nCalling FEC_Event_Readout\n");
+      ret = FEC_Event_Readout_2(debug, fec_address, 1, 0, num_cycles, num_samples, data_fname); 
+
+    }  /* end of function */ 	 
+
+
+  } /* end of while */
+
+  ret = U2F_Close();
+  return(0);
+}
diff -u -r -N -xCVS u2f.cern/goofie/.cvsignore u2f/goofie/.cvsignore
--- u2f.cern/goofie/.cvsignore	1970-01-01 01:00:00.000000000 +0100
+++ u2f/goofie/.cvsignore	2006-01-26 04:03:46.000000000 +0100
@@ -0,0 +1,8 @@
+.deps
+.libs
+Makefile
+Makefile.in
+goofie_lib.lo
+goofiescope
+libgoofie.la
+semantic.cache
diff -u -r -N -xCVS u2f.cern/goofie/Makefile u2f/goofie/Makefile
--- u2f.cern/goofie/Makefile	2005-03-20 08:45:12.000000000 +0100
+++ u2f/goofie/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,21 +0,0 @@
-CFLAGS = -DALTRODEBUG -I.. -c -g -O3 -pedantic -funsigned-char -Wall -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align
-LFLAGS = -L. -L../tools -L../altro -lgoofie -laltro -ltools
-
-all: goofiescope libgoofie.so
-	
-goofie_lib.o: goofie_lib.c goofie.h 
-	gcc $(CFLAGS) goofie_lib.c -o goofie_lib.o
-	
-libgoofie.so: goofie_lib.o
-	gcc -shared -L. -o libgoofie.so goofie_lib.o
-		
-goofiescope.o: goofiescope.c
-	gcc $(CFLAGS) goofiescope.c -o goofiescope.o
-
-goofiescope: goofiescope.o libgoofie.so
-	gcc goofiescope.o $(LFLAGS) -o goofiescope 
-
-clean:
-	rm -f *.so *.o *~ core goofiescope
-
-
diff -u -r -N -xCVS u2f.cern/goofie/Makefile.am u2f/goofie/Makefile.am
--- u2f.cern/goofie/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ u2f/goofie/Makefile.am	2006-01-27 09:47:16.000000000 +0100
@@ -0,0 +1,20 @@
+#
+#
+#
+AM_CPPFLAGS		= -DALTRODEBUG -I$(top_srcdir) -DALTRO_BUILD
+AM_CFLAGS 		= -pedantic -funsigned-char -Wall 	\
+			  -Wstrict-prototypes -Wpointer-arith 	\
+			  -Wcast-qual -Wcast-align
+
+pkglib_LTLIBRARIES	= libgoofie.la
+libgoofie_la_SOURCES	= goofie_lib.c
+libgoofie_la_LIBADD	= $(top_builddir)/altro/libaltro.la
+pkginclude_HEADERS	= goofie.h
+
+bin_PROGRAMS		= goofiescope
+goofiescope_SOURCES	= goofiescope.c
+goofiescope_LDADD	= libgoofie.la
+
+#
+# EOF
+#
diff -u -r -N -xCVS u2f.cern/goofie/goofiescope.c u2f/goofie/goofiescope.c
--- u2f.cern/goofie/goofiescope.c	2005-03-20 08:45:12.000000000 +0100
+++ u2f/goofie/goofiescope.c	2006-01-26 04:03:46.000000000 +0100
@@ -178,7 +178,8 @@
       dcount = 0;
       for (loop = 0; loop < osize; loop++) 
       {
-        printf("Word %d = 0x%02x %08x\n", loop, dmemdata[dcount++], dmemdata[dcount++]);
+        printf("Word %d = 0x%02x %08x\n", loop, dmemdata[dcount], dmemdata[dcount+1]);
+	dcount += 2;
       }
       
       /* write data to file */
diff -u -r -N -xCVS u2f.cern/scripts/.cvsignore u2f/scripts/.cvsignore
--- u2f.cern/scripts/.cvsignore	1970-01-01 01:00:00.000000000 +0100
+++ u2f/scripts/.cvsignore	2006-01-26 04:03:46.000000000 +0100
@@ -0,0 +1,19 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.la
+*.lo
+*.o
+RCUGUIDict.*
+nbi_acq
+u2f_acq
+u2f_acq_2
+u2f_acq_back
+read_altro
+rcuscope
+rcu
+
+
+altro
+semantic.cache
diff -u -r -N -xCVS u2f.cern/scripts/Makefile.am u2f/scripts/Makefile.am
--- u2f.cern/scripts/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ u2f/scripts/Makefile.am	2006-01-26 04:03:46.000000000 +0100
@@ -0,0 +1,10 @@
+#
+#
+#
+bin_SCRIPTS	= altro-config
+sbin_SCRIPTS	= altro
+EXTRA_DIST	= import_sources make_diff
+
+#
+# EOF
+#
\ No newline at end of file
diff -u -r -N -xCVS u2f.cern/scripts/altro-config.in u2f/scripts/altro-config.in
--- u2f.cern/scripts/altro-config.in	1970-01-01 01:00:00.000000000 +0100
+++ u2f/scripts/altro-config.in	2006-01-26 04:03:46.000000000 +0100
@@ -0,0 +1,150 @@
+#!/bin/sh
+#
+#  Copyright (c) 2005 Christian Holm <cholm@nbi.dk>
+#
+#  This library is free software; you can redistribute it and/or 
+#  modify it under the terms of the GNU Lesser General Public License 
+#  as published by the Free Software Foundation; either version 2.1 
+#  of the License, or (at your option) any later version. 
+#
+#  This library 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 
+#  Lesser General Public License for more details. 
+# 
+#  You should have received a copy of the GNU Lesser General Public 
+#  License along with this library; if not, write to the Free 
+#  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
+#  02111-1307 USA 
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+includedir=@includedir@ 
+pkgincludedir=@includedir@
+libdir=@libdir@
+pkglibdir=@libdir@/@PACKAGE@
+package="@PACKAGE_TARNAME@"
+string="@PACKAGE_STRING@"
+email="@PACKAGE_BUGREPORT@"
+version="@VERSION@"
+
+prog=`basename $0`
+lib=0
+needaltro=0
+needfec=0  
+needgoofie=0 
+needu2f=0    
+
+if test $# -eq 0 ; then 
+    $0 --help
+    exit 0
+fi
+
+while test $# -gt 0 ; do 
+    case $1 in 
+	--*=*)    
+	    opt=`echo $1 | sed 's/=.*//'`
+	    arg=`echo $1 | sed 's/[^=]*=//'` 
+	    ;;
+	--*)
+	    opt=$1
+	    arg=
+	    ;;
+	-*)
+	    opt=$1
+	    arg=$2
+	    ;;
+	*)
+	    opt=$1
+	    ;;
+    esac
+
+    case $opt in
+	--help|-h) 
+	    cat <<EOF
+Usage: $prog [OPTIONS] INTERFACE
+
+  --prefix          Gives the installation prefix
+  --libdir          Gives path to libraries
+  --includedir      Gives path to headers 
+  --libs            Gives libraries information 
+  --ldflags         Gives linkage information 
+  --cppflags        Gives preprocessor information
+  --version         Gives version information
+  --help            Gives this help
+
+INTERFACE is one of 
+
+  altro             USB low-level interface 
+  u2f		    USB 2 FEC card (RCU test board)
+  goofie            Goofie card 
+  fec               Front end card abstraction layer
+
+EOF
+	    ;;
+	--version|-v)
+	    cat <<EOF
+$string 
+
+Copyright 2002 Christian Holm Christensen <$email>
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+EOF
+	    exit 0
+	    ;;
+	-V)
+	    echo $version 
+	    exit 0
+	    ;;
+	--prefix|-p)
+	    out="$out $prefix" 
+	    ;;
+	--libdir|-L)
+	    out="$out $pkglibdir"
+	    ;;
+	--includedir|-I)
+	    out="$out $includedir" 
+	    ;;
+	--cppflags|-D)
+	    if test ! "x$pkgincludedir" = "x/usr/include" ; then 
+		out="$out -I$pkgincludedir" 
+	    fi
+	    ;;
+	--ldflags) 
+	    if test ! "x$pkglibdir" = "x/usr/lib" ; then 
+		out="$out -L$pkglibdir" 
+	    fi
+	    lib=1
+	    ;;
+	--libs|-l)
+	    lib=1
+	    ;;
+	*)
+	    opt=`echo $opt | tr '[A-Z]' '[a-z]'`
+	    case $opt in 
+		altro)  needaltro=1  ;; 
+		fec)    needfec=1    ; needaltro=1 ; needu2f=1 ;;
+		goofie) needgoofie=1 ; needaltro=1 ;;
+		u2f)    needu2f=1    ; needaltro=1 ;;
+		*)
+		    echo "$prog: unknown option '$opt' - try '$prog --help'"
+		    exit 1
+		    ;;
+	    esac
+	    ;;
+    esac
+    shift
+done
+
+if test $lib -gt 0 ; then 
+    out="$out -ltools" 
+    if test $needaltro  -gt 0 ; then out="$out -laltro"  ; fi
+    if test $needgoofie -gt 0 ; then out="$out -lgoofie" ; fi
+    if test $needu2f    -gt 0 ; then out="$out -lu2f"    ; fi
+    if test $needfec    -gt 0 ; then out="$out -lfec"    ; fi
+fi
+echo $out
+
+		
+	
diff -u -r -N -xCVS u2f.cern/scripts/altro.in u2f/scripts/altro.in
--- u2f.cern/scripts/altro.in	1970-01-01 01:00:00.000000000 +0100
+++ u2f/scripts/altro.in	2006-01-26 04:03:46.000000000 +0100
@@ -0,0 +1,117 @@
+#!/bin/sh
+#
+# rcu:       Starts the RCU driver
+#
+# Version:      @(#) /etc/rc.d/init.d/rcu 1.0
+#
+# chkconfig: 5 80 20
+# description: Starts and stops the RCU driver at boot time and shutdown.
+#
+# processname: rcu
+# hide: true
+PATH=$PATH:/sbin:/usr/sbin
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+pkglibdir=@libdir@/@PACKAGE@
+kvers=`uname -r` 
+case $kvers in
+    2.4*|2.2*) kmodext=o ;;
+    *)         kmodext=ko ;;
+esac
+moduledir=${pkglibdir}/modules/${kvers}
+name=altro
+driver_name=${name}_driver
+driver=${driver_name}.$kmodext
+minor=@MINOR@
+
+
+load_driver() 
+{
+    driver_opt=$1
+    echo -n "Starting ALTRO driver "
+    if test "x$driver_opt" = "x" ; then 
+	echo -n "with no options ... " 
+    else
+	echo -n "with options $opt ... "
+    fi
+    # load the module
+    if test ! -f $moduledir/$driver ; then 
+	echo "Failed" 
+	echo " Kernel module $moduledir/$driver not found" 
+	exit 1
+    fi
+    insmod $moduledir/$driver $driver_opt
+    if test $? -ne 0 ; then 
+	echo "Failed" 
+	exit 1
+    fi
+    sleep 1
+    echo "done"
+}
+
+remove_driver() 
+{
+    echo  -n "Shutting down ALTRO driver ... "
+    if `grep -q ${driver_name} /proc/modules > /dev/null 2>&1` ; then
+	rmmod -f ${driver_name}
+	if test $? -ne 0 ; then 
+	    echo "Failed" 
+	    exit 1
+	fi
+	sleep 1
+    fi
+    echo "done"
+    return 0
+}
+
+make_devices() 
+{
+    major=`grep usb /proc/devices | awk '{print $1}'`
+    minors=`grep Device: /proc/${name} | awk '{print $3}' | tr -d '()'`
+    i=0
+    for minor in $minors ; do
+	if test ! -c /dev/${name}$i ; then
+	    mknod /dev/${name}$i c $major $minor
+	fi
+	let i=$i+1
+    done
+    #give permissions
+    for dev in /dev/${name}? ; do
+	if test -c $dev ; then
+	    chmod 666 $dev
+	fi
+    done
+    return 0;
+}
+
+
+# See how we were called.
+case "$1" in
+    start)
+	load_driver 
+	make_devices 
+        ;;
+    stop)
+	remove_driver
+        ;;
+    status)
+        cat /proc/${name}
+        ;;
+    restart)
+	remove_driver
+	load_driver 
+	make_devices 
+        ;;
+    restart_debug)
+	remove_driver
+	load_driver debug=1
+	make_devices 
+        ;;
+  *)
+        echo "*** Usage: rcu {start|stop|status|restart|restart_debug}"
+        exit 1
+esac
+
+exit 0
+
diff -u -r -N -xCVS u2f.cern/scripts/import_sources u2f/scripts/import_sources
--- u2f.cern/scripts/import_sources	1970-01-01 01:00:00.000000000 +0100
+++ u2f/scripts/import_sources	2006-01-26 04:03:46.000000000 +0100
@@ -0,0 +1,84 @@
+#!/bin/bash
+
+indir="../rcu/altro_usb" 
+verbose=0
+# ____________________________________________________________________
+usage ()
+{
+    cat <<EOF
+Usage: $0 [OPTIONS]
+
+Options:
+
+	-h,--help		Show this help 
+	-i,--input=DIR		Set input directory to DIR
+	-v,--verbose		Be verbose 
+EOF
+    exit 0
+}
+
+# ____________________________________________________________________
+while test $# -gt 0 ; do 
+    case $1 in 
+	--*=*) 
+	    opt=`echo $1 | sed 's/=.*//'` 
+	    arg=`echo $1 | sed 's/.*=//'`
+	    ;;
+	--*)
+	    opt=$1 
+	    arg=
+	    ;;
+	-*)
+	    opt=$1 
+	    arg=$2
+	    ;; 
+    esac
+    
+    need_arg=0
+    case $opt in 
+	-h|--help) usage ;;
+	-i|--input) indir=$arg ; need_arg=1 ;; 
+	-v|--verbose) verbose=1 ;; 
+	*)
+	    echo "Unknown option '$1', try '$0 --help'" > /dev/stderr 
+	    exit 1
+	    ;;
+    esac
+    
+    case $opt:$need_arg in 
+	--*=*:*) ;;
+	--*:*)   ;;
+	-*:1) 
+	    if test "x$arg" = "x" ; then 
+		echo "Option '$opt' need an argument" > /dev/stderr 
+		exit 1
+	    fi
+	    shift ;;
+    esac
+    shift
+done 
+
+# ____________________________________________________________________
+if test "x$indir" = "x" || test ! -d $indir ; then 
+    echo "No such directory '$indir'" > /dev/stderr 
+    exit 1
+fi
+
+# ____________________________________________________________________
+files=`find . -name "*.h" -or -name "*.c"` 
+
+for f in $files ; do 
+    b=`basename $f`
+    n=`find $indir -name "$b"` 
+    if test $? -ne 0 || test "x$n" = "x"; then 
+	# echo "$b not found in $indir" 
+	continue 
+    fi
+    # test $verbose -gt 0 && echo "Will copy $n to $f" 
+    cpopt=
+    test $verbose -gt 0 && cpopt="-v" 
+    cp $cpopt $n $f 
+done
+
+
+
diff -u -r -N -xCVS u2f.cern/scripts/make_diff u2f/scripts/make_diff
--- u2f.cern/scripts/make_diff	1970-01-01 01:00:00.000000000 +0100
+++ u2f/scripts/make_diff	2006-01-26 04:03:46.000000000 +0100
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+indir="../rcu/altro_usb" 
+verbose=0
+# ____________________________________________________________________
+usage ()
+{
+    cat <<EOF
+Usage: $0 [OPTIONS]
+
+Options:
+
+	-h,--help		Show this help 
+	-i,--input=DIR		Set input directory to DIR
+	-v,--verbose		Be verbose 
+EOF
+    exit 0
+}
+
+# ____________________________________________________________________
+while test $# -gt 0 ; do 
+    case $1 in 
+	--*=*) 
+	    opt=`echo $1 | sed 's/=.*//'` 
+	    arg=`echo $1 | sed 's/.*=//'`
+	    ;;
+	--*)
+	    opt=$1 
+	    arg=
+	    ;;
+	-*)
+	    opt=$1 
+	    arg=$2
+	    ;; 
+    esac
+    
+    need_arg=0
+    case $opt in 
+	-h|--help) usage ;;
+	-i|--input) indir=$arg ; need_arg=1 ;; 
+	-v|--verbose) verbose=1 ;; 
+	*)
+	    echo "Unknown option '$1', try '$0 --help'" > /dev/stderr 
+	    exit 1
+	    ;;
+    esac
+    
+    case $opt:$need_arg in 
+	--*=*:*) ;;
+	--*:*)   ;;
+	-*:1) 
+	    if test "x$arg" = "x" ; then 
+		echo "Option '$opt' need an argument" > /dev/stderr 
+		exit 1
+	    fi
+	    shift ;;
+    esac
+    shift
+done 
+
+# ____________________________________________________________________
+if test "x$indir" = "x" || test ! -d $indir ; then 
+    echo "No such directory '$indir'" > /dev/stderr 
+    exit 1
+fi
+
+# ____________________________________________________________________
+files=`find . -name "*.h" -or -name "*.c"` 
+
+for f in $files ; do 
+    b=`basename $f`
+    n=`find $indir -name "$b"` 
+    if test $? -ne 0 || test "x$n" = "x"; then 
+	# echo "$b not found in $indir" 
+	continue 
+    fi
+    # test $verbose -gt 0 && echo "Will copy $n to $f" 
+    cpopt=
+    diff -u $n $f 
+done
+
+
+
diff -u -r -N -xCVS u2f.cern/tools/.cvsignore u2f/tools/.cvsignore
--- u2f.cern/tools/.cvsignore	1970-01-01 01:00:00.000000000 +0100
+++ u2f/tools/.cvsignore	2006-01-26 04:03:47.000000000 +0100
@@ -0,0 +1,9 @@
+.deps
+.libs
+Makefile
+Makefile.in
+get_input.lo
+libtools.la
+rcc_error.lo
+rcc_time_stamp.lo
+semantic.cache
diff -u -r -N -xCVS u2f.cern/tools/Makefile u2f/tools/Makefile
--- u2f.cern/tools/Makefile	2005-05-13 16:49:52.000000000 +0200
+++ u2f/tools/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,19 +0,0 @@
-CFLAGS = -c -g -O3 -pedantic -funsigned-char -Wall -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align
-
-all: libtools.so
-	
-libtools.so: rcc_error.o rcc_time_stamp.o get_input.o
-	gcc -shared -L. -o libtools.so rcc_error.o rcc_time_stamp.o get_input.o
-
-rcc_error.o: rcc_error.h rcc_error.c
-	gcc $(CFLAGS) rcc_error.c -o rcc_error.o
-
-rcc_time_stamp.o: rcc_time_stamp.h rcc_time_stamp.c
-	gcc $(CFLAGS) -DTSTAMP rcc_time_stamp.c -o rcc_time_stamp.o
-	
-get_input.o: get_input.c
-	gcc $(CFLAGS) get_input.c -o get_input.o
-
-clean:
-	rm -f *.so *.o 
-
diff -u -r -N -xCVS u2f.cern/tools/Makefile.am u2f/tools/Makefile.am
--- u2f.cern/tools/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ u2f/tools/Makefile.am	2006-01-26 04:03:47.000000000 +0100
@@ -0,0 +1,14 @@
+#
+#
+#
+AM_CPPFLAGS		= -DTSTAMP -DALTRO_BUILD
+AM_CFLAGS		= -funsigned-char -Wall \
+			  -Wpointer-arith -Wcast-qual -Wcast-align
+pkglib_LTLIBRARIES	= libtools.la
+libtools_la_SOURCES	= rcc_error.c rcc_time_stamp.c get_input.c
+pkginclude_HEADERS	= get_input.h rcc_error.h rcc_time_stamp.h
+
+#
+# EOF
+#
+
diff -u -r -N -xCVS u2f.cern/tools/rcc_error.h u2f/tools/rcc_error.h
--- u2f.cern/tools/rcc_error.h	2005-03-20 08:45:12.000000000 +0100
+++ u2f/tools/rcc_error.h	2006-01-26 04:03:46.000000000 +0100
@@ -12,7 +12,9 @@
  ********************************************************************/
 #ifndef _RCC_ERROR_H_
 #define _RCC_ERROR_H_
-#include <stdio.h>
+#ifndef __KERNEL__
+# include <stdio.h>
+#endif
 
 typedef enum 
 {
@@ -76,6 +78,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+#ifndef  __KERNEL__
 err_type rcc_error_open( void ) ;
 err_type rcc_error_close( void ) ;
 err_type rcc_error_init(err_pid p, err_type (*f)(err_pack, err_str, err_str) );
@@ -83,7 +86,7 @@
 err_type rcc_error_print(FILE* stream, err_type e);
 err_type rcc_error_get(err_type t, err_str ap, err_str as, err_str ip, err_str is);
 err_type rcc_error_string(char *text, err_type err);
-
+#endif
 #ifdef __cplusplus
 }
 #endif
diff -u -r -N -xCVS u2f.cern/tools/rcc_time_stamp.h u2f/tools/rcc_time_stamp.h
--- u2f.cern/tools/rcc_time_stamp.h	2005-03-20 08:45:12.000000000 +0100
+++ u2f/tools/rcc_time_stamp.h	2006-01-26 04:03:47.000000000 +0100
@@ -15,10 +15,14 @@
 /*                                                                      */
 /*******Copyright Ecosoft 2004 - Made from 80% recycled bytes************/
  
+#ifdef ALTRO_BUILD
 #include "rcc_error.h"
+#else 
+#include <altro/rcc_error.h>
+#endif
 
 #ifndef _TSTAMPLIB_H
-  #define _TSTAMPLIB_H
+# define _TSTAMPLIB_H
 
   typedef struct tstamp
   { 
@@ -30,19 +34,19 @@
   typedef unsigned int TS_ErrorCode_t;
   
   
-  #define TS_DUMMY       0
-  #define TS_MODE_NORING 0
-  #define TS_MODE_RING   1
+# define TS_DUMMY       0
+# define TS_MODE_NORING 0
+# define TS_MODE_RING   1
  
-  #ifdef TSTAMP
-    /* Constants */
-    #define FREQUENCY_LOW     16500000.0
-    #define FREQUENCY_HIGH    (1.0/256.0)
-    #define TS_FULL           1
-    #define TS_STOP_TS        2
-    #define TS_START_TS       ~TS_STOP_TS
-    #define MAX_OPENS         10
-  
+# ifdef TSTAMP
+/* Constants */
+#  define FREQUENCY_LOW     16500000.0
+#  define FREQUENCY_HIGH    (1.0/256.0)
+#  define TS_FULL           1
+#  define TS_STOP_TS        2
+#  define TS_START_TS       ~TS_STOP_TS
+#  define MAX_OPENS         10
+
     enum
       {
       TS_H1 = 1,
@@ -58,58 +62,58 @@
       };
 
     /* Macros */
-    static int tstamp_ret;
+    // static int tstamp_ret;
 
-    #define TS_OPEN(size, ts_handle)\
-    {\
-    tstamp_ret = ts_open(size, ts_handle);\
+#  define TS_OPEN(size, ts_handle)\
+    do {\
+    int tstamp_ret = ts_open(size, ts_handle);\
     if (tstamp_ret)\
       rcc_error_print(stdout, tstamp_ret);\
-    }
+    } while(0)
 
-    #define TS_SAVE(handle, name)\
-    {\
-    tstamp_ret=ts_save(handle, name);\
+#  define TS_SAVE(handle, name)\
+    do {\
+    int tstamp_ret=ts_save(handle, name);\
     if (tstamp_ret)\
       rcc_error_print(stdout, tstamp_ret);\
-    }
+    } while(0)
 
-    #define TS_CLOSE(handle)\
-    {\
-    tstamp_ret = ts_close(handle);\
+#  define TS_CLOSE(handle)\
+    do {\
+    int tstamp_ret = ts_close(handle);\
     if (tstamp_ret)\
       rcc_error_print(stdout, tstamp_ret);\
-    }
+    } while(0)
 
-    #define TS_RECORD(handle, udata)      ts_record(handle, udata)
-    #define TS_START(handle)              ts_start(handle)
-    #define TS_SETT0                      ts_sett0()
-    #define TS_PAUSE(handle)              ts_pause(handle) 
-    #define TS_RESUME(handle)             ts_resume(handle)
-    #define TS_DURATION( t1, t2)          ts_duration(t1, t2)
-    #define TS_CLOCK(time)                ts_clock(time)
-    #define TS_DELAY(time)                ts_delay(time)
-    #define TS_MODE(handle, mode)         ts_mode(handle, mode)
-    #define TS_COMPARE(t1, t2)            ts_compare(t1, t2)
-    #define TS_OFFSET(ts, usecs)          ts_offset(ts, usecs)
-    #define TS_WAIT_UNTIL(target, nyield) ts_wait_until(target, nyield)
-  #else
-    #define TS_OPEN(size, ts_handle)
-    #define TS_SAVE(handle, name)
-    #define TS_CLOSE(handle)
-    #define TS_RECORD(handle,udata)
-    #define TS_START(handle)
-    #define TS_PAUSE(handle)
-    #define TS_RESUME(handle)
-    #define TS_DURATION(t1, t2)
-    #define TS_CLOCK(time) 
-    #define TS_DELAY(time) 
-    #define TS_MODE(handle, mode)
-    #define TS_COMPARE(t1, t2)
-    #define TS_OFFSET(ts, usecs)
-    #define TS_WAIT_UNTIL(target, nyield)
-    #define TS_SETT0
-  #endif
+#  define TS_RECORD(handle, udata)      ts_record(handle, udata)
+#  define TS_START(handle)              ts_start(handle)
+#  define TS_SETT0                      ts_sett0()
+#  define TS_PAUSE(handle)              ts_pause(handle) 
+#  define TS_RESUME(handle)             ts_resume(handle)
+#  define TS_DURATION( t1, t2)          ts_duration(t1, t2)
+#  define TS_CLOCK(time)                ts_clock(time)
+#  define TS_DELAY(time)                ts_delay(time)
+#  define TS_MODE(handle, mode)         ts_mode(handle, mode)
+#  define TS_COMPARE(t1, t2)            ts_compare(t1, t2)
+#  define TS_OFFSET(ts, usecs)          ts_offset(ts, usecs)
+#  define TS_WAIT_UNTIL(target, nyield) ts_wait_until(target, nyield)
+# else
+#  define TS_OPEN(size, ts_handle)
+#  define TS_SAVE(handle, name)
+#  define TS_CLOSE(handle)
+#  define TS_RECORD(handle,udata)
+#  define TS_START(handle)
+#  define TS_PAUSE(handle)
+#  define TS_RESUME(handle)
+#  define TS_DURATION(t1, t2)
+#  define TS_CLOCK(time) 
+#  define TS_DELAY(time) 
+#  define TS_MODE(handle, mode)
+#  define TS_COMPARE(t1, t2)
+#  define TS_OFFSET(ts, usecs)
+#  define TS_WAIT_UNTIL(target, nyield)
+#  define TS_SETT0
+# endif
 
   /* Error codes */
   enum
@@ -129,21 +133,21 @@
   TSE_NOCODE
   };
   
-  #define TSE_OK_STR           "No error"  
-  #define TSE_NO_FREQ_STR      "Failed to set frequency"
-  #define TSE_FILE_STR         "Failed to open /proc/cpuinfo"
-  #define TSE_ILL_HANDLE_STR   "Parameter >handle< is out of range"
-  #define TSE_IS_CLOSED_STR    "The library has not been opened"
-  #define TSE_ILL_SIZE_STR     "Parameter >size< is out of range"
-  #define TSE_PFILE_STR        "Failed to open/close data file"
-  #define TSE_NO_REF_STR       "Reference time missing (ts_sett0)"
-  #define TSE_ERROR_FAIL_STR   "Failed to initialise the error system"
-  #define TSE_ILL_MODE_STR     "Parameter >mode< is out of range"
-  #define TSE_NOCODE_STR       "Unknown error code"
-   
-  #ifdef __cplusplus
+# define TSE_OK_STR           "No error"  
+# define TSE_NO_FREQ_STR      "Failed to set frequency"
+# define TSE_FILE_STR         "Failed to open /proc/cpuinfo"
+# define TSE_ILL_HANDLE_STR   "Parameter >handle< is out of range"
+# define TSE_IS_CLOSED_STR    "The library has not been opened"
+# define TSE_ILL_SIZE_STR     "Parameter >size< is out of range"
+# define TSE_PFILE_STR        "Failed to open/close data file"
+# define TSE_NO_REF_STR       "Reference time missing (ts_sett0)"
+# define TSE_ERROR_FAIL_STR   "Failed to initialise the error system"
+# define TSE_ILL_MODE_STR     "Parameter >mode< is out of range"
+# define TSE_NOCODE_STR       "Unknown error code"
+
+# ifdef __cplusplus
     extern "C" {
-  #endif
+# endif
 
   /*prototypes*/
   float ts_duration(tstamp t1, tstamp t2); 
@@ -166,9 +170,9 @@
   TS_ErrorCode_t ts_wait_until(tstamp target, unsigned int *nyield);
   TS_ErrorCode_t packTS_err_get (err_pack err, err_str pid_str, err_str en_str);
 
-  #ifdef __cplusplus
+# ifdef __cplusplus
     }
-  #endif
+# endif
 #endif
 
 
diff -u -r -N -xCVS u2f.cern/u2f/.cvsignore u2f/u2f/.cvsignore
--- u2f.cern/u2f/.cvsignore	2005-11-21 10:06:22.000000000 +0100
+++ u2f/u2f/.cvsignore	2006-01-26 04:03:47.000000000 +0100
@@ -1,16 +1,12 @@
-all
-altrobus_scope
-altrobus_scope.c
-backplane_test.c
-fec.h
-fec_lib
-fec_lib.c
-fec_test.c
-pic
-pulse1
-pulse3
+.deps
+.libs
+Makefile
+Makefile.in
+libu2f.la
 read_fec_fm
-test2
+semantic.cache
 u2f_acq
+u2f_lib.lo
 u2fscope
 write_fec_fm
+data
diff -u -r -N -xCVS u2f.cern/u2f/Makefile u2f/u2f/Makefile
--- u2f.cern/u2f/Makefile	2005-11-21 10:03:32.000000000 +0100
+++ u2f/u2f/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,40 +0,0 @@
-CFLAGS = -DALTRODEBUG -I.. -c -g -O3 -pedantic -funsigned-char -Wall -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align
-LFLAGS = -L. -L../tools -L../altro -lu2f -laltro -ltools
-
-all: libu2f.so u2f_acq write_fec_fm read_fec_fm u2fscope
-
-u2f_lib.o: u2f_lib.c u2f.h 
-	gcc $(CFLAGS) u2f_lib.c -o u2f_lib.o
-	
-libu2f.so: u2f_lib.o
-	gcc -shared -L. -o libu2f.so u2f_lib.o
-
-u2f_acq.o: u2f_acq.c 
-	gcc $(CFLAGS) u2f_acq.c -o u2f_acq.o
-
-u2f_acq: u2f_acq.o libu2f.so	
-	gcc u2f_acq.o $(LFLAGS) -o u2f_acq
-
-write_fec_fm.o: write_fec_fm.c 
-	gcc $(CFLAGS) write_fec_fm.c -o write_fec_fm.o
-
-write_fec_fm: write_fec_fm.o libu2f.so	
-	gcc write_fec_fm.o $(LFLAGS) -o write_fec_fm
-	
-read_fec_fm.o: read_fec_fm.c 
-	gcc $(CFLAGS) read_fec_fm.c -o read_fec_fm.o
-
-read_fec_fm: read_fec_fm.o libu2f.so	
-	gcc read_fec_fm.o $(LFLAGS) -o read_fec_fm
-
-u2fscope.o: u2fscope.c
-	gcc $(CFLAGS) u2fscope.c -o u2fscope.o
-
-u2fscope: u2fscope.o libu2f.so
-	gcc u2fscope.o $(LFLAGS) -o u2fscope 
-
-
-clean:
-	rm -f *.so *.o *~ core u2fscope u2f_acq write_fec_fm read_fec_fm
-
-
diff -u -r -N -xCVS u2f.cern/u2f/Makefile.am u2f/u2f/Makefile.am
--- u2f.cern/u2f/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ u2f/u2f/Makefile.am	2006-01-26 04:03:47.000000000 +0100
@@ -0,0 +1,26 @@
+#
+#
+#
+AM_CPPFLAGS		= -I$(top_srcdir) -DALTRODEBUG  -DALTRO_BUILD
+AM_CFLAGS		= -funsigned-char -Wall \
+			  -Wpointer-arith -Wcast-qual -Wcast-align
+pkglib_LTLIBRARIES	= libu2f.la
+pkginclude_HEADERS	= u2f.h 
+bin_PROGRAMS		= u2f_acq u2fscope
+noinst_PROGRAMS		= write_fec_fm read_fec_fm 
+
+libu2f_la_SOURCES	= u2f_lib.c
+libu2f_la_LIBADD	= $(top_builddir)/altro/libaltro.la
+
+u2f_acq_SOURCES		= u2f_acq.c
+u2f_acq_LDADD		= libu2f.la
+u2fscope_SOURCES	= u2fscope.c
+u2fscope_LDADD		= libu2f.la
+write_fec_fm_SOURCES	= write_fec_fm.c
+write_fec_fm_LDADD	= libu2f.la
+read_fec_fm_SOURCES	= read_fec_fm.c
+read_fec_fm_LDADD	= libu2f.la
+
+#
+# EOF
+# 
\ No newline at end of file
diff -u -r -N -xCVS u2f.cern/u2f/u2f.h u2f/u2f/u2f.h
--- u2f.cern/u2f/u2f.h	2005-11-21 10:06:19.000000000 +0100
+++ u2f/u2f/u2f.h	2006-01-26 04:03:48.000000000 +0100
@@ -227,10 +227,11 @@
 u_int U2F_err_get(err_pack err, err_str pid, err_str code);
 u_int U2F_banks_alloc(int mode, u2f_bank_t* bank); 
 u_int U2F_banks_init(int mode);
-u_int make_dummy_data(void); 
+u_int make_dummy_data(u_int); 
 void U2F_banks_destroy(int mode);
 void write_dummy_data(u_int which, u_int chip, u_int chan, u_int len); 
-
+void write_next_data(u_int which, u_int *chip, u_int *chan, u_int len);
+  
 
 #ifdef __cplusplus
 }
diff -u -r -N -xCVS u2f.cern/u2f/u2f_lib.c u2f/u2f/u2f_lib.c
--- u2f.cern/u2f/u2f_lib.c	2005-11-21 10:36:46.000000000 +0100
+++ u2f/u2f/u2f_lib.c	2006-01-26 04:03:47.000000000 +0100
@@ -37,7 +37,7 @@
     if (!bank) 
       return(RCC_ERROR_RETURN(0, U2F_SUCCESS));
 
-    bank->data = (u_int*)malloc(sizeof(u_int)*bank->size);
+    // bank->data = (u_int*)malloc(sizeof(u_int)*bank->size);
     if (!bank->data) 
     {
       DEBUG_TEXT(P_ID_U2F, 5 ,("U2F_banks_alloc: Failed to allocate memory for data bank\n"));
@@ -47,6 +47,15 @@
   return(0);
 }
 
+static u_int imem_data[S_IMEM];
+static u_int rmem_data[S_RMEM];
+static u_int pmem_data[S_PMEM];
+static u_int acl_data[S_ACL];
+static u_int dml1_data[S_DM];
+static u_int dmh1_data[S_DM];
+static u_int dml2_data[S_DM];
+static u_int dmh2_data[S_DM];
+static u_int reg_data[O_TRCFG2 + 1];
 
 /****************************/
 u_int U2F_banks_init(int mode)
@@ -60,38 +69,47 @@
     return(RCC_ERROR_RETURN(0, U2F_SUCCESS));
   }
   
+  u2f_imem.data = imem_data;
   ret = U2F_banks_alloc(mode, &u2f_imem);
   if (ret)
     return(RCC_ERROR_RETURN(0, U2F_MALLOC));
 
+  u2f_pmem.data = pmem_data;
   ret = U2F_banks_alloc(mode, &u2f_pmem);
   if (ret)
     return(RCC_ERROR_RETURN(0, U2F_MALLOC));
 
+  u2f_rmem.data = rmem_data;
   ret = U2F_banks_alloc(mode, &u2f_rmem);
   if (ret)
     return(RCC_ERROR_RETURN(0, U2F_MALLOC));
 
+  u2f_acl.data = acl_data;
   ret = U2F_banks_alloc(mode, &u2f_acl);
   if (ret)
     return(RCC_ERROR_RETURN(0, U2F_MALLOC));
 
+  u2f_dmh1.data = dmh1_data;
   ret = U2F_banks_alloc(mode, &u2f_dmh1);
   if (ret)
     return(RCC_ERROR_RETURN(0, U2F_MALLOC));
 
+  u2f_dml1.data = dml1_data;
   ret = U2F_banks_alloc(mode, &u2f_dml1);
   if (ret)
     return(RCC_ERROR_RETURN(0, U2F_MALLOC));
 
+  u2f_dmh2.data = dmh2_data;
   ret = U2F_banks_alloc(mode, &u2f_dmh2);
   if (ret)
     return(RCC_ERROR_RETURN(0, U2F_MALLOC));
 
+  u2f_dml2.data = dml2_data;
   ret = U2F_banks_alloc(mode, &u2f_dml2);
   if (ret)
     return(RCC_ERROR_RETURN(0, U2F_MALLOC));
 
+  u2f_registers.data = reg_data;
   ret = U2F_banks_alloc(mode, &u2f_registers);
   if (ret)
     return(RCC_ERROR_RETURN(0, U2F_MALLOC));
@@ -112,6 +130,7 @@
     return;
   else
   {
+#if 0
     free(u2f_imem.data);
     free(u2f_pmem.data);
     free(u2f_rmem.data);
@@ -121,6 +140,7 @@
     free(u2f_dmh2.data);
     free(u2f_dml2.data);
     free(u2f_registers.data);
+#endif
   }
 }
 
@@ -187,7 +207,7 @@
   u2f_dml2.data  = 0;
 
   u2f_registers.id    = A_REGISTERS;
-  u2f_registers.size  = O_RDOMOD + 1;
+  u2f_registers.size  = O_TRCFG2 + 1;
   u2f_registers.mask1 = 0xffff;
   u2f_registers.mask2 = 0xffff;
   u2f_registers.data  = 0;
@@ -280,7 +300,7 @@
     DEBUG_TEXT(P_ID_U2F, 20 , ("U2F_Memory_Read: Emulation: bank->id   = %d\n", bank->id));
     DEBUG_TEXT(P_ID_U2F, 20 , ("U2F_Memory_Read: Emulation: bank->size = %d\n", bank->size));
     *osize = isize;
-    for (loop = 0; loop < isize; loop++)
+    for (loop = 0; loop < isize; loop++) 
       data[loop] = bank->data[loop + offset];     
     return(U2F_SUCCESS);
   }
@@ -485,14 +505,24 @@
   u_int osize;
 
   DEBUG_TEXT(P_ID_U2F, 10, ("U2F_Reg_Read: Function called for reg = %d\n", reg));
-  if ((reg != O_ERRST)  && (reg != O_TRCFG)  && (reg != O_TRCNT) && (reg != O_IRADD) 
+  if ((reg != O_ERRST)  && (reg != O_TRCFG1)  && (reg != O_TRCNT) && (reg != O_IRADD) 
    && (reg != O_IRDAT)  && (reg != O_EVWORD) && (reg != O_LWADD) && (reg != O_ACTFEC) 
-   && (reg != O_FMIREG) && (reg != O_FMOREG) && (reg != O_RDOMOD))
+   && (reg != O_FMIREG) && (reg != O_FMOREG) && (reg != O_TRCFG2))
   {    
     DEBUG_TEXT(P_ID_U2F, 5, ("U2F_Reg_Read: Unknown register %d\n", reg));
     return(RCC_ERROR_RETURN(0, U2F_RANGE)); 
   }
-  return U2F_Memory_Read(&u2f_registers, 1, &osize, reg, data);
+  int ret = U2F_Memory_Read(&u2f_registers, 1, &osize, reg, data);
+  if (emode == SW) {
+    DEBUG_TEXT(P_ID_U2F, 1, ("Read 0x%08X from register 0x%04X\n",*data, reg));
+    if (reg == O_EVWORD && 
+	u2f_registers.data[O_EVWORD] == 0x0 &&
+	u2f_registers.data[O_TRCFG2] & 0x2) {
+      DEBUG_TEXT(P_ID_U2F, 1, ("Making hardware trigger in emulation mode\n"));
+      U2F_Exec_Command(C_SWTRG,0);
+    }
+  }
+  return ret;
 }  
 
 
@@ -521,10 +551,10 @@
 
 
 /*******************************/
-u_int U2F_TRCFG_Read(u_int* data)
+u_int U2F_TRCFG1_Read(u_int* data)
 /*******************************/
 {
-  return U2F_Reg_Read(O_TRCFG, data);
+  return U2F_Reg_Read(O_TRCFG1, data);
 }
 
 
@@ -575,10 +605,10 @@
 }
 
 /********************************/
-u_int U2F_RDOMOD_Read(u_int* data)
+u_int U2F_TRCFG2_Read(u_int* data)
 /********************************/
 {
-  return U2F_Reg_Read(O_RDOMOD, data);
+  return U2F_Reg_Read(O_TRCFG2, data);
 }
 
 
@@ -598,7 +628,7 @@
 
 
 /*****************************************************/
-u_int U2F_TRCFG_decode(u_int data, trcfg_t *parameters)
+u_int U2F_TRCFG1_decode(u_int data, trcfg_t *parameters)
 /*****************************************************/
 {
   U2FISOPEN;
@@ -644,14 +674,14 @@
 
 
 /**************************************/
-u_int U2F_TRCFG_Get(trcfg_t *parameters) 
+u_int U2F_TRCFG1_Get(trcfg_t *parameters) 
 /**************************************/
 {
   u_int data, ret;
   
-  ret = U2F_TRCFG_Read(&data);
+  ret = U2F_TRCFG1_Read(&data);
   if (ret) return ret;
-  return U2F_TRCFG_decode(data, parameters);
+  return U2F_TRCFG1_decode(data, parameters);
 }
 
 
@@ -692,8 +722,9 @@
     DEBUG_TEXT(P_ID_U2F, 20 , ("U2F_Memory_Write: Emulation: offset     = %d\n", offset));
     DEBUG_TEXT(P_ID_U2F, 20 , ("U2F_Memory_Write: Emulation: bank->id   = 0x%0x4\n", bank->id));
     DEBUG_TEXT(P_ID_U2F, 20 , ("U2F_Memory_Write: Emulation: bank->size = %d\n", bank->size));
-    for (loop = 0; loop < osize; loop++)
-       bank->data[loop + offset] = data[loop];     
+    for (loop = 0; loop < osize; loop++) 
+      bank->data[loop + offset] = (data[loop] & 
+				   (bank->mask1 + (bank->mask2 << 16)));
     return(U2F_SUCCESS);
   }
  
@@ -770,7 +801,6 @@
 /************************************************************/
 {
   u_int ret;
-  
   DEBUG_TEXT(P_ID_U2F, 10 ,("U2F_IMEM_Write: osize=%d\n", osize));
   ret = U2F_Memory_Write(&u2f_acl, osize, offset, data);
   return ret;
@@ -782,7 +812,7 @@
 /***********************************************************************/
 {
   static u_int low[2048], high[2048];
-  u_int ret, loop, ptr1, ptr2, ptr3;
+  u_int ret, loop;
   
   u2f_bank_t* lbank = 0;
   u2f_bank_t* hbank = 0;
@@ -802,17 +832,10 @@
   }
 
   DEBUG_TEXT(P_ID_U2F, 20, ("Writing to DM%d of size %d starting at %d\n", which, osize, offset));
-  ptr1 = 2;
-  ptr2 = 2;
-  ptr3 = 0;
   for (loop = 0; loop < osize; loop++) 
   {
-    low[ptr1++]  = data[ptr3]         & 0xffff;
-    low[ptr1++]  = (data[ptr3] >> 16) & 0x000f;
-    ptr3++;
-    high[ptr2++] = data[ptr3]         & 0xffff;
-    high[ptr2++] = (data[ptr3] >> 16) & 0x000f;
-    ptr3++;
+    low[loop]   = (data[4*loop+0] & 0x3ff) + ((data[4*loop+1] & 0x3ff)<<10);
+    high[loop]  = (data[4*loop+2] & 0x3ff) + ((data[4*loop+3] & 0x3ff)<<10);
   }  
  
   ret = U2F_Memory_Write(lbank, osize, offset, low);
@@ -845,22 +868,23 @@
   int ret;
   DEBUG_TEXT(P_ID_U2F, 20 , ("U2F_Reg_Write: reg = %d  data = %d\n", reg, data));
   
-  if ((reg != O_TRCFG) && (reg != O_ACTFEC) && (reg != O_FMIREG) && (reg != O_FMOREG) && (reg != O_RDOMOD)) 
+  if ((reg != O_TRCFG1) && (reg != O_ACTFEC) && (reg != O_FMIREG) && (reg != O_FMOREG) && (reg != O_TRCFG2)) 
   {    
     DEBUG_TEXT(P_ID_U2F, 5 , ("U2F_Reg_Write: The parameter reg is out of range (reg=%d)\n", reg));
     return(RCC_ERROR_RETURN(0, U2F_RANGE)); 
   } 
   ret = U2F_Memory_Write(&u2f_registers, 1, reg, &data);
-  
+  if (emode == SW) 
+    DEBUG_TEXT(P_ID_U2F, 1, ("Writing 0x%08X to register 0x%04X\n",data, reg));
   return(U2F_SUCCESS);
 }
 
 
 /*******************************/
-u_int U2F_TRCFG_Write(u_int data)
+u_int U2F_TRCFG1_Write(u_int data)
 /*******************************/
 {
-  return U2F_Reg_Write(O_TRCFG, data);
+  return U2F_Reg_Write(O_TRCFG1, data);
 }
 
 
@@ -873,46 +897,49 @@
 
 
 /*****************************************************/
-u_int U2F_TRCFG_encode(u_int *data, trcfg_t parameters)
+u_int U2F_TRCFG1_encode(u_int *data, trcfg_t parameters)
 /*****************************************************/
 {
   U2FISOPEN;
 
   if (parameters.tw > 0x3fff) 
   {    
-    DEBUG_TEXT(P_ID_U2F, 5 , ("U2F_TRCFG_encode: Parameter tw is out of range\n"));
+    DEBUG_TEXT(P_ID_U2F, 5 , ("U2F_TRCFG1_encode: Parameter tw is out of range\n"));
     return(RCC_ERROR_RETURN(0, U2F_RANGE));
   }       
   
   if (parameters.bmd > 2) 
   {    
-    DEBUG_TEXT(P_ID_U2F, 5 , ("U2F_TRCFG_encode: Parameter bmd is out of range\n"));
+    DEBUG_TEXT(P_ID_U2F, 5 , ("U2F_TRCFG1_encode: Parameter bmd is out of range\n"));
     return(RCC_ERROR_RETURN(0, U2F_RANGE));
   }     
 
   if ((parameters.mode > 3) || (parameters.mode == 1)) 
   {    
-    DEBUG_TEXT(P_ID_U2F, 5 , ("U2F_TRCFG_encode: Parameter mode is out of range\n"));
+    DEBUG_TEXT(P_ID_U2F, 5 , ("U2F_TRCFG1_encode: Parameter mode is out of range\n"));
     return(RCC_ERROR_RETURN(0, U2F_RANGE));
   }  
-
-  *data = parameters.tw + (parameters.bmd << 14) + (parameters.mode << 15) + 0x40000;
+  *data = ((parameters.tw  & 0x3fff)
+	   + ((parameters.bmd  & 0x1) << 14)
+	   + ((parameters.mode & 0x3) << 15)
+	   /* + ((parameters.opt  & 0x1) << 17) */
+	   /* + ((parameters.pop  & 0x1) << 18) */
+	   + 0x40000);
   
-  DEBUG_TEXT(P_ID_U2F, 20 , ("U2F_TRCFG_encode: The encoded data word is %d\n", *data));
+  DEBUG_TEXT(P_ID_U2F, 20 , ("U2F_TRCFG1_encode: The encoded data word is %d\n", *data));
  
   return(U2F_SUCCESS);
 }
 
   
 /*************************************/
-u_int U2F_TRCFG_Set(trcfg_t parameters)
+u_int U2F_TRCFG1_Set(trcfg_t parameters)
 /*************************************/
 {
-  u_int data, ret;
-  
-  ret = U2F_TRCFG_encode(&data, parameters);
+  u_int data, ret;			     
+  ret = U2F_TRCFG1_encode(&data, parameters);
   if (ret) return ret;
-  return U2F_TRCFG_Write(data);
+  return U2F_TRCFG1_Write(data);
 }
 
   
@@ -966,7 +993,7 @@
   
   /* write  the file */
   for (loop = 0; loop < size; loop++)
-    fprintf(outf,"%x\n",data[loop]);
+    fprintf(outf,"0x%x\n",data[loop]);
 
   fclose(outf);
   return(U2F_SUCCESS);  
@@ -977,12 +1004,14 @@
 u_int U2F_Exec_Command(u_int command, u_int data)
 /***********************************************/
 {
-  static u_int dmem1cnt = 0;
-  static u_int dmem2cnt = 0;
   altro_bulk_out_t out;
   u_short *msg;
   u_int address, i, ret;
-    
+  static u_int chip      = 0;
+  static u_int channel   = 0;
+  static u_int mem       = 1;
+  static u_int ntimebins = 256;
+  
   U2FISOPEN;
   DEBUG_TEXT(P_ID_U2F, 10 , ("U2F_Exec_Command: Called\n"));
 
@@ -1016,25 +1045,25 @@
     switch(command)
     {
       case C_RS_STATUS:
-        printf("Status reset");
+        DEBUG_TEXT(P_ID_U2F, 1, ("Status reset"));
         u2f_registers.data[O_ERRST] = 0x0;
         break;
 
       case C_RS_TRCFG:
-        printf("Trigger config reset");
-        u2f_registers.data[O_TRCFG] = 0x0;
+        DEBUG_TEXT(P_ID_U2F, 1, ("Trigger config reset"));
+        u2f_registers.data[O_TRCFG1] = 0x0;
         break;
       
       case C_RS_TRCNT:
-        printf("Trigger counter reset");
+        DEBUG_TEXT(P_ID_U2F, 1, ("Trigger counter reset"));
         u2f_registers.data[O_TRCNT] = 0x0;
         break;
       
       case C_EXEC:
-	printf("Execute instruction memory at offset %d\n", data);
+	DEBUG_TEXT(P_ID_U2F, 1, ("Execute instruction memory at offset %d\n", data));
 	for (i = data; i < u2f_imem.size; i++) 
 	{
-	  printf("%3d  0x%08x\n", i, u2f_imem.data[i]);
+	  DEBUG_TEXT(P_ID_U2F, 1, ("%3d  0x%08x\n", i, u2f_imem.data[i]));
 	  if (u2f_imem.data[i] == 0x390000) break;
 	  if (u2f_imem.data[i] & (1 << 22)) 
 	  {
@@ -1042,59 +1071,71 @@
 	      u2f_registers.data[O_IRDAT] = u2f_imem.data[i];
 	    else 
 	      u2f_registers.data[O_IRADD] = u2f_imem.data[i];
+	    if (!(u2f_imem.data[i] & (1 << 17)) && 
+		(u2f_imem.data[i] & (1 << 18)) && 
+		(u2f_imem.data[i] &  0xf) == 0xa) {
+	      /** Update aquisition window */
+	      i++;
+	      ntimebins = ((u2f_imem.data[i] & 0x3ff) - 
+			   ((u2f_imem.data[i] >> 10) & 0x3ff));
+	      DEBUG_TEXT(P_ID_U2F, 1, ("%3d  0x%08x\n", i, u2f_imem.data[i]));
+	      DEBUG_TEXT(P_ID_U2F, 1, ("Number of time bins %d\n", ntimebins));
+	    }
 	  }
 	}
 	return(ALTRO_SUCCESS);
       
       case C_ABORT:
-        printf("Abort current instructions\n");
+        DEBUG_TEXT(P_ID_U2F, 1, ("Abort current instructions\n"));
         break;
       
       case C_FECRST:
-        printf("Reset front end cards\n");
+        DEBUG_TEXT(P_ID_U2F, 1, ("Reset front end cards\n"));
         break;
       
       case C_SWTRG:
-	printf("Software trigger\n");
+	DEBUG_TEXT(P_ID_U2F, 1, ("Software trigger\n"));
 	u2f_registers.data[O_EVWORD] =  0x1B;
 	u2f_registers.data[O_TRCNT]  += 0x1001;
-	u2f_registers.data[O_LWADD]  =  0x4242;
-	write_dummy_data(1, 0, 0, 256);
-	write_dummy_data(2, 0, 1, 256);
+	u2f_registers.data[O_LWADD]  += 0x0;
+	chip    = 0;
+	channel = 0;
+	mem     = 0;
+	write_next_data(1, &chip, &channel, ntimebins);
+	write_next_data(2, &chip, &channel, ntimebins);
         break;
-      
       case C_RS_DMEM1:
-	printf("DMEM 1 reset\n");
-	dmem1cnt++;
-	if (dmem1cnt >= 16) 
-	  dmem1cnt = 0;
+	DEBUG_TEXT(P_ID_U2F, 1, ("DMEM 1 reset\n"));
+	u2f_registers.data[O_EVWORD] ^= 0x2;
+	write_next_data(1, &chip, &channel, ntimebins);
+	if ((u2f_registers.data[O_EVWORD] & 0x3) == 0) 
+	  u2f_registers.data[O_EVWORD] = 0x4;
+	DEBUG_TEXT(P_ID_U2F, 1, ("EVWORD 0x%x\n", u2f_registers.data[O_EVWORD]));
         break;
       
       case C_RS_DMEM2:
-	printf("DMEM 2 reset\n");
-	dmem2cnt++;
-	if (dmem2cnt >= 16) 
-	{
-	  dmem2cnt = 0;
+	DEBUG_TEXT(P_ID_U2F, 1, ("DMEM 2 reset\n"));
+	u2f_registers.data[O_EVWORD] ^= 0x1;
+	write_next_data(2, &chip, &channel, ntimebins);
+	if ((u2f_registers.data[O_EVWORD] & 0x3) == 0) 
 	  u2f_registers.data[O_EVWORD] = 0x4;
-	}
-        break;
-      
+	DEBUG_TEXT(P_ID_U2F, 1, ("EVWORD 0x%x\n", u2f_registers.data[O_EVWORD]));
+        break;      
       case C_TRG_CLR:
-        printf("Event word reset");
+        DEBUG_TEXT(P_ID_U2F, 1, ("Event word reset"));
         u2f_registers.data[O_EVWORD] = 0x0;
         break;
       
       case C_WRFM:
-        printf("Write FM");
+        DEBUG_TEXT(P_ID_U2F, 1, ("Write FM"));
         break;
       
       case C_RDFM:
-        printf("Read FM");
+        DEBUG_TEXT(P_ID_U2F, 1, ("Read FM"));
         break;
 
       case C_RDABORT:
-        printf("Abort large block read out");
+        DEBUG_TEXT(P_ID_U2F, 1, ("Abort large block read out"));
         break;
     }
     return(U2F_SUCCESS);
@@ -1246,7 +1287,7 @@
   if (mode & M_FIRST)
   {
     DEBUG_TEXT(P_ID_U2F, 20 ,("U2F_ReadOut: Enabling read-out mode\n"));
-    ret = U2F_Reg_Write(O_RDOMOD, 3);
+    ret = U2F_Reg_Write(O_TRCFG2, 3);
     if (ret)
     {
       ALTRO_err_get(ret, pid, code);
@@ -1288,7 +1329,7 @@
 	}
 
 	DEBUG_TEXT(P_ID_U2F, 20 ,("U2F_ReadOut: Disabling read-out mode\n"));
-	ret = U2F_Reg_Write(O_RDOMOD, 2);
+	ret = U2F_Reg_Write(O_TRCFG2, 2);
 	if (ret)
 	{
 	  ALTRO_err_get(ret, pid, code);
@@ -1340,7 +1381,7 @@
     }
 	    
     DEBUG_TEXT(P_ID_U2F, 20 ,("U2F_ReadOut: Disabling read-out mode\n"));
-    ret = U2F_Reg_Write(O_RDOMOD, 0);
+    ret = U2F_Reg_Write(O_TRCFG2, 0);
     if (ret)
     {
       ALTRO_err_get(ret, pid, code);
@@ -1355,49 +1396,80 @@
 
 
 /*************************/
-u_int make_dummy_data(void) 
+u_int make_dummy_data(u_int i) 
 /*************************/
 {
-  return 48 + (u_int)(5 * (float)rand() / RAND_MAX);
+  return i; // 48 + (u_int)(5 * (float)rand() / RAND_MAX);
 }
 
 
+void write_next_data(u_int which, u_int *chip, u_int *channel, u_int len) 
+{
+  u_int mem = 0;
+  for (;*chip < u2f_acl.size; (*chip)++) {
+    for (;*channel < 16; (*channel)++) {
+      if (u2f_acl.data[*chip] & (1 << *channel)) {
+	mem = which;
+	break;
+      }
+    }
+    if (mem) break;
+  }
+  if (!mem) return;
+  write_dummy_data(mem, *chip, *channel, len);
+  (*channel)++;
+  if ((*channel) >= 16) {
+    (*channel) = 0;
+    (*chip)++;
+  }
+}
+
+	
+
 /*******************************************************************/
 void write_dummy_data(u_int which, u_int chip, u_int chan, u_int len) 
 /*******************************************************************/
 {
   typedef unsigned long long w40_t;
-  static u_int data[512];
-  u_int trailer = ((((w40_t)0x2aaa) << 26) + (((w40_t)len) << 16) + (((w40_t)0xa) << 12) + (((w40_t)chip) << 4) + (((w40_t)chan) << 4));
-  u_int i, j = 0, n = len / 4, m = len % 4;
-
-  for (i = 0; i < n; i++) 
-  {
-    data[2 * i + 0] = make_dummy_data(); 
-    data[4 * i + 1] = make_dummy_data(); 
-    data[4 * i + 2] = make_dummy_data(); 
-    data[4 * i + 3] = make_dummy_data(); 
-    j += 4;
-  }
-  
-  for (i = 0; i < m; i++) 
-  {
-    data[2 * n + i] = make_dummy_data(); 
-    j++;
-  }
-  
-  for (; i < 4; i++) 
-  {
-    data[2 * n + i] = 0x2aa;
-    j++;
+  static u_int data[1024+4+4];
+  w40_t trailer = ((((w40_t)0x2aaa)            << 26) + 
+		   (((w40_t)((len+2) & 0x3ff)) << 16) + 
+		   (((w40_t)0xa)               << 12) + 
+		   (((w40_t)(chip & 0xff))     << 4) + 
+		   (((w40_t)(chan & 0xf))));
+  u_int i, j = 0, k; /* , n = (len+2) / 4, m = (len+2) % 4; */
+  // int ii;
+  
+  DEBUG_TEXT(P_ID_U2F, 1, ("Preparing psuedo data to DMEM%d (chip %d, chan %d) of size %d\n", which, chip, chan, len));
+  for (i = 0; i < len; i++) 
+  {
+    data[i] = make_dummy_data(i);
+  }
+  data[i] = len-1; i++;
+  data[i] = len+2; i++;
+  if (!(i % 4 == 0)) {
+    for (j = 0; j < (i % 4); j++) {
+      data[i] = 0x2aa;
+      i++;
+    }
   }
-  
-  data[2 * (n + 1) + 0] = (trailer >>  0) & 0xfffff;
-  data[2 * (n + 1) + 1] = (trailer >> 20) & 0xfffff;
-  j += 4;
-  
-  printf("Writing psuedo data to DMEM%d of size %d\n", which, j);
-  U2F_DM_Write(which, j / 4, 0, data);
+  data[i] =  (int)((trailer >>  0) & 0x3ff);  i++;
+  data[i] =  (int)((trailer >> 10) & 0x3ff);  i++;
+  data[i] =  (int)((trailer >> 20) & 0x3ff);  i++;
+  data[i] =  (int)((trailer >> 30) & 0x3ff);  i++;
+  
+  DEBUG_TEXT(P_ID_U2F, 1, ("Writing psuedo data to DMEM%d of size %d\n", which, j));
+#if 0
+  for (i = 0; i < j/4; i++) {
+    printf("%4d 0x%03X 0x%03X 0x%03X 0x%03X\n", i,  
+	   data[4*i+0], data[4*i+1],data[4*i+2],data[4*i+3]);
+  }
+#endif
+  k = (which == 2 ? ((i/4) << 8) : i/4);
+  u2f_registers.data[O_LWADD]  |= k;
+  k = (which == 2 ? 0x1 : 0x2);
+  u2f_registers.data[O_EVWORD] |= k;
+  U2F_DM_Write(which, i / 4, 0, data);
 }
 /***************************************************************/
 unsigned int U2F_err_get(err_pack err, err_str pid, err_str code)
diff -u -r -N -xCVS u2f.cern/u2f/u2fscope.c u2f/u2f/u2fscope.c
--- u2f.cern/u2f/u2fscope.c	2005-11-21 10:06:19.000000000 +0100
+++ u2f/u2f/u2fscope.c	2006-01-26 04:03:48.000000000 +0100
@@ -105,7 +105,7 @@
   static trcfg_t trcfg_s;
   static trcnt_t trcnt_s;
   u_int loop, osize, index;
-  FILE  *file;
+  FILE  *file = 0;
   int yesFile = 0;
   u_short *rodata, sd1, sd2, ad1, ad2;
   tstamp ts1, ts2;
