## Automatically generated incremental diff
## From:   linux-2.4.17-pre6
## To:     linux-2.4.17-pre7
## Robot:  $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $

diff -urN linux-2.4.17-pre6/Documentation/isdn/INTERFACE linux/Documentation/isdn/INTERFACE
--- linux-2.4.17-pre6/Documentation/isdn/INTERFACE	Mon Mar 26 15:38:19 2001
+++ linux/Documentation/isdn/INTERFACE	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-$Id: INTERFACE,v 1.15.8.2 2001/03/13 16:17:07 kai Exp $
+$Id: INTERFACE,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
 
 Description of the Interface between Linklevel and Hardwarelevel
   of isdn4linux:
diff -urN linux-2.4.17-pre6/Documentation/isdn/INTERFACE.fax linux/Documentation/isdn/INTERFACE.fax
--- linux-2.4.17-pre6/Documentation/isdn/INTERFACE.fax	Mon Nov 27 16:53:43 2000
+++ linux/Documentation/isdn/INTERFACE.fax	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-$Id: INTERFACE.fax,v 1.2 2000/08/06 09:22:50 armin Exp $
+$Id: INTERFACE.fax,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
 
 
 Description of the fax-subinterface between linklevel and hardwarelevel of 
diff -urN linux-2.4.17-pre6/Documentation/isdn/README.act2000 linux/Documentation/isdn/README.act2000
--- linux-2.4.17-pre6/Documentation/isdn/README.act2000	Sat Nov 11 18:58:02 2000
+++ linux/Documentation/isdn/README.act2000	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-$Id: README.act2000,v 1.3 2000/08/06 09:22:51 armin Exp $
+$Id: README.act2000,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
 
 This document describes the ACT2000 driver for the
 IBM Active 2000 ISDN card.
diff -urN linux-2.4.17-pre6/Documentation/isdn/README.audio linux/Documentation/isdn/README.audio
--- linux-2.4.17-pre6/Documentation/isdn/README.audio	Thu Aug 12 09:42:33 1999
+++ linux/Documentation/isdn/README.audio	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-$Id: README.audio,v 1.8 1999/07/11 17:17:29 armin Exp $
+$Id: README.audio,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
 
 ISDN subsystem for Linux.
   Description of audio mode.
diff -urN linux-2.4.17-pre6/Documentation/isdn/README.eicon linux/Documentation/isdn/README.eicon
--- linux-2.4.17-pre6/Documentation/isdn/README.eicon	Mon Mar 26 15:38:19 2001
+++ linux/Documentation/isdn/README.eicon	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-$Id: README.eicon,v 1.10.6.1 2001/02/19 10:04:59 armin Exp $
+$Id: README.eicon,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
 
 (c) 1999,2000 Armin Schindler (mac@melware.de)
 (c) 1999,2000 Cytronics & Melware (info@melware.de)
diff -urN linux-2.4.17-pre6/Documentation/isdn/README.hysdn linux/Documentation/isdn/README.hysdn
--- linux-2.4.17-pre6/Documentation/isdn/README.hysdn	Fri Mar  2 11:12:12 2001
+++ linux/Documentation/isdn/README.hysdn	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-$Id: README.hysdn,v 1.3.6.1 2001/02/10 14:41:19 kai Exp $
+$Id: README.hysdn,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
 The hysdn driver has been written by
 by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) 
 for Hypercope GmbH Aachen Germany. Hypercope agreed to publish this driver
diff -urN linux-2.4.17-pre6/Documentation/isdn/README.icn linux/Documentation/isdn/README.icn
--- linux-2.4.17-pre6/Documentation/isdn/README.icn	Sat Nov 11 18:58:03 2000
+++ linux/Documentation/isdn/README.icn	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-$Id: README.icn,v 1.7 2000/08/06 09:22:51 armin Exp $
+$Id: README.icn,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
 
 You can get the ICN-ISDN-card from:
 
diff -urN linux-2.4.17-pre6/Makefile linux/Makefile
--- linux-2.4.17-pre6/Makefile	Sun Dec  9 12:39:27 2001
+++ linux/Makefile	Sun Dec  9 12:40:04 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 17
-EXTRAVERSION = -pre6
+EXTRAVERSION = -pre7
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.17-pre6/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- linux-2.4.17-pre6/arch/i386/boot/setup.S	Sun Dec  9 12:39:27 2001
+++ linux/arch/i386/boot/setup.S	Fri Nov  9 13:58:02 2001
@@ -539,7 +539,7 @@
 	cmpw	$0, %cs:realmode_swtch
 	jz	rmodeswtch_normal
 
-	lcall	*%cs:realmode_swtch
+	lcall	%cs:realmode_swtch
 
 	jmp	rmodeswtch_end
 
diff -urN linux-2.4.17-pre6/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
--- linux-2.4.17-pre6/drivers/char/agp/agpgart_be.c	Sun Dec  9 12:39:27 2001
+++ linux/drivers/char/agp/agpgart_be.c	Sun Dec  9 12:40:04 2001
@@ -3252,8 +3252,18 @@
 	 *        AGP devices and collect their data.
 	 */
 
-	while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8,
-					device)) != NULL) {
+
+	pci_for_each_dev(device)
+	{
+		/*
+		 *	Enable AGP devices. Most will be VGA display but
+		 *	some may be coprocessors on non VGA devices too
+		 */
+		 
+		if((((device->class >> 16) & 0xFF) != PCI_BASE_CLASS_DISPLAY) &&
+			(device->class != (PCI_CLASS_PROCESSOR_CO << 8)))
+			continue;
+
 		pci_read_config_dword(device, 0x04, &scratch);
 
 		if (!(scratch & 0x00100000))
diff -urN linux-2.4.17-pre6/drivers/char/ip2/i2ellis.c linux/drivers/char/ip2/i2ellis.c
--- linux-2.4.17-pre6/drivers/char/ip2/i2ellis.c	Sun Dec  9 12:39:27 2001
+++ linux/drivers/char/ip2/i2ellis.c	Wed Oct 24 12:05:18 2001
@@ -102,7 +102,6 @@
 // This routine performs any required cleanup of the iiEllis subsystem.
 //
 //******************************************************************************
-#if 0 /* Unused */
 static void
 iiEllisCleanup(void)
 {
@@ -110,7 +109,6 @@
 		kfree ( pDelayTimer );
 	}
 }
-#endif
 
 //******************************************************************************
 // Function:   iiSetAddress(pB, address, delay)
diff -urN linux-2.4.17-pre6/drivers/isdn/Config.in linux/drivers/isdn/Config.in
--- linux-2.4.17-pre6/drivers/isdn/Config.in	Sun Dec  9 12:39:27 2001
+++ linux/drivers/isdn/Config.in	Sun Dec  9 12:40:04 2001
@@ -42,6 +42,7 @@
    fi
    bool '  HiSax Support for german 1TR6' CONFIG_HISAX_1TR6
    bool '  HiSax Support for US NI1' CONFIG_HISAX_NI1
+   int  '  Maximum number of cards supported by HiSax' CONFIG_HISAX_MAX_CARDS 8
    comment '  HiSax supported cards'
    bool '  Teles 16.0/8.0' CONFIG_HISAX_16_0
    bool '  Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3
diff -urN linux-2.4.17-pre6/drivers/isdn/act2000/act2000.h linux/drivers/isdn/act2000/act2000.h
--- linux-2.4.17-pre6/drivers/isdn/act2000/act2000.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/act2000/act2000.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: act2000.h,v 1.8.6.3 2001/09/23 22:24:32 kai Exp $
+/* $Id: act2000.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/act2000/act2000_isa.c linux/drivers/isdn/act2000/act2000_isa.c
--- linux-2.4.17-pre6/drivers/isdn/act2000/act2000_isa.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/act2000/act2000_isa.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: act2000_isa.c,v 1.11.6.3 2001/09/23 22:24:32 kai Exp $
+/* $Id: act2000_isa.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version).
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/act2000/act2000_isa.h linux/drivers/isdn/act2000/act2000_isa.h
--- linux-2.4.17-pre6/drivers/isdn/act2000/act2000_isa.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/act2000/act2000_isa.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: act2000_isa.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $
+/* $Id: act2000_isa.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version).
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/act2000/capi.c linux/drivers/isdn/act2000/capi.c
--- linux-2.4.17-pre6/drivers/isdn/act2000/capi.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/act2000/capi.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capi.c,v 1.9.6.2 2001/09/23 22:24:32 kai Exp $
+/* $Id: capi.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  * CAPI encoder/decoder
diff -urN linux-2.4.17-pre6/drivers/isdn/act2000/capi.h linux/drivers/isdn/act2000/capi.h
--- linux-2.4.17-pre6/drivers/isdn/act2000/capi.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/act2000/capi.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capi.h,v 1.6.6.2 2001/09/23 22:24:32 kai Exp $
+/* $Id: capi.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/act2000/module.c linux/drivers/isdn/act2000/module.c
--- linux-2.4.17-pre6/drivers/isdn/act2000/module.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/act2000/module.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: module.c,v 1.14.6.4 2001/09/23 22:24:32 kai Exp $
+/* $Id: module.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/avm_cs.c linux/drivers/isdn/avmb1/avm_cs.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/avm_cs.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/avm_cs.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: avm_cs.c,v 1.4.6.3 2001/09/23 22:24:33 kai Exp $
+/* $Id: avm_cs.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * A PCMCIA client driver for AVM B1/M1/M2
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/avmcard.h linux/drivers/isdn/avmb1/avmcard.h
--- linux-2.4.17-pre6/drivers/isdn/avmb1/avmcard.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/avmcard.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: avmcard.h,v 1.8.6.4 2001/09/23 22:24:33 kai Exp $
+/* $Id: avmcard.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/b1.c linux/drivers/isdn/avmb1/b1.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/b1.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/b1.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: b1.c,v 1.20.6.7 2001/09/23 22:24:33 kai Exp $
+/* $Id: b1.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Common module for AVM B1 cards.
  * 
@@ -27,7 +27,7 @@
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.20.6.7 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 /* ------------------------------------------------------------- */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/b1dma.c linux/drivers/isdn/avmb1/b1dma.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/b1dma.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/b1dma.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: b1dma.c,v 1.11.6.8 2001/09/23 22:24:33 kai Exp $
+/* $Id: b1dma.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Common module for AVM B1 cards that support dma with AMCC
  * 
@@ -32,7 +32,7 @@
 #error FIXME: driver requires 32-bit platform
 #endif
 
-static char *revision = "$Revision: 1.11.6.8 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 /* ------------------------------------------------------------- */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/b1isa.c linux/drivers/isdn/avmb1/b1isa.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/b1isa.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/b1isa.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: b1isa.c,v 1.10.6.6 2001/09/23 22:24:33 kai Exp $
+/* $Id: b1isa.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Module for AVM B1 ISA-card.
  * 
@@ -24,7 +24,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.10.6.6 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 /* ------------------------------------------------------------- */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/b1pci.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/b1pci.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: b1pci.c,v 1.29.6.5 2001/09/23 22:24:33 kai Exp $
+/* $Id: b1pci.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Module for AVM B1 PCI-card.
  * 
@@ -26,7 +26,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.29.6.5 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 /* ------------------------------------------------------------- */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/b1pcmcia.c linux/drivers/isdn/avmb1/b1pcmcia.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/b1pcmcia.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/b1pcmcia.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: b1pcmcia.c,v 1.12.6.5 2001/09/23 22:24:33 kai Exp $
+/* $Id: b1pcmcia.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Module for AVM B1/M1/M2 PCMCIA-card.
  * 
@@ -25,7 +25,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.12.6.5 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 /* ------------------------------------------------------------- */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/c4.c linux/drivers/isdn/avmb1/c4.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/c4.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/c4.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: c4.c,v 1.20.6.11 2001/09/23 22:24:33 kai Exp $
+/* $Id: c4.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Module for AVM C4 & C2 card.
  * 
@@ -29,7 +29,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.20.6.11 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 #undef CONFIG_C4_DEBUG
 #undef CONFIG_C4_POLLDEBUG
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capi.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capi.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capi.c,v 1.44.6.15 2001/09/28 08:05:29 kai Exp $
+/* $Id: capi.c,v 1.1.4.2 2001/12/09 18:45:13 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
@@ -45,7 +45,7 @@
 #include "capifs.h"
 #endif
 
-static char *revision = "$Revision: 1.44.6.15 $";
+static char *revision = "$Revision: 1.1.4.2 $";
 
 MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
 MODULE_AUTHOR("Carsten Paeth");
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capicmd.h linux/drivers/isdn/avmb1/capicmd.h
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capicmd.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capicmd.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capicmd.h,v 1.2.6.2 2001/09/23 22:24:33 kai Exp $
+/* $Id: capicmd.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * CAPI 2.0 Interface for Linux
  * 
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capidev.h linux/drivers/isdn/avmb1/capidev.h
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capidev.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capidev.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capidev.h,v 1.6.6.2 2001/09/23 22:24:33 kai Exp $
+/* $Id: capidev.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capidrv.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capidrv.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capidrv.c,v 1.39.6.7 2001/09/23 22:24:33 kai Exp $
+/* $Id: capidrv.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
@@ -35,7 +35,7 @@
 #include "capicmd.h"
 #include "capidrv.h"
 
-static char *revision = "$Revision: 1.39.6.7 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 static int debugmode = 0;
 
 MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capidrv.h linux/drivers/isdn/avmb1/capidrv.h
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capidrv.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capidrv.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capidrv.h,v 1.2.8.2 2001/09/23 22:24:33 kai Exp $
+/* $Id: capidrv.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capifs.c linux/drivers/isdn/avmb1/capifs.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capifs.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capifs.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capifs.c,v 1.14.6.8 2001/09/23 22:24:33 kai Exp $
+/* $Id: capifs.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Copyright 2000 by Carsten Paeth <calle@calle.de>
  *
@@ -32,7 +32,7 @@
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
 
-static char *revision = "$Revision: 1.14.6.8 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 struct capifs_ncci {
 	struct inode *inode;
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capifs.h linux/drivers/isdn/avmb1/capifs.h
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capifs.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capifs.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capifs.h,v 1.2.6.2 2001/09/23 22:24:33 kai Exp $
+/* $Id: capifs.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Copyright 2000 by Carsten Paeth <calle@calle.de>
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capilli.h linux/drivers/isdn/avmb1/capilli.h
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capilli.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capilli.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capilli.h,v 1.4.8.1 2001/09/23 22:24:33 kai Exp $
+/* $Id: capilli.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Kernel CAPI 2.0 Driver Interface for Linux
  * 
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capiutil.c linux/drivers/isdn/avmb1/capiutil.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capiutil.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capiutil.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capiutil.c,v 1.13.6.4 2001/09/23 22:24:33 kai Exp $
+/* $Id: capiutil.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * CAPI 2.0 convert capi message to capi message struct
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/capiutil.h linux/drivers/isdn/avmb1/capiutil.h
--- linux-2.4.17-pre6/drivers/isdn/avmb1/capiutil.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/capiutil.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: capiutil.h,v 1.5.6.2 2001/09/23 22:24:33 kai Exp $
+/* $Id: capiutil.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * CAPI 2.0 defines & types
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/kcapi.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/kcapi.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: kcapi.c,v 1.21.6.8 2001/09/23 22:24:33 kai Exp $
+/* $Id: kcapi.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Kernel CAPI 2.0 Module
  * 
@@ -33,7 +33,7 @@
 #include <linux/b1lli.h>
 #endif
 
-static char *revision = "$Revision: 1.21.6.8 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 /* ------------------------------------------------------------- */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/t1isa.c linux/drivers/isdn/avmb1/t1isa.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/t1isa.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/t1isa.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: t1isa.c,v 1.16.6.7 2001/09/23 22:24:34 kai Exp $
+/* $Id: t1isa.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Module for AVM T1 HEMA-card.
  * 
@@ -25,7 +25,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.16.6.7 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 /* ------------------------------------------------------------- */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/avmb1/t1pci.c linux/drivers/isdn/avmb1/t1pci.c
--- linux-2.4.17-pre6/drivers/isdn/avmb1/t1pci.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/avmb1/t1pci.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: t1pci.c,v 1.13.6.6 2001/09/23 22:24:34 kai Exp $
+/* $Id: t1pci.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Module for AVM T1 PCI-card.
  * 
@@ -26,7 +26,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.13.6.6 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 
 #undef CONFIG_T1PCI_DEBUG
 #undef CONFIG_T1PCI_POLLDEBUG
diff -urN linux-2.4.17-pre6/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c
--- linux-2.4.17-pre6/drivers/isdn/divert/divert_procfs.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/divert/divert_procfs.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: divert_procfs.c,v 1.11.6.2 2001/09/23 22:24:36 kai Exp $
+/* $Id: divert_procfs.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * Filesystem handling for the diversion supplementary services.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/divert/isdn_divert.c linux/drivers/isdn/divert/isdn_divert.c
--- linux-2.4.17-pre6/drivers/isdn/divert/isdn_divert.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/divert/isdn_divert.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_divert.c,v 1.6.6.3 2001/09/23 22:24:36 kai Exp $
+/* $Id: isdn_divert.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * DSS1 main diversion supplementary handling for i4l.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/divert/isdn_divert.h linux/drivers/isdn/divert/isdn_divert.h
--- linux-2.4.17-pre6/drivers/isdn/divert/isdn_divert.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/divert/isdn_divert.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_divert.h,v 1.5.6.1 2001/09/23 22:24:36 kai Exp $
+/* $Id: isdn_divert.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * Header for the diversion supplementary ioctl interface.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/Makefile linux/drivers/isdn/hisax/Makefile
--- linux-2.4.17-pre6/drivers/isdn/hisax/Makefile	Sun Dec  9 12:39:27 2001
+++ linux/drivers/isdn/hisax/Makefile	Sun Dec  9 12:40:04 2001
@@ -4,6 +4,10 @@
 
 O_TARGET	  := vmlinux-obj.o
 
+# Define maximum number of cards
+
+EXTRA_CFLAGS      += -DHISAX_MAX_CARDS=$(CONFIG_HISAX_MAX_CARDS)
+
 # Objects that export symbols.
 
 export-objs	  := config.o fsm.o hisax_isac.o
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/amd7930.c linux/drivers/isdn/hisax/amd7930.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/amd7930.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/amd7930.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: amd7930.c,v 1.5.6.4 2001/09/23 22:24:46 kai Exp $
+/* $Id: amd7930.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * HiSax ISDN driver - chip specific routines for AMD 7930
  *
@@ -98,7 +98,7 @@
 #include "rawhdlc.h"
 #include <linux/interrupt.h>
 
-static const char *amd7930_revision = "$Revision: 1.5.6.4 $";
+static const char *amd7930_revision = "$Revision: 1.1.4.1 $";
 
 #define RCV_BUFSIZE	1024	/* Size of raw receive buffer in bytes */
 #define RCV_BUFBLKS	4	/* Number of blocks to divide buffer into
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/arcofi.c linux/drivers/isdn/hisax/arcofi.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/arcofi.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/arcofi.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: arcofi.c,v 1.12.6.2 2001/09/23 22:24:46 kai Exp $
+/* $Id: arcofi.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * Ansteuerung ARCOFI 2165
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/arcofi.h linux/drivers/isdn/hisax/arcofi.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/arcofi.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/arcofi.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: arcofi.h,v 1.6.6.2 2001/09/23 22:24:46 kai Exp $
+/* $Id: arcofi.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * Ansteuerung ARCOFI 2165
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/asuscom.c linux/drivers/isdn/hisax/asuscom.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/asuscom.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/asuscom.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: asuscom.c,v 1.11.6.3 2001/09/23 22:24:46 kai Exp $
+/* $Id: asuscom.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for ASUSCOM NETWORK INC. ISDNLink cards
  *
@@ -22,7 +22,7 @@
 
 extern const char *CardType[];
 
-const char *Asuscom_revision = "$Revision: 1.11.6.3 $";
+const char *Asuscom_revision = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/avm_a1.c linux/drivers/isdn/hisax/avm_a1.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/avm_a1.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/avm_a1.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: avm_a1.c,v 2.13.6.2 2001/09/23 22:24:46 kai Exp $
+/* $Id: avm_a1.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for AVM A1 (Fritz) isdn cards
  *
@@ -18,7 +18,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-static const char *avm_revision = "$Revision: 2.13.6.2 $";
+static const char *avm_revision = "$Revision: 1.1.4.1 $";
 
 #define	 AVM_A1_STAT_ISAC	0x01
 #define	 AVM_A1_STAT_HSCX	0x02
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/avm_a1p.c linux/drivers/isdn/hisax/avm_a1p.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/avm_a1p.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/avm_a1p.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: avm_a1p.c,v 2.7.6.2 2001/09/23 22:24:46 kai Exp $
+/* $Id: avm_a1p.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for the following AVM cards:
  * A1 PCMCIA
@@ -57,7 +57,7 @@
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
 
-static const char *avm_revision = "$Revision: 2.7.6.2 $";
+static const char *avm_revision = "$Revision: 1.1.4.1 $";
 
 static inline u_char
 ReadISAC(struct IsdnCardState *cs, u_char offset)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/avm_pci.c linux/drivers/isdn/hisax/avm_pci.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/avm_pci.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/avm_pci.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: avm_pci.c,v 1.22.6.6 2001/09/23 22:24:46 kai Exp $
+/* $Id: avm_pci.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
  *
@@ -22,7 +22,7 @@
 #include <linux/interrupt.h>
 
 extern const char *CardType[];
-static const char *avm_pci_rev = "$Revision: 1.22.6.6 $";
+static const char *avm_pci_rev = "$Revision: 1.1.4.1 $";
 
 #define  AVM_FRITZ_PCI		1
 #define  AVM_FRITZ_PNP		2
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/bkm_a4t.c linux/drivers/isdn/hisax/bkm_a4t.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/bkm_a4t.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/bkm_a4t.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: bkm_a4t.c,v 1.13.6.6 2001/09/23 22:24:46 kai Exp $
+/* $Id: bkm_a4t.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for T-Berkom A4T
  *
@@ -24,7 +24,7 @@
 
 extern const char *CardType[];
 
-const char *bkm_a4t_revision = "$Revision: 1.13.6.6 $";
+const char *bkm_a4t_revision = "$Revision: 1.1.4.1 $";
 
 
 static inline u_char
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/bkm_a8.c linux/drivers/isdn/hisax/bkm_a8.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/bkm_a8.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/bkm_a8.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: bkm_a8.c,v 1.14.6.7 2001/09/23 22:24:46 kai Exp $
+/* $Id: bkm_a8.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for Scitel Quadro (4*S0, passive)
  *
@@ -28,7 +28,7 @@
 
 extern const char *CardType[];
 
-const char sct_quadro_revision[] = "$Revision: 1.14.6.7 $";
+const char sct_quadro_revision[] = "$Revision: 1.1.4.1 $";
 
 static const char *sct_quadro_subtypes[] =
 {
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/bkm_ax.h linux/drivers/isdn/hisax/bkm_ax.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/bkm_ax.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/bkm_ax.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: bkm_ax.h,v 1.5.6.3 2001/09/23 22:24:46 kai Exp $
+/* $Id: bkm_ax.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level decls for T-Berkom cards A4T and Scitel Quadro (4*S0, passive)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/callc.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/callc.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: callc.c,v 2.51.6.6 2001/09/23 22:24:46 kai Exp $
+/* $Id: callc.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
@@ -26,7 +26,7 @@
 #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module))
 #endif	/* MODULE */
 
-const char *lli_revision = "$Revision: 2.51.6.6 $";
+const char *lli_revision = "$Revision: 1.1.4.1 $";
 
 extern struct IsdnCard cards[];
 extern int nrcards;
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/cert.c linux/drivers/isdn/hisax/cert.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/cert.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/cert.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: cert.c,v 2.3.6.3 2001/09/23 22:24:47 kai Exp $
+/* $Id: cert.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/config.c	Sun Dec  9 12:39:27 2001
+++ linux/drivers/isdn/hisax/config.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: config.c,v 2.57.6.20 2001/09/23 22:24:47 kai Exp $
+/* $Id: config.c,v 1.1.4.5 2001/12/09 19:19:26 kai Exp $
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
@@ -336,17 +336,8 @@
 	NULL, \
 }
 
-#define EMPTY_CARD	{0, DEFAULT_PROTO, {0, 0, 0, 0}, NULL}
-
 struct IsdnCard cards[HISAX_MAX_CARDS] = {
 	FIRST_CARD,
-	EMPTY_CARD,
-	EMPTY_CARD,
-	EMPTY_CARD,
-	EMPTY_CARD,
-	EMPTY_CARD,
-	EMPTY_CARD,
-	EMPTY_CARD,
 };
 
 #define HISAX_IDSIZE (HISAX_MAX_CARDS*8)
@@ -374,10 +365,7 @@
 static int mem[HISAX_MAX_CARDS] __devinitdata = { 0, };
 static char *id __devinitdata = HiSaxID;
 
-/* string magic */
-#define h1(s) h2(s)
-#define h2(s) #s
-#define PARM_PARA "1-"h1(HISAX_MAX_CARDS)"i"
+#define PARM_PARA "1-" __MODULE_STRING(HISAX_MAX_CARDS) "i"
 
 MODULE_DESCRIPTION("ISDN4Linux: Driver for passive ISDN cards");
 MODULE_AUTHOR("Karsten Keil");
@@ -454,6 +442,7 @@
 	i = 0;
 	j = 1;
 	while (argc && (i < HISAX_MAX_CARDS)) {
+		cards[i].protocol = DEFAULT_PROTO;
 		if (argc) {
 			cards[i].typ = ints[j];
 			j++;
@@ -481,7 +470,7 @@
 		}
 		i++;
 	}
-	if (str && *str) {
+  	if (str && *str) {
 		if (strlen(str) < HISAX_IDSIZE)
 			strcpy(HiSaxID, str);
 		else
@@ -1404,6 +1393,8 @@
 		if (protocol[i]) {
 			cards[j].protocol = protocol[i];
 			nzproto++;
+		} else {
+			cards[j].protocol = DEFAULT_PROTO;
 		}
 		switch (type[i]) {
 		case ISDN_CTYPE_16_0:
@@ -1481,15 +1472,22 @@
 			} else {
 				/* QUADRO is a 4 BRI card */
 				cards[j++].para[0] = 1;
-				cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
-				cards[j].protocol = protocol[i];
-				cards[j++].para[0] = 2;
-				cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
-				cards[j].protocol = protocol[i];
-				cards[j++].para[0] = 3;
-				cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
-				cards[j].protocol = protocol[i];
-				cards[j].para[0] = 4;
+				/* we need to check if further cards can be added */
+				if (j < HISAX_MAX_CARDS) {
+					cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
+					cards[j].protocol = protocol[i];
+					cards[j++].para[0] = 2;
+				}
+				if (j < HISAX_MAX_CARDS) {
+					cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
+					cards[j].protocol = protocol[i];
+					cards[j++].para[0] = 3;
+				}
+				if (j < HISAX_MAX_CARDS) {
+					cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
+					cards[j].protocol = protocol[i];
+					cards[j].para[0] = 4;
+				}
 			}
 			break;
 		}
@@ -1562,6 +1560,8 @@
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
+		} else {
+			cards[i].protocol = DEFAULT_PROTO;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
@@ -1602,6 +1602,8 @@
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
+		} else {
+			cards[i].protocol = DEFAULT_PROTO;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
@@ -1642,6 +1644,8 @@
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
+		} else {
+			cards[i].protocol = DEFAULT_PROTO;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
@@ -1682,6 +1686,8 @@
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
+		} else {
+			cards[i].protocol = DEFAULT_PROTO;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/diva.c linux/drivers/isdn/hisax/diva.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/diva.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/diva.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: diva.c,v 1.25.6.5 2001/09/23 22:24:47 kai Exp $
+/* $Id: diva.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for Eicon.Diehl Diva Family ISDN cards
  *
@@ -27,7 +27,7 @@
 
 extern const char *CardType[];
 
-const char *Diva_revision = "$Revision: 1.25.6.5 $";
+const char *Diva_revision = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/elsa.c linux/drivers/isdn/hisax/elsa.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/elsa.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/elsa.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: elsa.c,v 2.26.6.6 2001/09/23 22:24:47 kai Exp $
+/* $Id: elsa.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for Elsa isdn cards
  *
@@ -33,7 +33,7 @@
 
 extern const char *CardType[];
 
-const char *Elsa_revision = "$Revision: 2.26.6.6 $";
+const char *Elsa_revision = "$Revision: 1.1.4.1 $";
 const char *Elsa_Types[] =
 {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
  "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", 
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/elsa_cs.c linux/drivers/isdn/hisax/elsa_cs.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/elsa_cs.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/elsa_cs.c	Sun Dec  9 12:40:04 2001
@@ -72,7 +72,7 @@
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
 static char *version =
-"elsa_cs.c $Revision: 1.1.2.2 $ $Date: 2001/09/23 22:24:47 $ (K.Lichtenwalder)";
+"elsa_cs.c $Revision: 1.1.4.1 $ $Date: 2001/11/20 14:19:35 $ (K.Lichtenwalder)";
 #else
 #define DEBUG(n, args...)
 #endif
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/elsa_ser.c linux/drivers/isdn/hisax/elsa_ser.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/elsa_ser.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/elsa_ser.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: elsa_ser.c,v 2.10.6.4 2001/09/23 22:24:47 kai Exp $
+/* $Id: elsa_ser.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * stuff for the serial modem on ELSA cards
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/fsm.c linux/drivers/isdn/hisax/fsm.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/fsm.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/fsm.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: fsm.c,v 1.14.6.4 2001/09/23 22:24:47 kai Exp $
+/* $Id: fsm.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * Finite state machine
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/fsm.h linux/drivers/isdn/hisax/fsm.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/fsm.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/fsm.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: fsm.h,v 1.3.2.2 2001/09/23 22:24:47 kai Exp $
+/* $Id: fsm.h,v 1.1.2.1 2001/11/20 14:19:35 kai Exp $
  *
  * Finite state machine
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/gazel.c linux/drivers/isdn/hisax/gazel.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/gazel.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/gazel.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: gazel.c,v 2.11.6.7 2001/09/23 22:24:47 kai Exp $
+/* $Id: gazel.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for Gazel isdn cards
  *
@@ -22,7 +22,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *gazel_revision = "$Revision: 2.11.6.7 $";
+const char *gazel_revision = "$Revision: 1.1.4.1 $";
 
 #define R647      1
 #define R685      2
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hfc_2bds0.c linux/drivers/isdn/hisax/hfc_2bds0.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/hfc_2bds0.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hfc_2bds0.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bds0.c,v 1.15.6.3 2001/09/23 22:24:47 kai Exp $
+/* $Id: hfc_2bds0.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * specific routines for CCD's HFC 2BDS0
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hfc_2bds0.h linux/drivers/isdn/hisax/hfc_2bds0.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/hfc_2bds0.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hfc_2bds0.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bds0.h,v 1.4.6.2 2001/09/23 22:24:47 kai Exp $
+/* $Id: hfc_2bds0.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * specific defines for CCD's HFC 2BDS0
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hfc_2bs0.c linux/drivers/isdn/hisax/hfc_2bs0.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/hfc_2bs0.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hfc_2bs0.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bs0.c,v 1.17.6.3 2001/09/23 22:24:47 kai Exp $
+/* $Id: hfc_2bs0.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * specific routines for CCD's HFC 2BS0
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hfc_2bs0.h linux/drivers/isdn/hisax/hfc_2bs0.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/hfc_2bs0.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hfc_2bs0.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bs0.h,v 1.3.6.2 2001/09/23 22:24:47 kai Exp $
+/* $Id: hfc_2bs0.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * specific defines for CCD's HFC 2BS0
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/hfc_pci.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hfc_pci.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_pci.c,v 1.34.6.8 2001/09/23 22:24:47 kai Exp $
+/* $Id: hfc_pci.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level driver for CCD´s hfc-pci based cards
  *
@@ -26,7 +26,7 @@
 
 extern const char *CardType[];
 
-static const char *hfcpci_revision = "$Revision: 1.34.6.8 $";
+static const char *hfcpci_revision = "$Revision: 1.1.4.1 $";
 
 /* table entry in the PCI devices list */
 typedef struct {
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hfc_pci.h linux/drivers/isdn/hisax/hfc_pci.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/hfc_pci.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hfc_pci.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_pci.h,v 1.8.6.2 2001/09/23 22:24:48 kai Exp $
+/* $Id: hfc_pci.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * specific defines for CCD's HFC 2BDS0 PCI chips
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hfc_sx.c linux/drivers/isdn/hisax/hfc_sx.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/hfc_sx.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hfc_sx.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_sx.c,v 1.9.6.3 2001/09/23 22:24:48 kai Exp $
+/* $Id: hfc_sx.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * level driver for CCD´s hfc-s+/sp based cards
  *
@@ -20,7 +20,7 @@
 
 extern const char *CardType[];
 
-static const char *hfcsx_revision = "$Revision: 1.9.6.3 $";
+static const char *hfcsx_revision = "$Revision: 1.1.4.1 $";
 
 /***************************************/
 /* IRQ-table for CCDs demo board       */
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hfc_sx.h linux/drivers/isdn/hisax/hfc_sx.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/hfc_sx.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hfc_sx.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_sx.h,v 1.2.6.1 2001/09/23 22:24:48 kai Exp $
+/* $Id: hfc_sx.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * specific defines for CCD's HFC 2BDS0 S+,SP chips
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hfcscard.c linux/drivers/isdn/hisax/hfcscard.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/hfcscard.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hfcscard.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hfcscard.c,v 1.8.6.2 2001/09/23 22:24:48 kai Exp $
+/* $Id: hfcscard.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  *
  * low level stuff for hfcs based cards (Teles3c, ACER P10)
  *
@@ -18,7 +18,7 @@
 
 extern const char *CardType[];
 
-static const char *hfcs_revision = "$Revision: 1.8.6.2 $";
+static const char *hfcs_revision = "$Revision: 1.1.4.1 $";
 
 static void
 hfcs_interrupt(int intno, void *dev_id, struct pt_regs *regs)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/hisax.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hisax.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hisax.h,v 2.52.6.9 2001/09/23 22:24:48 kai Exp $
+/* $Id: hisax.h,v 1.1.4.2 2001/12/09 19:15:28 kai Exp $
  *
  * Basic declarations, defines and prototypes
  *
@@ -949,8 +949,6 @@
 #define  MON1_RX	2
 #define  MON0_TX	4
 #define  MON1_TX	8
-
-#define	 HISAX_MAX_CARDS	8
 
 #define  ISDN_CTYPE_16_0	1
 #define  ISDN_CTYPE_8_0		2
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hscx.c linux/drivers/isdn/hisax/hscx.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/hscx.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hscx.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hscx.c,v 1.21.6.3 2001/09/23 22:24:48 kai Exp $
+/* $Id: hscx.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * HSCX specific routines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hscx.h linux/drivers/isdn/hisax/hscx.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/hscx.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hscx.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hscx.h,v 1.6.6.2 2001/09/23 22:24:48 kai Exp $
+/* $Id: hscx.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * HSCX specific defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/hscx_irq.c linux/drivers/isdn/hisax/hscx_irq.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/hscx_irq.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/hscx_irq.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hscx_irq.c,v 1.16.6.2 2001/09/23 22:24:48 kai Exp $
+/* $Id: hscx_irq.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level b-channel stuff for Siemens HSCX
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/icc.c linux/drivers/isdn/hisax/icc.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/icc.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/icc.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: icc.c,v 1.5.6.4 2001/09/23 22:24:48 kai Exp $
+/* $Id: icc.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * ICC specific routines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/icc.h linux/drivers/isdn/hisax/icc.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/icc.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/icc.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: icc.h,v 1.2.6.3 2001/09/23 22:24:48 kai Exp $
+/* $Id: icc.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * ICC specific routines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/ipac.h linux/drivers/isdn/hisax/ipac.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/ipac.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/ipac.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: ipac.h,v 1.5.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: ipac.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * IPAC specific defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isac.c linux/drivers/isdn/hisax/isac.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/isac.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isac.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isac.c,v 1.28.6.3 2001/09/23 22:24:49 kai Exp $
+/* $Id: isac.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * ISAC specific routines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isac.h linux/drivers/isdn/hisax/isac.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/isac.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isac.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isac.h,v 1.7.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: isac.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * ISAC specific defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isar.c linux/drivers/isdn/hisax/isar.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/isar.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/isar.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isar.c,v 1.17.6.5 2001/09/23 11:51:33 keil Exp $
+/* $Id: isar.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * isar.c   ISAR (Siemens PSB 7110) specific routines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isar.h linux/drivers/isdn/hisax/isar.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/isar.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isar.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isar.h,v 1.9.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: isar.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * ISAR (Siemens PSB 7110) specific defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isdnl1.c linux/drivers/isdn/hisax/isdnl1.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/isdnl1.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isdnl1.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl1.c,v 2.41.6.5 2001/09/23 22:24:49 kai Exp $
+/* $Id: isdnl1.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * common low level stuff for Siemens Chipsetbased isdn cards
  *
@@ -18,7 +18,7 @@
  *
  */
 
-const char *l1_revision = "$Revision: 2.41.6.5 $";
+const char *l1_revision = "$Revision: 1.1.4.1 $";
 
 #define __NO_VERSION__
 #include <linux/init.h>
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isdnl1.h linux/drivers/isdn/hisax/isdnl1.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/isdnl1.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isdnl1.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl1.h,v 2.9.6.3 2001/09/23 22:24:49 kai Exp $
+/* $Id: isdnl1.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Layer 1 defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isdnl2.c linux/drivers/isdn/hisax/isdnl2.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/isdnl2.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isdnl2.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl2.c,v 2.25.6.4 2001/09/23 22:24:49 kai Exp $
+/* $Id: isdnl2.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
@@ -20,7 +20,7 @@
 #include "hisax.h"
 #include "isdnl2.h"
 
-const char *l2_revision = "$Revision: 2.25.6.4 $";
+const char *l2_revision = "$Revision: 1.1.4.1 $";
 
 static void l2m_debug(struct FsmInst *fi, char *fmt, ...);
 
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isdnl2.h linux/drivers/isdn/hisax/isdnl2.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/isdnl2.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isdnl2.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl2.h,v 1.3.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: isdnl2.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Layer 2 defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isdnl3.c linux/drivers/isdn/hisax/isdnl3.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/isdnl3.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isdnl3.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl3.c,v 2.17.6.5 2001/09/23 22:24:49 kai Exp $
+/* $Id: isdnl3.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
@@ -21,7 +21,7 @@
 #include "isdnl3.h"
 #include <linux/config.h>
 
-const char *l3_revision = "$Revision: 2.17.6.5 $";
+const char *l3_revision = "$Revision: 1.1.4.1 $";
 
 static struct Fsm l3fsm;
 
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isdnl3.h linux/drivers/isdn/hisax/isdnl3.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/isdnl3.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isdnl3.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl3.h,v 2.6.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: isdnl3.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/isurf.c linux/drivers/isdn/hisax/isurf.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/isurf.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/isurf.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isurf.c,v 1.10.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: isurf.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for Siemens I-Surf/I-Talk cards
  *
@@ -19,7 +19,7 @@
 
 extern const char *CardType[];
 
-static const char *ISurf_revision = "$Revision: 1.10.6.2 $";
+static const char *ISurf_revision = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/ix1_micro.c linux/drivers/isdn/hisax/ix1_micro.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/ix1_micro.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/ix1_micro.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: ix1_micro.c,v 2.10.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: ix1_micro.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for ITK ix1-micro Rev.2 isdn cards
  * derived from the original file teles3.c from Karsten Keil
@@ -25,7 +25,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *ix1_revision = "$Revision: 2.10.6.2 $";
+const char *ix1_revision = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/jade.c linux/drivers/isdn/hisax/jade.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/jade.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/jade.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: jade.c,v 1.6.6.3 2001/09/23 22:24:49 kai Exp $
+/* $Id: jade.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * JADE stuff (derived from original hscx.c)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/jade.h linux/drivers/isdn/hisax/jade.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/jade.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/jade.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: jade.h,v 1.3.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: jade.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * JADE specific defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/jade_irq.c linux/drivers/isdn/hisax/jade_irq.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/jade_irq.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/jade_irq.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: jade_irq.c,v 1.5.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: jade_irq.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Low level JADE IRQ stuff (derived from original hscx_irq.c)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/l3_1tr6.c linux/drivers/isdn/hisax/l3_1tr6.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/l3_1tr6.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/l3_1tr6.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: l3_1tr6.c,v 2.13.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: l3_1tr6.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * German 1TR6 D-channel protocol
  *
@@ -20,7 +20,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *l3_1tr6_revision = "$Revision: 2.13.6.2 $";
+const char *l3_1tr6_revision = "$Revision: 1.1.4.1 $";
 
 #define MsgHead(ptr, cref, mty, dis) \
 	*ptr++ = dis; \
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/l3_1tr6.h linux/drivers/isdn/hisax/l3_1tr6.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/l3_1tr6.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/l3_1tr6.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: l3_1tr6.h,v 2.2.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: l3_1tr6.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * German 1TR6 D-channel protocol defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/l3dss1.c linux/drivers/isdn/hisax/l3dss1.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/l3dss1.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/l3dss1.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: l3dss1.c,v 2.30.6.2 2001/09/23 22:24:49 kai Exp $
+/* $Id: l3dss1.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * EURO/DSS1 D-channel protocol
  *
@@ -27,7 +27,7 @@
 #include <linux/config.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 2.30.6.2 $";
+const char *dss1_revision = "$Revision: 1.1.4.1 $";
 
 #define EXT_BEARER_CAPS 1
 
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/l3dss1.h linux/drivers/isdn/hisax/l3dss1.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/l3dss1.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/l3dss1.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: l3dss1.h,v 1.10.6.2 2001/09/23 22:24:50 kai Exp $
+/* $Id: l3dss1.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * DSS1 (Euro) D-channel protocol defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/l3ni1.c linux/drivers/isdn/hisax/l3ni1.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/l3ni1.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/l3ni1.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: l3ni1.c,v 2.5.6.3 2001/09/23 22:24:50 kai Exp $
+/* $Id: l3ni1.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * NI1 D-channel protocol
  *
@@ -25,7 +25,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *ni1_revision = "$Revision: 2.5.6.3 $";
+const char *ni1_revision = "$Revision: 1.1.4.1 $";
 
 #define EXT_BEARER_CAPS 1
 
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/l3ni1.h linux/drivers/isdn/hisax/l3ni1.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/l3ni1.h	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/l3ni1.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: l3ni1.h,v 2.3.6.2 2001/09/23 22:24:50 kai Exp $
+/* $Id: l3ni1.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * NI1 D-channel protocol
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/lmgr.c linux/drivers/isdn/hisax/lmgr.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/lmgr.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/lmgr.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: lmgr.c,v 1.7.6.2 2001/09/23 22:24:50 kai Exp $
+/* $Id: lmgr.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Layermanagement module
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/mic.c linux/drivers/isdn/hisax/mic.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/mic.c	Sun Sep 30 12:26:05 2001
+++ linux/drivers/isdn/hisax/mic.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: mic.c,v 1.10.6.2 2001/09/23 22:24:50 kai Exp $
+/* $Id: mic.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for mic cards
  *
@@ -19,7 +19,7 @@
 
 extern const char *CardType[];
 
-const char *mic_revision = "$Revision: 1.10.6.2 $";
+const char *mic_revision = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/netjet.c linux/drivers/isdn/hisax/netjet.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/netjet.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/netjet.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: netjet.c,v 1.24.6.6 2001/09/23 22:24:50 kai Exp $
+/* $Id: netjet.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for Traverse Technologie NETJet ISDN cards
  *
@@ -24,7 +24,7 @@
 #include <asm/io.h>
 #include "netjet.h"
 
-const char *NETjet_revision = "$Revision: 1.24.6.6 $";
+const char *NETjet_revision = "$Revision: 1.1.4.1 $";
 
 /* Interface functions */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/netjet.h linux/drivers/isdn/hisax/netjet.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/netjet.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/netjet.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: netjet.h,v 2.5.6.3 2001/09/23 22:24:50 kai Exp $
+/* $Id: netjet.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * NETjet common header file
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/niccy.c linux/drivers/isdn/hisax/niccy.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/niccy.c	Wed Oct 24 15:34:51 2001
+++ linux/drivers/isdn/hisax/niccy.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: niccy.c,v 1.15.6.6 2001/10/20 22:08:24 kai Exp $
+/* $Id: niccy.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and
  * compatible (SAGEM cybermodem)
@@ -24,7 +24,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *niccy_revision = "$Revision: 1.15.6.6 $";
+const char *niccy_revision = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/nj_s.c linux/drivers/isdn/hisax/nj_s.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/nj_s.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/nj_s.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: nj_s.c,v 2.7.6.6 2001/09/23 22:24:50 kai Exp $
+/* $Id: nj_s.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
@@ -16,7 +16,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_S_revision = "$Revision: 2.7.6.6 $";
+const char *NETjet_S_revision = "$Revision: 1.1.4.1 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/nj_u.c linux/drivers/isdn/hisax/nj_u.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/nj_u.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/nj_u.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: nj_u.c,v 2.8.6.6 2001/09/23 22:24:50 kai Exp $ 
+/* $Id: nj_u.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $ 
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
@@ -16,7 +16,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_U_revision = "$Revision: 2.8.6.6 $";
+const char *NETjet_U_revision = "$Revision: 1.1.4.1 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/q931.c linux/drivers/isdn/hisax/q931.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/q931.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/q931.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: q931.c,v 1.10.6.3 2001/09/23 22:24:50 kai Exp $
+/* $Id: q931.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * code to decode ITU Q.931 call control messages
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/rawhdlc.c linux/drivers/isdn/hisax/rawhdlc.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/rawhdlc.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/rawhdlc.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: rawhdlc.c,v 1.5.6.2 2001/09/23 22:24:51 kai Exp $
+/* $Id: rawhdlc.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * support routines for cards that don't support HDLC
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/rawhdlc.h linux/drivers/isdn/hisax/rawhdlc.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/rawhdlc.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/rawhdlc.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: rawhdlc.h,v 1.3.6.2 2001/09/23 22:24:51 kai Exp $
+/* $Id: rawhdlc.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Author     Brent Baccala
  * Copyright  by Brent Baccala <baccala@FreeSoft.org>
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/s0box.c linux/drivers/isdn/hisax/s0box.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/s0box.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/s0box.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: s0box.c,v 2.4.6.2 2001/09/23 22:24:51 kai Exp $
+/* $Id: s0box.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for Creatix S0BOX
  *
@@ -18,7 +18,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *s0box_revision = "$Revision: 2.4.6.2 $";
+const char *s0box_revision = "$Revision: 1.1.4.1 $";
 
 static inline void
 writereg(unsigned int padr, signed int addr, u_char off, u_char val) {
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/saphir.c linux/drivers/isdn/hisax/saphir.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/saphir.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/saphir.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: saphir.c,v 1.8.6.2 2001/09/23 22:24:51 kai Exp $
+/* $Id: saphir.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for HST Saphir 1
  *
@@ -20,7 +20,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-static char *saphir_rev = "$Revision: 1.8.6.2 $";
+static char *saphir_rev = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/sedlbauer.c linux/drivers/isdn/hisax/sedlbauer.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/sedlbauer.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/sedlbauer.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: sedlbauer.c,v 1.25.6.6 2001/09/23 22:24:51 kai Exp $
+/* $Id: sedlbauer.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for Sedlbauer cards
  * includes support for the Sedlbauer speed star (speed star II),
@@ -51,7 +51,7 @@
 
 extern const char *CardType[];
 
-const char *Sedlbauer_revision = "$Revision: 1.25.6.6 $";
+const char *Sedlbauer_revision = "$Revision: 1.1.4.1 $";
 
 const char *Sedlbauer_Types[] =
 	{"None", "speed card/win", "speed star", "speed fax+",
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/sportster.c linux/drivers/isdn/hisax/sportster.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/sportster.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/sportster.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: sportster.c,v 1.14.6.2 2001/09/23 22:24:51 kai Exp $
+/* $Id: sportster.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for USR Sportster internal TA
  *
@@ -20,7 +20,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *sportster_revision = "$Revision: 1.14.6.2 $";
+const char *sportster_revision = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/tei.c linux/drivers/isdn/hisax/tei.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/tei.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/tei.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: tei.c,v 2.17.6.3 2001/09/23 22:24:51 kai Exp $
+/* $Id: tei.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
@@ -21,7 +21,7 @@
 #include <linux/init.h>
 #include <linux/random.h>
 
-const char *tei_revision = "$Revision: 2.17.6.3 $";
+const char *tei_revision = "$Revision: 1.1.4.1 $";
 
 #define ID_REQUEST	1
 #define ID_ASSIGNED	2
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/teleint.c linux/drivers/isdn/hisax/teleint.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/teleint.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/teleint.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: teleint.c,v 1.14.6.2 2001/09/23 22:24:52 kai Exp $
+/* $Id: teleint.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for TeleInt isdn cards
  *
@@ -19,7 +19,7 @@
 
 extern const char *CardType[];
 
-const char *TeleInt_revision = "$Revision: 1.14.6.2 $";
+const char *TeleInt_revision = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/teles0.c linux/drivers/isdn/hisax/teles0.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/teles0.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/teles0.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: teles0.c,v 2.13.6.2 2001/09/23 22:24:52 kai Exp $
+/* $Id: teles0.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for Teles Memory IO isdn cards
  *
@@ -24,7 +24,7 @@
 
 extern const char *CardType[];
 
-const char *teles0_revision = "$Revision: 2.13.6.2 $";
+const char *teles0_revision = "$Revision: 1.1.4.1 $";
 
 #define TELES_IOMEM_SIZE	0x400
 #define byteout(addr,val) outb(val,addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/teles3.c linux/drivers/isdn/hisax/teles3.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/teles3.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/teles3.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: teles3.c,v 2.17.6.2 2001/09/23 22:24:52 kai Exp $
+/* $Id: teles3.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for Teles 16.3 & PNP isdn cards
  *
@@ -21,7 +21,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *teles3_revision = "$Revision: 2.17.6.2 $";
+const char *teles3_revision = "$Revision: 1.1.4.1 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/telespci.c linux/drivers/isdn/hisax/telespci.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/telespci.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/telespci.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: telespci.c,v 2.16.6.5 2001/09/23 22:24:52 kai Exp $
+/* $Id: telespci.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * low level stuff for Teles PCI isdn cards
  *
@@ -22,7 +22,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *telespci_revision = "$Revision: 2.16.6.5 $";
+const char *telespci_revision = "$Revision: 1.1.4.1 $";
 
 #define ZORAN_PO_RQ_PEN	0x02000000
 #define ZORAN_PO_WR	0x00800000
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/w6692.c linux/drivers/isdn/hisax/w6692.c
--- linux-2.4.17-pre6/drivers/isdn/hisax/w6692.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/w6692.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: w6692.c,v 1.12.6.6 2001/09/23 22:24:52 kai Exp $
+/* $Id: w6692.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Winbond W6692 specific routines
  *
@@ -36,7 +36,7 @@
 
 extern const char *CardType[];
 
-const char *w6692_revision = "$Revision: 1.12.6.6 $";
+const char *w6692_revision = "$Revision: 1.1.4.1 $";
 
 #define DBUSY_TIMER_VALUE 80
 
diff -urN linux-2.4.17-pre6/drivers/isdn/hisax/w6692.h linux/drivers/isdn/hisax/w6692.h
--- linux-2.4.17-pre6/drivers/isdn/hisax/w6692.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hisax/w6692.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: w6692.h,v 1.2.6.2 2001/09/23 22:24:52 kai Exp $
+/* $Id: w6692.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
  *
  * Winbond W6692 specific defines
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/boardergo.c linux/drivers/isdn/hysdn/boardergo.c
--- linux-2.4.17-pre6/drivers/isdn/hysdn/boardergo.c	Fri Nov  9 13:41:42 2001
+++ linux/drivers/isdn/hysdn/boardergo.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: boardergo.c,v 1.5.6.7 2001/11/06 21:58:19 kai Exp $
+/* $Id: boardergo.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards, specific routines for ergo type boards.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/boardergo.h linux/drivers/isdn/hysdn/boardergo.h
--- linux-2.4.17-pre6/drivers/isdn/hysdn/boardergo.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hysdn/boardergo.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: boardergo.h,v 1.2.6.1 2001/09/23 22:24:54 kai Exp $
+/* $Id: boardergo.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards, definitions for ergo type boards (buffers..).
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/hycapi.c linux/drivers/isdn/hysdn/hycapi.c
--- linux-2.4.17-pre6/drivers/isdn/hysdn/hycapi.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hysdn/hycapi.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hycapi.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
+/* $Id: hycapi.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards, CAPI2.0-Interface.
  *
@@ -29,7 +29,7 @@
 #include "hysdn_defs.h"
 #include <linux/kernelcapi.h>
 
-static char hycapi_revision[]="$Revision: 1.8.6.4 $";
+static char hycapi_revision[]="$Revision: 1.1.4.1 $";
 
 unsigned int hycapi_enable = 0xffffffff; 
 MODULE_PARM(hycapi_enable, "i");
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_boot.c linux/drivers/isdn/hysdn/hysdn_boot.c
--- linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_boot.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hysdn/hysdn_boot.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_boot.c,v 1.4.6.4 2001/09/23 22:24:54 kai Exp $
+/* $Id: hysdn_boot.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards
  * specific routines for booting and pof handling
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_defs.h linux/drivers/isdn/hysdn/hysdn_defs.h
--- linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_defs.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hysdn/hysdn_defs.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_defs.h,v 1.5.6.3 2001/09/23 22:24:54 kai Exp $
+/* $Id: hysdn_defs.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards
  * global definitions and exported vars and functions.
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_init.c linux/drivers/isdn/hysdn/hysdn_init.c
--- linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_init.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hysdn/hysdn_init.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_init.c,v 1.6.6.6 2001/09/23 22:24:54 kai Exp $
+/* $Id: hysdn_init.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards, init functions.
  *
@@ -33,7 +33,7 @@
 MODULE_AUTHOR("Werner Cornelius");
 MODULE_LICENSE("GPL");
 
-static char *hysdn_init_revision = "$Revision: 1.6.6.6 $";
+static char *hysdn_init_revision = "$Revision: 1.1.4.1 $";
 int cardmax;			/* number of found cards */
 hysdn_card *card_root = NULL;	/* pointer to first card */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_net.c linux/drivers/isdn/hysdn/hysdn_net.c
--- linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_net.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hysdn/hysdn_net.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_net.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
+/* $Id: hysdn_net.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards, net (ethernet type) handling routines.
  *
@@ -29,7 +29,7 @@
 MODULE_PARM(hynet_enable, "i");
 
 /* store the actual version for log reporting */
-char *hysdn_net_revision = "$Revision: 1.8.6.4 $";
+char *hysdn_net_revision = "$Revision: 1.1.4.1 $";
 
 #define MAX_SKB_BUFFERS 20	/* number of buffers for keeping TX-data */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_pof.h linux/drivers/isdn/hysdn/hysdn_pof.h
--- linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_pof.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hysdn/hysdn_pof.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_pof.h,v 1.2.6.1 2001/09/23 22:24:54 kai Exp $
+/* $Id: hysdn_pof.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards, definitions used for handling pof-files.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_procconf.c linux/drivers/isdn/hysdn/hysdn_procconf.c
--- linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_procconf.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hysdn/hysdn_procconf.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_procconf.c,v 1.8.6.4 2001/09/23 22:24:54 kai Exp $
+/* $Id: hysdn_procconf.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards, /proc/net filesystem dir and conf functions.
  *
@@ -21,7 +21,7 @@
 
 #include "hysdn_defs.h"
 
-static char *hysdn_procconf_revision = "$Revision: 1.8.6.4 $";
+static char *hysdn_procconf_revision = "$Revision: 1.1.4.1 $";
 
 #define INFO_OUT_LEN 80		/* length of info line including lf */
 
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_proclog.c linux/drivers/isdn/hysdn/hysdn_proclog.c
--- linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_proclog.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/hysdn/hysdn_proclog.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_proclog.c,v 1.9.6.3 2001/09/23 22:24:54 kai Exp $
+/* $Id: hysdn_proclog.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards, /proc/net filesystem log functions.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_sched.c linux/drivers/isdn/hysdn/hysdn_sched.c
--- linux-2.4.17-pre6/drivers/isdn/hysdn/hysdn_sched.c	Fri Nov  9 13:41:42 2001
+++ linux/drivers/isdn/hysdn/hysdn_sched.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_sched.c,v 1.5.6.4 2001/11/06 21:58:19 kai Exp $
+/* $Id: hysdn_sched.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Linux driver for HYSDN cards
  * scheduler routines for handling exchange card <-> pc.
diff -urN linux-2.4.17-pre6/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c
--- linux-2.4.17-pre6/drivers/isdn/icn/icn.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/icn/icn.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: icn.c,v 1.65.6.8 2001/09/23 22:24:55 kai Exp $
+/* $Id: icn.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * ISDN low-level module for the ICN active ISDN-Card.
  *
@@ -41,7 +41,7 @@
 #undef MAP_DEBUG
 
 static char
-*revision = "$Revision: 1.65.6.8 $";
+*revision = "$Revision: 1.1.4.1 $";
 
 static int icn_addcard(int, char *, char *);
 
diff -urN linux-2.4.17-pre6/drivers/isdn/icn/icn.h linux/drivers/isdn/icn/icn.h
--- linux-2.4.17-pre6/drivers/isdn/icn/icn.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/icn/icn.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: icn.h,v 1.30.6.5 2001/09/23 22:24:55 kai Exp $
+/* $Id: icn.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * ISDN lowlevel-module for the ICN active ISDN-Card.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_audio.c linux/drivers/isdn/isdn_audio.c
--- linux-2.4.17-pre6/drivers/isdn/isdn_audio.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_audio.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_audio.c,v 1.21.6.2 2001/09/23 22:24:31 kai Exp $
+/* $Id: isdn_audio.c,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
  *
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
@@ -15,7 +15,7 @@
 #include "isdn_audio.h"
 #include "isdn_common.h"
 
-char *isdn_audio_revision = "$Revision: 1.21.6.2 $";
+char *isdn_audio_revision = "$Revision: 1.1.4.1 $";
 
 /*
  * Misc. lookup-tables.
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_audio.h linux/drivers/isdn/isdn_audio.h
--- linux-2.4.17-pre6/drivers/isdn/isdn_audio.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_audio.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_audio.h,v 1.9.6.1 2001/09/23 22:24:31 kai Exp $
+/* $Id: isdn_audio.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- linux-2.4.17-pre6/drivers/isdn/isdn_common.c	Fri Nov  9 13:41:41 2001
+++ linux/drivers/isdn/isdn_common.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.114.6.16 2001/11/06 20:58:28 kai Exp $
+/* $Id: isdn_common.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, common used functions (linklevel).
  *
@@ -44,7 +44,7 @@
 
 isdn_dev *dev;
 
-static char *isdn_revision = "$Revision: 1.114.6.16 $";
+static char *isdn_revision = "$Revision: 1.1.4.1 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_common.h linux/drivers/isdn/isdn_common.h
--- linux-2.4.17-pre6/drivers/isdn/isdn_common.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_common.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.h,v 1.21.6.1 2001/09/23 22:24:31 kai Exp $
+/* $Id: isdn_common.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * header for Linux ISDN subsystem
  * common used functions and debugging-switches (linklevel).
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_concap.c linux/drivers/isdn/isdn_concap.c
--- linux-2.4.17-pre6/drivers/isdn/isdn_concap.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_concap.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_concap.c,v 1.8.6.1 2001/09/23 22:24:31 kai Exp $
+/* $Id: isdn_concap.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  * 
  * Linux ISDN subsystem, protocol encapsulation
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_concap.h linux/drivers/isdn/isdn_concap.h
--- linux-2.4.17-pre6/drivers/isdn/isdn_concap.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_concap.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_concap.h,v 1.3.6.1 2001/09/23 22:24:31 kai Exp $
+/* $Id: isdn_concap.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, protocol encapsulation
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- linux-2.4.17-pre6/drivers/isdn/isdn_net.c	Fri Nov  9 13:41:41 2001
+++ linux/drivers/isdn/isdn_net.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.140.6.11 2001/11/06 20:58:28 kai Exp $
+/* $Id: isdn_net.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
@@ -175,7 +175,7 @@
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
 static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
 
-char *isdn_net_revision = "$Revision: 1.140.6.11 $";
+char *isdn_net_revision = "$Revision: 1.1.4.1 $";
 
  /*
   * Code for raw-networking over ISDN
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_net.h linux/drivers/isdn/isdn_net.h
--- linux-2.4.17-pre6/drivers/isdn/isdn_net.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_net.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.h,v 1.19.6.4 2001/09/28 08:05:29 kai Exp $
+/* $Id: isdn_net.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * header for Linux ISDN subsystem, network related functions (linklevel).
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- linux-2.4.17-pre6/drivers/isdn/isdn_ppp.c	Fri Nov  9 13:41:41 2001
+++ linux/drivers/isdn/isdn_ppp.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.c,v 1.85.6.9 2001/11/06 20:58:28 kai Exp $
+/* $Id: isdn_ppp.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
@@ -69,7 +69,7 @@
 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
 #endif	/* CONFIG_ISDN_MPP */
   
-char *isdn_ppp_revision = "$Revision: 1.85.6.9 $";
+char *isdn_ppp_revision = "$Revision: 1.1.4.1 $";
 
 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
 
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_ppp.h linux/drivers/isdn/isdn_ppp.h
--- linux-2.4.17-pre6/drivers/isdn/isdn_ppp.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_ppp.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.h,v 1.17.6.1 2001/09/23 22:24:32 kai Exp $
+/* $Id: isdn_ppp.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * header for Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c
--- linux-2.4.17-pre6/drivers/isdn/isdn_tty.c	Fri Nov  9 13:41:41 2001
+++ linux/drivers/isdn/isdn_tty.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.c,v 1.94.6.9 2001/11/06 20:58:29 kai Exp $
+/* $Id: isdn_tty.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
  *
@@ -53,7 +53,7 @@
 static int si2bit[8] =
 {4, 1, 4, 4, 4, 4, 4, 4};
 
-char *isdn_tty_revision = "$Revision: 1.94.6.9 $";
+char *isdn_tty_revision = "$Revision: 1.1.4.1 $";
 
 
 /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_tty.h linux/drivers/isdn/isdn_tty.h
--- linux-2.4.17-pre6/drivers/isdn/isdn_tty.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_tty.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.h,v 1.22.6.2 2001/09/23 22:24:32 kai Exp $
+/* $Id: isdn_tty.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * header for Linux ISDN subsystem, tty related functions (linklevel).
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_ttyfax.c linux/drivers/isdn/isdn_ttyfax.c
--- linux-2.4.17-pre6/drivers/isdn/isdn_ttyfax.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_ttyfax.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_ttyfax.c,v 1.7.6.2 2001/09/23 22:24:32 kai Exp $
+/* $Id: isdn_ttyfax.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, tty_fax AT-command emulator (linklevel).
  *
@@ -20,7 +20,7 @@
 #include "isdn_ttyfax.h"
 
 
-static char *isdn_tty_fax_revision = "$Revision: 1.7.6.2 $";
+static char *isdn_tty_fax_revision = "$Revision: 1.1.4.1 $";
 
 #define PARSE_ERROR1 { isdn_tty_fax_modem_result(1, info); return 1; }
 
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_ttyfax.h linux/drivers/isdn/isdn_ttyfax.h
--- linux-2.4.17-pre6/drivers/isdn/isdn_ttyfax.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_ttyfax.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_ttyfax.h,v 1.2.6.1 2001/09/23 22:24:32 kai Exp $
+/* $Id: isdn_ttyfax.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * header for Linux ISDN subsystem, tty_fax related functions (linklevel).
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_v110.c linux/drivers/isdn/isdn_v110.c
--- linux-2.4.17-pre6/drivers/isdn/isdn_v110.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_v110.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_v110.c,v 1.5.6.4 2001/09/23 22:24:32 kai Exp $
+/* $Id: isdn_v110.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
@@ -19,7 +19,7 @@
 
 #undef ISDN_V110_DEBUG
 
-char *isdn_v110_revision = "$Revision: 1.5.6.4 $";
+char *isdn_v110_revision = "$Revision: 1.1.4.1 $";
 
 #define V110_38400 255
 #define V110_19200  15
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_v110.h linux/drivers/isdn/isdn_v110.h
--- linux-2.4.17-pre6/drivers/isdn/isdn_v110.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_v110.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_v110.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $
+/* $Id: isdn_v110.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_x25iface.c linux/drivers/isdn/isdn_x25iface.c
--- linux-2.4.17-pre6/drivers/isdn/isdn_x25iface.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_x25iface.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_x25iface.c,v 1.9.6.1 2001/09/23 22:24:32 kai Exp $
+/* $Id: isdn_x25iface.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * Linux ISDN subsystem, X.25 related functions
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdn_x25iface.h linux/drivers/isdn/isdn_x25iface.h
--- linux-2.4.17-pre6/drivers/isdn/isdn_x25iface.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdn_x25iface.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_x25iface.h,v 1.3.6.1 2001/09/23 22:24:32 kai Exp $
+/* $Id: isdn_x25iface.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  *
  * header for Linux ISDN subsystem, x.25 related functions
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/isdnloop/isdnloop.c linux/drivers/isdn/isdnloop/isdnloop.c
--- linux-2.4.17-pre6/drivers/isdn/isdnloop/isdnloop.c	Mon Nov 12 10:02:54 2001
+++ linux/drivers/isdn/isdnloop/isdnloop.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnloop.c,v 1.11.6.7 2001/11/11 19:54:31 kai Exp $
+/* $Id: isdnloop.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * ISDN low-level module implementing a dummy loop driver.
  *
@@ -14,7 +14,7 @@
 #include <linux/init.h>
 #include "isdnloop.h"
 
-static char *revision = "$Revision: 1.11.6.7 $";
+static char *revision = "$Revision: 1.1.4.1 $";
 static char *isdnloop_id;
 
 MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card");
diff -urN linux-2.4.17-pre6/drivers/isdn/isdnloop/isdnloop.h linux/drivers/isdn/isdnloop/isdnloop.h
--- linux-2.4.17-pre6/drivers/isdn/isdnloop/isdnloop.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/isdnloop/isdnloop.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnloop.h,v 1.5.6.3 2001/09/23 22:24:56 kai Exp $
+/* $Id: isdnloop.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Loopback lowlevel module for testing of linklevel.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/card.h linux/drivers/isdn/sc/card.h
--- linux-2.4.17-pre6/drivers/isdn/sc/card.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/card.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: card.h,v 1.1.10.1 2001/09/23 22:24:59 kai Exp $
+/* $Id: card.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Driver parameters for SpellCaster ISA ISDN adapters
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/command.c linux/drivers/isdn/sc/command.c
--- linux-2.4.17-pre6/drivers/isdn/sc/command.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/command.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: command.c,v 1.4.10.1 2001/09/23 22:24:59 kai Exp $
+/* $Id: command.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/debug.c linux/drivers/isdn/sc/debug.c
--- linux-2.4.17-pre6/drivers/isdn/sc/debug.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/debug.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: debug.c,v 1.5.6.1 2001/09/23 22:24:59 kai Exp $
+/* $Id: debug.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/debug.h linux/drivers/isdn/sc/debug.h
--- linux-2.4.17-pre6/drivers/isdn/sc/debug.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/debug.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: debug.h,v 1.2.8.1 2001/09/23 22:24:59 kai Exp $
+/* $Id: debug.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/event.c linux/drivers/isdn/sc/event.c
--- linux-2.4.17-pre6/drivers/isdn/sc/event.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/event.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: event.c,v 1.4.8.1 2001/09/23 22:24:59 kai Exp $
+/* $Id: event.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/interrupt.c linux/drivers/isdn/sc/interrupt.c
--- linux-2.4.17-pre6/drivers/isdn/sc/interrupt.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/interrupt.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: interrupt.c,v 1.4.8.3 2001/09/23 22:24:59 kai Exp $
+/* $Id: interrupt.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/message.c linux/drivers/isdn/sc/message.c
--- linux-2.4.17-pre6/drivers/isdn/sc/message.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/message.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: message.c,v 1.5.8.2 2001/09/23 22:24:59 kai Exp $
+/* $Id: message.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * functions for sending and receiving control messages
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/message.h linux/drivers/isdn/sc/message.h
--- linux-2.4.17-pre6/drivers/isdn/sc/message.h	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/message.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: message.h,v 1.1.10.1 2001/09/23 22:24:59 kai Exp $
+/* $Id: message.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/packet.c linux/drivers/isdn/sc/packet.c
--- linux-2.4.17-pre6/drivers/isdn/sc/packet.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/packet.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: packet.c,v 1.5.8.1 2001/09/23 22:24:59 kai Exp $
+/* $Id: packet.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/shmem.c linux/drivers/isdn/sc/shmem.c
--- linux-2.4.17-pre6/drivers/isdn/sc/shmem.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/shmem.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: shmem.c,v 1.2.10.1 2001/09/23 22:24:59 kai Exp $
+/* $Id: shmem.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/sc/timer.c linux/drivers/isdn/sc/timer.c
--- linux-2.4.17-pre6/drivers/isdn/sc/timer.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/sc/timer.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: timer.c,v 1.3.6.1 2001/09/23 22:24:59 kai Exp $
+/* $Id: timer.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/tpam/tpam.h linux/drivers/isdn/tpam/tpam.h
--- linux-2.4.17-pre6/drivers/isdn/tpam/tpam.h	Fri Nov  9 13:41:41 2001
+++ linux/drivers/isdn/tpam/tpam.h	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: tpam.h,v 1.1.2.3 2001/11/06 20:58:30 kai Exp $
+/* $Id: tpam.h,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/tpam/tpam_commands.c linux/drivers/isdn/tpam/tpam_commands.c
--- linux-2.4.17-pre6/drivers/isdn/tpam/tpam_commands.c	Fri Nov  9 13:41:41 2001
+++ linux/drivers/isdn/tpam/tpam_commands.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: tpam_commands.c,v 1.1.2.4 2001/11/06 20:58:30 kai Exp $
+/* $Id: tpam_commands.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - ISDN commands)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/tpam/tpam_crcpc.c linux/drivers/isdn/tpam/tpam_crcpc.c
--- linux-2.4.17-pre6/drivers/isdn/tpam/tpam_crcpc.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/tpam/tpam_crcpc.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: tpam_crcpc.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
+/* $Id: tpam_crcpc.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - CRC encoding)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/tpam/tpam_hdlc.c linux/drivers/isdn/tpam/tpam_hdlc.c
--- linux-2.4.17-pre6/drivers/isdn/tpam/tpam_hdlc.c	Fri Nov  9 13:41:41 2001
+++ linux/drivers/isdn/tpam/tpam_hdlc.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: tpam_hdlc.c,v 1.1.2.3 2001/11/06 20:58:30 kai Exp $
+/* $Id: tpam_hdlc.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - HDLC encoding)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/tpam/tpam_main.c linux/drivers/isdn/tpam/tpam_main.c
--- linux-2.4.17-pre6/drivers/isdn/tpam/tpam_main.c	Sun Dec  9 12:39:27 2001
+++ linux/drivers/isdn/tpam/tpam_main.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: tpam_main.c,v 1.1.2.3 2001/09/23 22:25:03 kai Exp $
+/* $Id: tpam_main.c,v 1.1.2.2 2001/12/09 18:45:14 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - main routines)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/tpam/tpam_memory.c linux/drivers/isdn/tpam/tpam_memory.c
--- linux-2.4.17-pre6/drivers/isdn/tpam/tpam_memory.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/tpam/tpam_memory.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: tpam_memory.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
+/* $Id: tpam_memory.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - Board Memory Access)
  *
diff -urN linux-2.4.17-pre6/drivers/isdn/tpam/tpam_nco.c linux/drivers/isdn/tpam/tpam_nco.c
--- linux-2.4.17-pre6/drivers/isdn/tpam/tpam_nco.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/tpam/tpam_nco.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: tpam_nco.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
+/* $Id: tpam_nco.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. 
  * (Kernel Driver - Low Level NCO Manipulation)
diff -urN linux-2.4.17-pre6/drivers/isdn/tpam/tpam_queues.c linux/drivers/isdn/tpam/tpam_queues.c
--- linux-2.4.17-pre6/drivers/isdn/tpam/tpam_queues.c	Sun Sep 30 12:26:06 2001
+++ linux/drivers/isdn/tpam/tpam_queues.c	Sun Dec  9 12:40:04 2001
@@ -1,4 +1,4 @@
-/* $Id: tpam_queues.c,v 1.1.2.2 2001/09/23 22:25:03 kai Exp $
+/* $Id: tpam_queues.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver)
  *
diff -urN linux-2.4.17-pre6/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- linux-2.4.17-pre6/drivers/pcmcia/yenta.c	Tue Nov 20 23:19:48 2001
+++ linux/drivers/pcmcia/yenta.c	Sun Dec  9 12:40:05 2001
@@ -688,7 +688,7 @@
 
 	/*
 	 * This does not work currently. The controller
-	 * loses too much informationduring D3 to come up
+	 * loses too much information during D3 to come up
 	 * cleanly. We should probably fix yenta_init()
 	 * to update all the critical registers, notably
 	 * the IO and MEM bridging region data.. That is
diff -urN linux-2.4.17-pre6/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- linux-2.4.17-pre6/drivers/scsi/Config.in	Fri Nov  9 15:22:54 2001
+++ linux/drivers/scsi/Config.in	Sun Dec  9 12:40:05 2001
@@ -50,6 +50,9 @@
 dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
 dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
 dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   dep_tristate 'Adaptec AACRAID support (EXPERIMENTAL)' CONFIG_SCSI_AACRAID $CONFIG_SCSI $CONFIG_PCI
+fi
 source drivers/scsi/aic7xxx/Config.in
 if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then
    dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI
diff -urN linux-2.4.17-pre6/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- linux-2.4.17-pre6/drivers/scsi/Makefile	Wed Nov 21 09:59:11 2001
+++ linux/drivers/scsi/Makefile	Sun Dec  9 12:40:05 2001
@@ -25,6 +25,7 @@
 mod-subdirs	:= pcmcia ../acorn/scsi
 
 
+subdir-$(CONFIG_SCSI_AACRAID)	+= aacraid
 subdir-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx
 subdir-$(CONFIG_PCMCIA)		+= pcmcia
 
@@ -64,6 +65,9 @@
 obj-$(CONFIG_SCSI_AHA152X)	+= aha152x.o
 obj-$(CONFIG_SCSI_AHA1542)	+= aha1542.o
 obj-$(CONFIG_SCSI_AHA1740)	+= aha1740.o
+ifeq ($(CONFIG_SCSI_AACRAID),y)
+  obj-$(CONFIG_SCSI_AACRAID)	+= aacraid/aacraid.o
+endif
 ifeq ($(CONFIG_SCSI_AIC7XXX),y)
 obj-$(CONFIG_SCSI_AIC7XXX)	+= aic7xxx/aic7xxx_drv.o
 endif
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
--- linux-2.4.17-pre6/drivers/scsi/aacraid/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/Makefile	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,16 @@
+
+EXTRA_CFLAGS	+= -I$(TOPDIR)/drivers/scsi
+
+
+O_TARGET	:= dummy.o
+
+list-multi	:= aacraid.o
+aacraid-objs	:= linit.o aachba.o commctrl.o comminit.o commsup.o \
+		   dpcsup.o rx.o sap1sup.o
+
+obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
+
+include $(TOPDIR)/Rules.make
+
+aacraid.o: $(aacraid-objs)
+	$(LD) -r -o $@ $(aacraid-objs)
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
--- linux-2.4.17-pre6/drivers/scsi/aacraid/README	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/README	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,41 @@
+AACRAID Driver for Linux (take two)
+
+Introduction
+-------------------------
+The aacraid driver adds support for Adaptec (http://www.adaptec.com)
+OEM based RAID controllers. This is a major rewrite from the original 
+Adaptec supplied driver. It has signficantly cleaned up both the code
+and the running binary size (the module is less than half the size of
+the original).
+
+This driver is experimental.
+
+Supported Cards/Chipsets
+-------------------------
+	Dell Computer Corporation PERC 2 Quad Channel
+	Dell Computer Corporation PERC 2/Si
+	Dell Computer Corporation PERC 3/Si
+	Dell Computer Corporation PERC 3/Di
+	HP NetRAID-4M
+
+Probably Supported Devices
+-------------------------
+	Any and All Adaptec branded AAC964/5400 series raid controllers.
+
+People
+-------------------------
+Alan Cox <alan@redhat.com>
+Christoph Hellwig <hch@caldera.de>	(small cleanups/fixes)
+Matt Domsch <matt_domsch@dell.com>	(revision ioctl, adapter messages)
+
+Original Driver
+-------------------------
+Adaptec Unix OEM Product Group
+
+Mailing List
+-------------------------
+None currently. Also note this is very different to Brian's original driver
+so don't expect him to support it.
+
+Original by Brian Boerner February 2001
+Rewritten by Alan Cox, November 2001
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/TODO linux/drivers/scsi/aacraid/TODO
--- linux-2.4.17-pre6/drivers/scsi/aacraid/TODO	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/TODO	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,4 @@
+o	Testing
+o	More testing
+o	Feature request: display the firmware/bios/etc revisions in the
+	/proc info
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
--- linux-2.4.17-pre6/drivers/scsi/aacraid/aachba.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/aachba.c	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,1153 @@
+/*
+ *	Adaptec AAC series RAID controller driver
+ *	(c) Copyright 2001 Red Hat Inc.	<alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/completion.h>
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+#define MAJOR_NR SCSI_DISK0_MAJOR	/* For DEVICE_NR() */
+#include <linux/blk.h>
+#include "scsi.h"
+#include "hosts.h"
+#include "sd.h"
+
+#include "aacraid.h"
+
+/*	SCSI Commands */
+#define	SS_TEST			0x00	/* Test unit ready */
+#define SS_REZERO		0x01	/* Rezero unit */
+#define	SS_REQSEN		0x03	/* Request Sense */
+#define SS_REASGN		0x07	/* Reassign blocks */
+#define	SS_READ			0x08	/* Read 6   */
+#define	SS_WRITE		0x0A	/* Write 6  */
+#define	SS_INQUIR		0x12	/* inquiry */
+#define	SS_ST_SP		0x1B	/* Start/Stop unit */
+#define	SS_LOCK			0x1E	/* prevent/allow medium removal */
+#define SS_RESERV		0x16	/* Reserve */
+#define SS_RELES		0x17	/* Release */
+#define SS_MODESEN		0x1A	/* Mode Sense 6 */
+#define	SS_RDCAP		0x25	/* Read Capacity */
+#define	SM_READ			0x28	/* Read 10  */
+#define	SM_WRITE		0x2A	/* Write 10 */
+#define SS_SEEK			0x2B	/* Seek */
+
+/* values for inqd_pdt: Peripheral device type in plain English */
+#define	INQD_PDT_DA	0x00	/* Direct-access (DISK) device */
+#define	INQD_PDT_PROC	0x03	/* Processor device */
+#define	INQD_PDT_CHNGR	0x08	/* Changer (jukebox, scsi2) */
+#define	INQD_PDT_COMM	0x09	/* Communication device (scsi2) */
+#define	INQD_PDT_NOLUN2 0x1f	/* Unknown Device (scsi2) */
+#define	INQD_PDT_NOLUN	0x7f	/* Logical Unit Not Present */
+
+#define	INQD_PDT_DMASK	0x1F	/* Peripheral Device Type Mask */
+#define	INQD_PDT_QMASK	0xE0	/* Peripheral Device Qualifer Mask */
+
+#define	TARGET_LUN_TO_CONTAINER(target, lun)	(((lun) << 4) | target)
+#define CONTAINER_TO_TARGET(cont)		((cont) & 0xf)
+#define CONTAINER_TO_LUN(cont)			((cont) >> 4)
+
+#define MAX_FIB_DATA (sizeof(struct hw_fib) - sizeof(FIB_HEADER))
+
+#define MAX_DRIVER_SG_SEGMENT_COUNT 17
+
+/*
+ *	Sense keys
+ */
+#define SENKEY_NO_SENSE      0x00	
+#define SENKEY_UNDEFINED     0x01	
+#define SENKEY_NOT_READY     0x02	
+#define SENKEY_MEDIUM_ERR    0x03	
+#define SENKEY_HW_ERR        0x04	
+#define SENKEY_ILLEGAL       0x05	
+#define SENKEY_ATTENTION     0x06	
+#define SENKEY_PROTECTED     0x07	
+#define SENKEY_BLANK         0x08	
+#define SENKEY_V_UNIQUE      0x09	
+#define SENKEY_CPY_ABORT     0x0A	
+#define SENKEY_ABORT         0x0B	
+#define SENKEY_EQUAL         0x0C	
+#define SENKEY_VOL_OVERFLOW  0x0D	
+#define SENKEY_MISCOMP       0x0E	
+#define SENKEY_RESERVED      0x0F	
+
+/*
+ *	Sense codes
+ */
+ 
+#define SENCODE_NO_SENSE                        0x00
+#define SENCODE_END_OF_DATA                     0x00
+#define SENCODE_BECOMING_READY                  0x04
+#define SENCODE_INIT_CMD_REQUIRED               0x04
+#define SENCODE_PARAM_LIST_LENGTH_ERROR         0x1A
+#define SENCODE_INVALID_COMMAND                 0x20
+#define SENCODE_LBA_OUT_OF_RANGE                0x21
+#define SENCODE_INVALID_CDB_FIELD               0x24
+#define SENCODE_LUN_NOT_SUPPORTED               0x25
+#define SENCODE_INVALID_PARAM_FIELD             0x26
+#define SENCODE_PARAM_NOT_SUPPORTED             0x26
+#define SENCODE_PARAM_VALUE_INVALID             0x26
+#define SENCODE_RESET_OCCURRED                  0x29
+#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET     0x3E
+#define SENCODE_INQUIRY_DATA_CHANGED            0x3F
+#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED     0x39
+#define SENCODE_DIAGNOSTIC_FAILURE              0x40
+#define SENCODE_INTERNAL_TARGET_FAILURE         0x44
+#define SENCODE_INVALID_MESSAGE_ERROR           0x49
+#define SENCODE_LUN_FAILED_SELF_CONFIG          0x4c
+#define SENCODE_OVERLAPPED_COMMAND              0x4E
+
+/*
+ *	Additional sense codes
+ */
+ 
+#define ASENCODE_NO_SENSE                       0x00
+#define ASENCODE_END_OF_DATA                    0x05
+#define ASENCODE_BECOMING_READY                 0x01
+#define ASENCODE_INIT_CMD_REQUIRED              0x02
+#define ASENCODE_PARAM_LIST_LENGTH_ERROR        0x00
+#define ASENCODE_INVALID_COMMAND                0x00
+#define ASENCODE_LBA_OUT_OF_RANGE               0x00
+#define ASENCODE_INVALID_CDB_FIELD              0x00
+#define ASENCODE_LUN_NOT_SUPPORTED              0x00
+#define ASENCODE_INVALID_PARAM_FIELD            0x00
+#define ASENCODE_PARAM_NOT_SUPPORTED            0x01
+#define ASENCODE_PARAM_VALUE_INVALID            0x02
+#define ASENCODE_RESET_OCCURRED                 0x00
+#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET    0x00
+#define ASENCODE_INQUIRY_DATA_CHANGED           0x03
+#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED    0x00
+#define ASENCODE_DIAGNOSTIC_FAILURE             0x80
+#define ASENCODE_INTERNAL_TARGET_FAILURE        0x00
+#define ASENCODE_INVALID_MESSAGE_ERROR          0x00
+#define ASENCODE_LUN_FAILED_SELF_CONFIG         0x00
+#define ASENCODE_OVERLAPPED_COMMAND             0x00
+
+#define BYTE0(x) (unsigned char)(x)
+#define BYTE1(x) (unsigned char)((x) >> 8)
+#define BYTE2(x) (unsigned char)((x) >> 16)
+#define BYTE3(x) (unsigned char)((x) >> 24)
+
+/*------------------------------------------------------------------------------
+ *              S T R U C T S / T Y P E D E F S
+ *----------------------------------------------------------------------------*/
+/* SCSI inquiry data */
+struct inquiry_data {
+	u8 inqd_pdt;	/* Peripheral qualifier | Peripheral Device Type  */
+	u8 inqd_dtq;	/* RMB | Device Type Qualifier  */
+	u8 inqd_ver;	/* ISO version | ECMA version | ANSI-approved version */
+	u8 inqd_rdf;	/* AENC | TrmIOP | Response data format */
+	u8 inqd_len;	/* Additional length (n-4) */
+	u8 inqd_pad1[2];/* Reserved - must be zero */
+	u8 inqd_pad2;	/* RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */
+	u8 inqd_vid[8];	/* Vendor ID */
+	u8 inqd_pid[16];/* Product ID */
+	u8 inqd_prl[4];	/* Product Revision Level */
+};
+
+struct sense_data {
+	u8 error_code;		/* 70h (current errors), 71h(deferred errors) */
+	u8 valid:1;		/* A valid bit of one indicates that the information  */
+	/* field contains valid information as defined in the
+	 * SCSI-2 Standard.
+	 */
+	u8 segment_number;	/* Only used for COPY, COMPARE, or COPY AND VERIFY Commands */
+	u8 sense_key:4;		/* Sense Key */
+	u8 reserved:1;
+	u8 ILI:1;		/* Incorrect Length Indicator */
+	u8 EOM:1;		/* End Of Medium - reserved for random access devices */
+	u8 filemark:1;		/* Filemark - reserved for random access devices */
+
+	u8 information[4];	/* for direct-access devices, contains the unsigned 
+				 * logical block address or residue associated with 
+				 * the sense key 
+				 */
+	u8 add_sense_len;	/* number of additional sense bytes to follow this field */
+	u8 cmnd_info[4];	/* not used */
+	u8 ASC;			/* Additional Sense Code */
+	u8 ASCQ;		/* Additional Sense Code Qualifier */
+	u8 FRUC;		/* Field Replaceable Unit Code - not used */
+	u8 bit_ptr:3;		/* indicates which byte of the CDB or parameter data
+				 * was in error
+				 */
+	u8 BPV:1;		/* bit pointer valid (BPV): 1- indicates that 
+				 * the bit_ptr field has valid value
+				 */
+	u8 reserved2:2;
+	u8 CD:1;		/* command data bit: 1- illegal parameter in CDB.
+				 * 0- illegal parameter in data.
+				 */
+	u8 SKSV:1;
+	u8 field_ptr[2];	/* byte of the CDB or parameter data in error */
+};
+
+/*
+ *              M O D U L E   G L O B A L S
+ */
+ 
+static struct fsa_scsi_hba *fsa_dev[MAXIMUM_NUM_ADAPTERS];	/*  SCSI Device Instance Pointers */
+static struct sense_data sense_data[MAXIMUM_NUM_CONTAINERS];
+static void get_sd_devname(int disknum, char *buffer);
+
+/**
+ *	aac_get_containers	-	list containers
+ *	@common: adapter to probe
+ *
+ *	Make a list of all containers on this controller
+ */
+int aac_get_containers(struct aac_dev *dev)
+{
+	struct fsa_scsi_hba *fsa_dev_ptr;
+	int index, status = 0;
+	struct aac_query_mount *dinfo;
+	struct aac_mount *dresp;
+	struct fib * fibptr;
+	unsigned instance;
+
+	fsa_dev_ptr = &(dev->fsa_dev);
+	instance = dev->scsi_host_ptr->unique_id;
+
+	if (!(fibptr = fib_alloc(dev)))
+		return -ENOMEM;
+
+	for (index = 0; index < MAXIMUM_NUM_CONTAINERS; index++) {
+		fib_init(fibptr);
+		dinfo = (struct aac_query_mount *) fib_data(fibptr);
+
+		dinfo->command = cpu_to_le32(VM_NameServe);
+		dinfo->count = cpu_to_le32(index);
+		dinfo->type = cpu_to_le32(FT_FILESYS);
+
+		status = fib_send(ContainerCommand,
+				    fibptr,
+				    sizeof (struct aac_query_mount),
+				    FsaNormal,
+				    1, 1,
+				    NULL, NULL);
+		if (status < 0 ) {
+			printk(KERN_WARNING "ProbeContainers: SendFIB failed.\n");
+			break;
+		}
+		dresp = (struct aac_mount *)fib_data(fibptr);
+
+		if ((le32_to_cpu(dresp->status) == ST_OK) &&
+		    (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
+			fsa_dev_ptr->valid[index] = 1;
+			fsa_dev_ptr->type[index] = le32_to_cpu(dresp->mnt[0].vol);
+			fsa_dev_ptr->size[index] = le32_to_cpu(dresp->mnt[0].capacity);
+			if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)
+				    fsa_dev_ptr->ro[index] = 1;
+		}
+		fib_complete(fibptr);
+		/*
+		 *	If there are no more containers, then stop asking.
+		 */
+		if ((index + 1) >= le32_to_cpu(dresp->count))
+			break;
+	}
+	fib_free(fibptr);
+	fsa_dev[instance] = fsa_dev_ptr;
+	return status;
+}
+
+/**
+ *	probe_container		-	query a logical volume
+ *	@dev: device to query
+ *	@cid: container identifier
+ *
+ *	Queries the controller about the given volume. The volume information
+ *	is updated in the struct fsa_scsi_hba structure rather than returned.
+ */
+ 
+static int probe_container(struct aac_dev *dev, int cid)
+{
+	struct fsa_scsi_hba *fsa_dev_ptr;
+	int status;
+	struct aac_query_mount *dinfo;
+	struct aac_mount *dresp;
+	struct fib * fibptr;
+	unsigned instance;
+
+	fsa_dev_ptr = &(dev->fsa_dev);
+	instance = dev->scsi_host_ptr->unique_id;
+
+	if (!(fibptr = fib_alloc(dev)))
+		return -ENOMEM;
+
+	fib_init(fibptr);
+
+	dinfo = (struct aac_query_mount *)fib_data(fibptr);
+
+	dinfo->command = cpu_to_le32(VM_NameServe);
+	dinfo->count = cpu_to_le32(cid);
+	dinfo->type = cpu_to_le32(FT_FILESYS);
+
+	status = fib_send(ContainerCommand,
+			    fibptr,
+			    sizeof(struct aac_query_mount),
+			    FsaNormal,
+			    1, 1,
+			    NULL, NULL);
+	if (status < 0) {
+		printk(KERN_WARNING "aacraid: probe_containers query failed.\n");
+		goto error;
+	}
+
+	dresp = (struct aac_mount *) fib_data(fibptr);
+
+	if ((le32_to_cpu(dresp->status) == ST_OK) &&
+	    (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
+		fsa_dev_ptr->valid[cid] = 1;
+		fsa_dev_ptr->type[cid] = le32_to_cpu(dresp->mnt[0].vol);
+		fsa_dev_ptr->size[cid] = le32_to_cpu(dresp->mnt[0].capacity);
+		if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)
+			fsa_dev_ptr->ro[cid] = 1;
+	}
+
+error:
+	fib_complete(fibptr);
+	fib_free(fibptr);
+
+	return status;
+}
+
+/* Local Structure to set SCSI inquiry data strings */
+struct scsi_inq {
+	char vid[8];         /* Vendor ID */
+	char pid[16];        /* Product ID */
+	char prl[4];         /* Product Revision Level */
+};
+
+/**
+ *	InqStrCopy	-	string merge
+ *	@a:	string to copy from
+ *	@b:	string to copy to
+ *
+ * 	Copy a String from one location to another
+ *	without copying \0
+ */
+
+static void inqstrcpy(char *a, char *b)
+{
+
+	while(*a != (char)0) 
+		*b++ = *a++;
+}
+
+static char *container_types[] = {
+        "None",
+        "Volume",
+        "Mirror",
+        "Stripe",
+        "RAID5",
+        "SSRW",
+        "SSRO",
+        "Morph",
+        "Legacy",
+        "RAID4",
+        "RAID10",             
+        "RAID00",             
+        "V-MIRRORS",          
+        "PSEUDO R4",          
+	"RAID50",
+        "Unknown"
+};
+
+
+
+/* Function: setinqstr
+ *
+ * Arguments: [1] pointer to void [1] int
+ *
+ * Purpose: Sets SCSI inquiry data strings for vendor, product
+ * and revision level. Allows strings to be set in platform dependant
+ * files instead of in OS dependant driver source.
+ */
+
+static void setinqstr(int devtype, void *data, int tindex)
+{
+	struct scsi_inq *str;
+	char *findit;
+	struct aac_driver_ident *mp;
+	extern struct aac_driver_ident aac_drivers[];	/* HACK FIXME */
+
+	mp = &aac_drivers[devtype];
+   
+	str = (struct scsi_inq *)(data); /* cast data to scsi inq block */
+
+	inqstrcpy (mp->vname, str->vid); 
+	inqstrcpy (mp->model, str->pid); /* last six chars reserved for vol type */
+
+	findit = str->pid;
+
+	for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
+		findit++;
+	
+	if (tindex < (sizeof(container_types)/sizeof(char *))){
+		inqstrcpy (container_types[tindex], findit);
+	}
+	inqstrcpy ("0001", str->prl);
+}
+
+void set_sense(char *sense_buf, u8 sense_key, u8 sense_code,
+		    u8 a_sense_code, u8 incorrect_length,
+		    u8 bit_pointer, unsigned field_pointer,
+		    unsigned long residue)
+{
+	sense_buf[0] = 0xF0;	/* Sense data valid, err code 70h (current error) */
+	sense_buf[1] = 0;	/* Segment number, always zero */
+
+	if (incorrect_length) {
+		sense_buf[2] = sense_key | 0x20;	/* Set the ILI bit | sense key */
+		sense_buf[3] = BYTE3(residue);
+		sense_buf[4] = BYTE2(residue);
+		sense_buf[5] = BYTE1(residue);
+		sense_buf[6] = BYTE0(residue);
+	} else
+		sense_buf[2] = sense_key;	/* Sense key */
+
+	if (sense_key == SENKEY_ILLEGAL)
+		sense_buf[7] = 10;	/* Additional sense length */
+	else
+		sense_buf[7] = 6;	/* Additional sense length */
+
+	sense_buf[12] = sense_code;	/* Additional sense code */
+	sense_buf[13] = a_sense_code;	/* Additional sense code qualifier */
+	if (sense_key == SENKEY_ILLEGAL) {
+		sense_buf[15] = 0;
+
+		if (sense_code == SENCODE_INVALID_PARAM_FIELD)
+			sense_buf[15] = 0x80;	/* Std sense key specific field */
+		/* Illegal parameter is in the parameter block */
+
+		if (sense_code == SENCODE_INVALID_CDB_FIELD)
+			sense_buf[15] = 0xc0;	/* Std sense key specific field */
+		/* Illegal parameter is in the CDB block */
+		sense_buf[15] |= bit_pointer;
+		sense_buf[16] = field_pointer >> 8;	/* MSB */
+		sense_buf[17] = field_pointer;		/* LSB */
+	}
+}
+
+static void aac_io_done(Scsi_Cmnd * scsicmd)
+{
+	unsigned long cpu_flags;
+	spin_lock_irqsave(&io_request_lock, cpu_flags);
+	scsicmd->scsi_done(scsicmd);
+	spin_unlock_irqrestore(&io_request_lock, cpu_flags);
+}
+
+static void __aac_io_done(Scsi_Cmnd * scsicmd)
+{
+	scsicmd->scsi_done(scsicmd);
+}
+
+static void read_callback(void *context, struct fib * fibptr)
+{
+	struct aac_dev *dev;
+	struct aac_read_reply *readreply;
+	Scsi_Cmnd *scsicmd;
+	unsigned long lba;
+	int cid;
+
+	scsicmd = (Scsi_Cmnd *) context;
+
+	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	cid =TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
+
+	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
+	dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %ld, t = %ld.\n", smp_processor_id(), lba, jiffies));
+
+	if (fibptr == NULL)
+		BUG();
+		
+	if(scsicmd->use_sg)
+		pci_unmap_sg(dev->pdev, 
+			(struct scatterlist *)scsicmd->buffer,
+			scsicmd->use_sg,
+			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+	else if(scsicmd->request_bufflen)
+		pci_unmap_single(dev->pdev, (u32)scsicmd->SCp.ptr, scsicmd->request_bufflen,
+				scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+	readreply = (struct aac_read_reply *)fib_data(fibptr);
+	if (le32_to_cpu(readreply->status) == ST_OK)
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
+	else {
+		printk(KERN_WARNING "read_callback: read failed, status = %d\n", readreply->status);
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
+		set_sense((char *) &sense_data[cid],
+				    SENKEY_HW_ERR,
+				    SENCODE_INTERNAL_TARGET_FAILURE,
+				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+				    0, 0);
+	}
+	fib_complete(fibptr);
+	fib_free(fibptr);
+
+	aac_io_done(scsicmd);
+}
+
+static void write_callback(void *context, struct fib * fibptr)
+{
+	struct aac_dev *dev;
+	struct aac_write_reply *writereply;
+	Scsi_Cmnd *scsicmd;
+	unsigned long lba;
+	int cid;
+
+	scsicmd = (Scsi_Cmnd *) context;
+	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
+
+	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
+	dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %ld, t = %ld.\n", smp_processor_id(), lba, jiffies));
+	if (fibptr == NULL)
+		BUG();
+
+	if(scsicmd->use_sg)
+		pci_unmap_sg(dev->pdev, 
+			(struct scatterlist *)scsicmd->buffer,
+			scsicmd->use_sg,
+			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+	else if(scsicmd->request_bufflen)
+		pci_unmap_single(dev->pdev, (u32)scsicmd->SCp.ptr, scsicmd->request_bufflen,
+			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+
+	writereply = (struct aac_write_reply *) fib_data(fibptr);
+	if (le32_to_cpu(writereply->status) == ST_OK)
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
+	else {
+		printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status);
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
+		set_sense((char *) &sense_data[cid],
+				    SENKEY_HW_ERR,
+				    SENCODE_INTERNAL_TARGET_FAILURE,
+				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+				    0, 0);
+	}
+
+	fib_complete(fibptr);
+	fib_free(fibptr);
+	aac_io_done(scsicmd);
+}
+
+int aac_read(Scsi_Cmnd * scsicmd, int cid)
+{
+	unsigned long lba;
+	unsigned long count;
+	unsigned long byte_count = 0;
+	int status;
+
+	struct aac_read *readcmd;
+	u16 fibsize;
+	struct aac_dev *dev;
+	struct fib * cmd_fibcontext;
+
+	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	/*
+	 *	Get block address and transfer length
+	 */
+	if (scsicmd->cmnd[0] == SS_READ)	/* 6 byte command */
+	{
+		dprintk((KERN_DEBUG "aachba: received a read(6) command on target %d.\n", cid));
+
+		lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
+		count = scsicmd->cmnd[4];
+
+		if (count == 0)
+			count = 256;
+	} else {
+		dprintk((KERN_DEBUG "aachba: received a read(10) command on target %d.\n", cid));
+
+		lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+		count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
+	}
+	dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %lu, t = %ld.\n", smp_processor_id(), lba, jiffies));
+	/*
+	 *	Alocate and initialize a Fib
+	 */
+	if (!(cmd_fibcontext = fib_alloc(dev))) {
+		scsicmd->result = DID_ERROR << 16;
+		aac_io_done(scsicmd);
+		return (-1);
+	}
+
+	fib_init(cmd_fibcontext);
+
+	readcmd = (struct aac_read *) fib_data(cmd_fibcontext);
+	readcmd->command = cpu_to_le32(VM_CtBlockRead);
+	readcmd->cid = cpu_to_le32(cid);
+	readcmd->block = cpu_to_le32(lba);
+	readcmd->count = cpu_to_le32(count * 512);
+	readcmd->sg.count = cpu_to_le32(1);
+
+	if (count * 512 > (64 * 1024))
+		BUG();
+	/*
+	 *	Build Scatter/Gather list
+	 */
+	if (scsicmd->use_sg)	/* use scatter/gather list */
+	{
+		struct scatterlist *sg;
+		int i;
+		int sg_count;
+
+		sg = (struct scatterlist *) scsicmd->request_buffer;
+		
+		sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
+			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+			
+		byte_count = 0;
+
+		for (i = 0; i < sg_count; i++) {
+			readcmd->sg.sg[i].addr = cpu_to_le32(sg_dma_address(sg));
+			readcmd->sg.sg[i].count = cpu_to_le32(sg_dma_len(sg));
+			byte_count += sg->length;
+			if (sg->length > (64 * 1024))
+				BUG();
+			sg++;
+		}
+		readcmd->sg.count = cpu_to_le32(sg_count);
+
+		if (sg_count > MAX_DRIVER_SG_SEGMENT_COUNT)
+			BUG();
+	}
+	else if(scsicmd->request_bufflen)
+	{
+		u32 addr;
+		addr = pci_map_single(dev->pdev, scsicmd->request_buffer,
+				scsicmd->request_bufflen, scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+		scsicmd->SCp.ptr = (void *)addr;
+		readcmd->sg.sg[0].addr = cpu_to_le32(addr);
+		readcmd->sg.sg[0].count = cpu_to_le32(scsicmd->request_bufflen);
+
+		byte_count = scsicmd->request_bufflen;
+
+		if (byte_count > (64 * 1024))
+			BUG();
+	}
+	if (byte_count != readcmd->count)
+		BUG();
+	/*
+	 *	Now send the Fib to the adapter
+	 */
+	fibsize = sizeof(struct aac_read) + ((readcmd->sg.count - 1) * sizeof (struct sgentry));
+	status = fib_send(ContainerCommand, 
+			  cmd_fibcontext, 
+			  fibsize, 
+			  FsaNormal, 
+			  0, 1, 
+			  (fib_callback) read_callback, 
+			  (void *) scsicmd);
+	/*
+	 *	Check that the command queued to the controller
+	 */
+	if (status == -EINPROGRESS) 
+		return 0;
+		
+	printk(KERN_WARNING "aac_read: fib_send failed with status: %d.\n", status);
+	/*
+	 *	For some reason, the Fib didn't queue, return QUEUE_FULL
+	 */
+	scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL;
+	aac_io_done(scsicmd);
+	fib_complete(cmd_fibcontext);
+	fib_free(cmd_fibcontext);
+	return -1;
+}
+
+static int aac_write(Scsi_Cmnd * scsicmd, int cid)
+{
+	unsigned long lba;
+	unsigned long count;
+	unsigned long byte_count = 0;
+	int status;
+	struct aac_write *writecmd;
+	u16 fibsize;
+	struct aac_dev *dev;
+	struct fib * cmd_fibcontext;
+
+	dev = (struct aac_dev *)scsicmd->host->hostdata;
+	/*
+	 *	Get block address and transfer length
+	 */
+	if (scsicmd->cmnd[0] == SS_WRITE)	/* 6 byte command */
+	{
+		lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
+		count = scsicmd->cmnd[4];
+		if (count == 0)
+			count = 256;
+	} else {
+		dprintk((KERN_DEBUG "aachba: received a write(10) command on target %d.\n", cid));
+		lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+		count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
+	}
+	dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %lu, t = %ld.\n", smp_processor_id(), lba, jiffies));
+	/*
+	 *	Allocate and initialize a Fib then setup a BlockWrite command
+	 */
+	if (!(cmd_fibcontext = fib_alloc(dev))) {
+		scsicmd->result = DID_ERROR << 16;
+		aac_io_done(scsicmd);
+		return -1;
+	}
+	fib_init(cmd_fibcontext);
+
+	writecmd = (struct aac_write *) fib_data(cmd_fibcontext);
+	writecmd->command = cpu_to_le32(VM_CtBlockWrite);
+	writecmd->cid = cpu_to_le32(cid);
+	writecmd->block = cpu_to_le32(lba);
+	writecmd->count = cpu_to_le32(count * 512);
+	writecmd->sg.count = cpu_to_le32(1);
+	/* FIXME: why isnt ->stable setup */
+
+	if (count * 512 > (64 * 1024)) {
+		BUG();
+	}
+	/*
+	 *	Build Scatter/Gather list
+	 */
+	if (scsicmd->use_sg)
+	{
+		struct scatterlist *sg;
+		int i;
+		int sg_count;
+		
+		sg = (struct scatterlist *) scsicmd->request_buffer;
+
+		sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
+			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+
+		byte_count = 0;
+
+		for (i = 0; i < scsicmd->use_sg; i++) {
+			writecmd->sg.sg[i].addr = cpu_to_le32(sg_dma_address(sg));
+			writecmd->sg.sg[i].count = cpu_to_le32(sg_dma_len(sg));
+			byte_count += sg->length;
+
+			if (sg->length > (64 * 1024))
+				BUG();
+			sg++;
+		}
+		writecmd->sg.count = cpu_to_le32(sg_count);
+
+		if (sg_count > MAX_DRIVER_SG_SEGMENT_COUNT)
+			BUG();
+	}
+	else if(scsicmd->request_bufflen)
+	{
+		u32 addr; 
+		addr = pci_map_single(dev->pdev,
+				scsicmd->request_buffer,
+				scsicmd->request_bufflen,
+				scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
+		writecmd->sg.sg[0].addr = cpu_to_le32(addr);
+		writecmd->sg.sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
+		scsicmd->SCp.ptr = (void *)addr;
+		byte_count = scsicmd->request_bufflen;
+
+		if (byte_count > (64 * 1024))
+			BUG();
+	}
+	if (byte_count != writecmd->count)
+		BUG();
+	/*
+	 *	Now send the Fib to the adapter
+	 */
+	fibsize = sizeof (struct aac_write) + ((writecmd->sg.count - 1) * sizeof (struct sgentry));
+
+	status = fib_send(ContainerCommand, 
+			  cmd_fibcontext,
+			  fibsize, FsaNormal,
+			  0, 1,
+			  (fib_callback) write_callback,
+			  (void *) scsicmd);
+	/*
+	 *	Check that the command queued to the controller
+	 */
+	if (status == -EINPROGRESS)
+		return 0;
+
+	printk(KERN_WARNING "aac_write: fib_send failed with status: %d\n", status);
+	/*
+	 *	For some reason, the Fib didn't queue, return QUEUE_FULL
+	 */
+	scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL;
+	aac_io_done(scsicmd);
+
+	fib_complete(cmd_fibcontext);
+	fib_free(cmd_fibcontext);
+	return -1;
+}
+
+
+/**
+ *	aac_scsi_cmd()		-	Process SCSI command
+ *	@scsicmd:		SCSI command block
+ *	@wait:			1 if the user wants to await completion
+ *
+ *	Emulate a SCSI command and queue the required request for the
+ *	aacraid firmware.
+ */
+ 
+int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
+{
+	int cid = 0;
+	struct fsa_scsi_hba *fsa_dev_ptr;
+	int cardtype;
+	int ret;
+	struct aac_dev *dev = (struct aac_dev *)scsicmd->host->hostdata;
+	
+	cardtype = dev->cardtype;
+
+	fsa_dev_ptr = fsa_dev[scsicmd->host->unique_id];
+
+	/*
+	 *	If the bus, target or lun is out of range, return fail
+	 *	Test does not apply to ID 16, the pseudo id for the controller
+	 *	itself.
+	 */
+	if (scsicmd->target != scsicmd->host->this_id) {
+		if ((scsicmd->channel > 0) ||(scsicmd->target > 15) || (scsicmd->lun > 7)) 
+		{
+			dprintk((KERN_DEBUG "The bus, target or lun is out of range = %d, %d, %d.\n", 
+				scsicmd->channel, scsicmd->target, scsicmd->lun));
+			scsicmd->result = DID_BAD_TARGET << 16;
+			__aac_io_done(scsicmd);
+			return -1;
+		}
+		cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
+		/*
+		 *	If the target container doesn't exist, it may have
+		 *	been newly created
+		 */
+		if (fsa_dev_ptr->valid[cid] == 0) {
+			switch (scsicmd->cmnd[0]) {
+			case SS_INQUIR:
+			case SS_RDCAP:
+			case SS_TEST:
+				spin_unlock_irq(&io_request_lock);
+				probe_container(dev, cid);
+				spin_lock_irq(&io_request_lock);
+			default:
+				break;
+			}
+		}
+		/*
+		 *	If the target container still doesn't exist, 
+		 *	return failure
+		 */
+		if (fsa_dev_ptr->valid[cid] == 0) {
+			scsicmd->result = DID_BAD_TARGET << 16;
+			__aac_io_done(scsicmd);
+			return -1;
+		}
+	} 
+	else if ((scsicmd->cmnd[0] != SS_INQUIR) &&	/* only INQUIRY & TUR cmnd supported for controller */
+	    (scsicmd->cmnd[0] != SS_TEST)) 
+	{
+		/*
+		 *	Command aimed at the controller
+		 */
+		dprintk((KERN_WARNING "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x.\n", scsicmd->cmnd[0]));
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
+		set_sense((char *) &sense_data[cid],
+			    SENKEY_ILLEGAL,
+			    SENCODE_INVALID_COMMAND,
+			    ASENCODE_INVALID_COMMAND, 0, 0, 0, 0);
+		__aac_io_done(scsicmd);
+		return -1;
+	}
+	/* Handle commands here that don't really require going out to the adapter */
+	switch (scsicmd->cmnd[0]) 
+	{
+		case SS_INQUIR:
+		{
+			struct inquiry_data *inq_data_ptr;
+
+			dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->target));
+			inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer;
+			memset(inq_data_ptr, 0, sizeof (struct inquiry_data));
+
+			inq_data_ptr->inqd_ver = 2;	/* claim compliance to SCSI-2 */
+			inq_data_ptr->inqd_dtq = 0x80;	/* set RMB bit to one indicating that the medium is removable */
+			inq_data_ptr->inqd_rdf = 2;	/* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
+			inq_data_ptr->inqd_len = 31;
+
+			/*
+			 *	Set the Vendor, Product, and Revision Level
+			 *	see: <vendor>.c i.e. aac.c
+			 */
+			setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr->type[cid]);
+			if (scsicmd->target == scsicmd->host->this_id)
+			    	inq_data_ptr->inqd_pdt = INQD_PDT_PROC;	/* Processor device */
+			else
+				inq_data_ptr->inqd_pdt = INQD_PDT_DA;	/* Direct/random access device */
+			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
+			__aac_io_done(scsicmd);
+			return 0;
+		}
+		case SS_RDCAP:
+		{
+			int capacity;
+			char *cp;
+
+			dprintk((KERN_DEBUG "READ CAPACITY command.\n"));
+			capacity = fsa_dev_ptr->size[cid] - 1;
+			cp = scsicmd->request_buffer;
+			cp[0] = (capacity >> 24) & 0xff;
+			cp[1] = (capacity >> 16) & 0xff;
+			cp[2] = (capacity >> 8) & 0xff;
+			cp[3] = (capacity >> 0) & 0xff;
+			cp[4] = 0;
+			cp[5] = 0;
+			cp[6] = 2;
+			cp[7] = 0;
+
+			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
+			__aac_io_done(scsicmd);
+
+			return 0;
+		}
+
+		case SS_MODESEN:
+		{
+			char *mode_buf;
+
+			dprintk((KERN_DEBUG "MODE SENSE command.\n"));
+			mode_buf = scsicmd->request_buffer;
+			mode_buf[0] = 0;	/* Mode data length (MSB) */
+			mode_buf[1] = 6;	/* Mode data length (LSB) */
+			mode_buf[2] = 0;	/* Medium type - default */
+			mode_buf[3] = 0;	/* Device-specific param, bit 8: 0/1 = write enabled/protected */
+			mode_buf[4] = 0;	/* reserved */
+			mode_buf[5] = 0;	/* reserved */
+			mode_buf[6] = 0;	/* Block descriptor length (MSB) */
+			mode_buf[7] = 0;	/* Block descriptor length (LSB) */
+
+			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
+			__aac_io_done(scsicmd);
+
+			return 0;
+		}
+		case SS_REQSEN:
+			dprintk((KERN_DEBUG "REQUEST SENSE command.\n"));
+			memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof (struct sense_data));
+			memset(&sense_data[cid], 0, sizeof (struct sense_data));
+			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
+			__aac_io_done(scsicmd);
+			return (0);
+
+		case SS_LOCK:
+			dprintk((KERN_DEBUG "LOCK command.\n"));
+			if (scsicmd->cmnd[4])
+				fsa_dev_ptr->locked[cid] = 1;
+			else
+				fsa_dev_ptr->locked[cid] = 0;
+
+			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
+			__aac_io_done(scsicmd);
+			return 0;
+		/*
+		 *	These commands are all No-Ops
+		 */
+		case SS_TEST:
+		case SS_RESERV:
+		case SS_RELES:
+		case SS_REZERO:
+		case SS_REASGN:
+		case SS_SEEK:
+		case SS_ST_SP:
+			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
+			__aac_io_done(scsicmd);
+			return (0);
+	}
+
+	switch (scsicmd->cmnd[0]) 
+	{
+		case SS_READ:
+		case SM_READ:
+			/*
+			 *	Hack to keep track of ordinal number of the device that
+			 *	corresponds to a container. Needed to convert
+			 *	containers to /dev/sd device names
+			 */
+			 
+			spin_unlock_irq(&io_request_lock);
+			fsa_dev_ptr->devno[cid] = DEVICE_NR(scsicmd->request.rq_dev);
+			ret = aac_read(scsicmd, cid);
+			spin_lock_irq(&io_request_lock);
+			return ret;
+
+		case SS_WRITE:
+		case SM_WRITE:
+			spin_unlock_irq(&io_request_lock);
+			ret = aac_write(scsicmd, cid);
+			spin_lock_irq(&io_request_lock);
+			return ret;
+		default:
+			/*
+			 *	Unhandled commands
+			 */
+			printk(KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]);
+			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
+			set_sense((char *) &sense_data[cid],
+				SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND,
+			ASENCODE_INVALID_COMMAND, 0, 0, 0, 0);
+			__aac_io_done(scsicmd);
+			return -1;
+	}
+}
+
+static int query_disk(struct aac_dev *dev, void *arg)
+{
+	struct aac_query_disk qd;
+	struct fsa_scsi_hba *fsa_dev_ptr;
+
+	fsa_dev_ptr = &(dev->fsa_dev);
+	if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk)))
+		return -EFAULT;
+	if (qd.cnum == -1)
+		qd.cnum = TARGET_LUN_TO_CONTAINER(qd.target, qd.lun);
+	else if ((qd.bus == -1) && (qd.target == -1) && (qd.lun == -1)) 
+	{
+		if (qd.cnum < 0 || qd.cnum > MAXIMUM_NUM_CONTAINERS)
+			return -EINVAL;
+		qd.instance = dev->scsi_host_ptr->host_no;
+		qd.bus = 0;
+		qd.target = CONTAINER_TO_TARGET(qd.cnum);
+		qd.lun = CONTAINER_TO_LUN(qd.cnum);
+	}
+	else return -EINVAL;
+
+	qd.valid = fsa_dev_ptr->valid[qd.cnum];
+	qd.locked = fsa_dev_ptr->locked[qd.cnum];
+	qd.deleted = fsa_dev_ptr->deleted[qd.cnum];
+
+	if (fsa_dev_ptr->devno[qd.cnum] == -1)
+		qd.unmapped = 1;
+	else
+		qd.unmapped = 0;
+
+	get_sd_devname(fsa_dev_ptr->devno[qd.cnum], qd.name);
+
+	if (copy_to_user(arg, &qd, sizeof (struct aac_query_disk)))
+		return -EFAULT;
+	return 0;
+}
+
+static void get_sd_devname(int disknum, char *buffer)
+{
+	if (disknum < 0) {
+		sprintf(buffer, "%s", "");
+		return;
+	}
+
+	if (disknum < 26)
+		sprintf(buffer, "sd%c", 'a' + disknum);
+	else {
+		unsigned int min1;
+		unsigned int min2;
+		/*
+		 * For larger numbers of disks, we need to go to a new
+		 * naming scheme.
+		 */
+		min1 = disknum / 26;
+		min2 = disknum % 26;
+		sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
+	}
+}
+
+static int force_delete_disk(struct aac_dev *dev, void *arg)
+{
+	struct aac_delete_disk dd;
+	struct fsa_scsi_hba *fsa_dev_ptr;
+
+	fsa_dev_ptr = &(dev->fsa_dev);
+
+	if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))
+		return -EFAULT;
+
+	if (dd.cnum > MAXIMUM_NUM_CONTAINERS)
+		return -EINVAL;
+	/*
+	 *	Mark this container as being deleted.
+	 */
+	fsa_dev_ptr->deleted[dd.cnum] = 1;
+	/*
+	 *	Mark the container as no longer valid
+	 */
+	fsa_dev_ptr->valid[dd.cnum] = 0;
+	return 0;
+}
+
+static int delete_disk(struct aac_dev *dev, void *arg)
+{
+	struct aac_delete_disk dd;
+	struct fsa_scsi_hba *fsa_dev_ptr;
+
+	fsa_dev_ptr = &(dev->fsa_dev);
+
+	if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))
+		return -EFAULT;
+
+	if (dd.cnum > MAXIMUM_NUM_CONTAINERS)
+		return -EINVAL;
+	/*
+	 *	If the container is locked, it can not be deleted by the API.
+	 */
+	if (fsa_dev_ptr->locked[dd.cnum])
+		return -EBUSY;
+	else {
+		/*
+		 *	Mark the container as no longer being valid.
+		 */
+		fsa_dev_ptr->valid[dd.cnum] = 0;
+		fsa_dev_ptr->devno[dd.cnum] = -1;
+		return 0;
+	}
+}
+
+int aac_dev_ioctl(struct aac_dev *dev, int cmd, void *arg)
+{
+	switch (cmd) {
+	case FSACTL_QUERY_DISK:
+		return query_disk(dev, arg);
+	case FSACTL_DELETE_DISK:
+		return delete_disk(dev, arg);
+	case FSACTL_FORCE_DELETE_DISK:
+		return force_delete_disk(dev, arg);
+	case 2131:
+		return aac_get_containers(dev);
+	default:
+		return -ENOTTY;
+	}
+}
+
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/aacraid.h linux/drivers/scsi/aacraid/aacraid.h
--- linux-2.4.17-pre6/drivers/scsi/aacraid/aacraid.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/aacraid.h	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,1198 @@
+#define dprintk(x)	printk x
+
+#define AAC_NUM_FIB	128
+#define AAC_NUM_IO_FIB	116
+
+/*------------------------------------------------------------------------------
+ *              D E F I N E S
+ *----------------------------------------------------------------------------*/
+
+struct diskparm
+{
+	int heads;
+	int sectors;
+	int cylinders;
+};
+
+
+/*
+ *	DON'T CHANGE THE ORDER, this is set by the firmware
+ */
+ 
+#define		CT_NONE			0
+#define		CT_VOLUME		1
+#define		CT_MIRROR		2
+#define		CT_STRIPE		3
+#define		CT_RAID5		4
+#define		CT_SSRW			5
+#define		CT_SSRO			6
+#define		CT_MORPH		7
+#define		CT_PASSTHRU		8
+#define		CT_RAID4		9
+#define		CT_RAID10		10	/* stripe of mirror */
+#define		CT_RAID00		11	/* stripe of stripe */
+#define		CT_VOLUME_OF_MIRRORS	12	/* volume of mirror */
+#define		CT_PSEUDO_RAID		13	/* really raid4 */
+#define		CT_LAST_VOLUME_TYPE	14
+
+/*
+ *	Types of objects addressable in some fashion by the client.
+ *	This is a superset of those objects handled just by the filesystem
+ *	and includes "raw" objects that an administrator would use to
+ *	configure containers and filesystems.
+ */
+
+#define		FT_REG		1	/* regular file */
+#define		FT_DIR		2	/* directory */
+#define		FT_BLK		3	/* "block" device - reserved */
+#define		FT_CHR		4	/* "character special" device - reserved */
+#define		FT_LNK		5	/* symbolic link */
+#define		FT_SOCK		6	/* socket */
+#define		FT_FIFO		7	/* fifo */
+#define		FT_FILESYS	8	/* ADAPTEC's "FSA"(tm) filesystem */
+#define		FT_DRIVE	9	/* physical disk - addressable in scsi by bus/target/lun */
+#define		FT_SLICE	10	/* virtual disk - raw volume - slice */
+#define		FT_PARTITION	11	/* FSA partition - carved out of a slice - building block for containers */
+#define		FT_VOLUME	12	/* Container - Volume Set */
+#define		FT_STRIPE	13	/* Container - Stripe Set */
+#define		FT_MIRROR	14	/* Container - Mirror Set */
+#define		FT_RAID5	15	/* Container - Raid 5 Set */
+#define		FT_DATABASE	16	/* Storage object with "foreign" content manager */
+
+/*
+ *	Host side memory scatter gather list
+ *	Used by the adapter for read, write, and readdirplus operations
+ */
+
+struct sgentry {
+	u32	addr;	/* 32-bit Base address. */
+	u32	count;	/* Length. */
+};
+
+/*
+ *	SGMAP
+ *
+ *	This is the SGMAP structure for all commands that use
+ *	32-bit addressing.
+ *
+ *	Note that the upper 16 bits of SgCount are used as flags.
+ *	Only the lower 16 bits of SgCount are actually used as the
+ *	SG element count.
+ */
+
+struct sgmap {
+	u32		count;
+	struct sgentry	sg[1];
+};
+
+struct creation_info
+{
+	u8 		buildnum;		/* e.g., 588 */
+	u8 		usec;			/* e.g., 588 */
+	u8	 	via;			/* e.g., 1 = FSU,
+						 * 	 2 = API
+						 */
+	u8	 	year;		 	/* e.g., 1997 = 97 */
+	u32		date;			/*
+						 * unsigned 	Month		:4;	// 1 - 12
+						 * unsigned 	Day		:6;	// 1 - 32
+						 * unsigned 	Hour		:6;	// 0 - 23
+						 * unsigned 	Minute		:6;	// 0 - 60
+						 * unsigned 	Second		:6;	// 0 - 60
+						 */
+	u64		serial;			/* e.g., 0x1DEADB0BFAFAF001 */
+};
+
+
+/*
+ *	Define all the constants needed for the communication interface
+ */
+
+/*
+ *	Define how many queue entries each queue will have and the total
+ *	number of entries for the entire communication interface. Also define
+ *	how many queues we support.
+ *
+ *	This has to match the controller
+ */
+
+#define NUMBER_OF_COMM_QUEUES  8   // 4 command; 4 response
+#define HOST_HIGH_CMD_ENTRIES  4
+#define HOST_NORM_CMD_ENTRIES  8
+#define ADAP_HIGH_CMD_ENTRIES  4
+#define ADAP_NORM_CMD_ENTRIES  512
+#define HOST_HIGH_RESP_ENTRIES 4
+#define HOST_NORM_RESP_ENTRIES 512
+#define ADAP_HIGH_RESP_ENTRIES 4
+#define ADAP_NORM_RESP_ENTRIES 8
+
+#define TOTAL_QUEUE_ENTRIES  \
+    (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
+	    HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
+
+
+/*
+ *	Set the queues on a 16 byte alignment
+ */
+ 
+#define QUEUE_ALIGNMENT		16
+
+/*
+ *	The queue headers define the Communication Region queues. These
+ *	are physically contiguous and accessible by both the adapter and the
+ *	host. Even though all queue headers are in the same contiguous block
+ *	they will be represented as individual units in the data structures.
+ */
+
+struct aac_entry {
+	u32 size;       /* Size in bytes of the Fib which this QE points to */
+	u32 addr;	/* Receiver addressable address of the FIB (low 32 address bits) */
+};
+
+/*
+ *	The adapter assumes the ProducerIndex and ConsumerIndex are grouped
+ *	adjacently and in that order.
+ */
+ 
+struct aac_qhdr {
+	u64 header_addr;		/* Address to hand the adapter to access to this queue head */
+	u32 *producer;			/* The producer index for this queue (host address) */
+	u32 *consumer;			/* The consumer index for this queue (host address) */
+};
+
+/*
+ *	Define all the events which the adapter would like to notify
+ *	the host of.
+ */
+ 
+#define		HostNormCmdQue		1	/* Change in host normal priority command queue */
+#define		HostHighCmdQue		2	/* Change in host high priority command queue */
+#define		HostNormRespQue		3	/* Change in host normal priority response queue */
+#define		HostHighRespQue		4	/* Change in host high priority response queue */
+#define		AdapNormRespNotFull	5
+#define		AdapHighRespNotFull	6
+#define		AdapNormCmdNotFull	7
+#define		AdapHighCmdNotFull	8
+#define		SynchCommandComplete	9
+#define		AdapInternalError	0xfe    /* The adapter detected an internal error shutting down */
+
+/*
+ *	Define all the events the host wishes to notify the
+ *	adapter of. The first four values much match the Qid the
+ *	corresponding queue.
+ */
+
+#define		AdapNormCmdQue		2
+#define		AdapHighCmdQue		3
+#define		AdapNormRespQue		6
+#define		AdapHighRespQue		7
+#define		HostShutdown		8
+#define		HostPowerFail		9
+#define		FatalCommError		10
+#define		HostNormRespNotFull	11
+#define		HostHighRespNotFull	12
+#define		HostNormCmdNotFull	13
+#define		HostHighCmdNotFull	14
+#define		FastIo			15
+#define		AdapPrintfDone		16
+
+/*
+ *	Define all the queues that the adapter and host use to communicate
+ *	Number them to match the physical queue layout.
+ */
+
+enum aac_queue_types {
+        HostNormCmdQueue = 0,	/* Adapter to host normal priority command traffic */
+        HostHighCmdQueue,	/* Adapter to host high priority command traffic */
+        AdapNormCmdQueue,	/* Host to adapter normal priority command traffic */
+        AdapHighCmdQueue,	/* Host to adapter high priority command traffic */
+        HostNormRespQueue,	/* Adapter to host normal priority response traffic */
+        HostHighRespQueue,	/* Adapter to host high priority response traffic */
+        AdapNormRespQueue,	/* Host to adapter normal priority response traffic */
+        AdapHighRespQueue	/* Host to adapter high priority response traffic */
+};
+
+/*
+ *	Assign type values to the FSA communication data structures
+ */
+
+#define		FIB_MAGIC	0x0001
+
+/*
+ *	Define the priority levels the FSA communication routines support.
+ */
+
+#define		FsaNormal	1
+#define		FsaHigh		2
+
+//
+// Define the FIB. The FIB is the where all the requested data and
+// command information are put to the application on the FSA adapter.
+//
+
+struct aac_fibhdr {
+	u32 XferState;			// Current transfer state for this CCB
+	u16 Command;			// Routing information for the destination
+	u8 StructType;			// Type FIB
+	u8 Flags;			// Flags for FIB
+	u16 Size;			// Size of this FIB in bytes
+	u16 SenderSize;			// Size of the FIB in the sender (for response sizing)
+	u32 SenderFibAddress;		// Host defined data in the FIB
+	u32 ReceiverFibAddress;		// Logical address of this FIB for the adapter
+	u32 SenderData;			// Place holder for the sender to store data
+	union {
+		struct {
+		    u32 _ReceiverTimeStart; 	// Timestamp for receipt of fib
+		    u32 _ReceiverTimeDone;	// Timestamp for completion of fib
+		} _s;
+		struct list_head _FibLinks;	// Used to link Adapter Initiated Fibs on the host
+	} _u;
+};
+
+#define FibLinks			_u._FibLinks
+
+#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(struct aac_fibhdr))
+
+
+struct hw_fib {
+	struct aac_fibhdr header;
+	u8 data[FIB_DATA_SIZE_IN_BYTES];		// Command specific data
+};
+
+/*
+ *	FIB commands
+ */
+
+#define 	TestCommandResponse		1
+#define		TestAdapterCommand		2
+/*
+ *	Lowlevel and comm commands
+ */
+#define		LastTestCommand			100
+#define		ReinitHostNormCommandQueue	101
+#define		ReinitHostHighCommandQueue	102
+#define		ReinitHostHighRespQueue		103
+#define		ReinitHostNormRespQueue		104
+#define		ReinitAdapNormCommandQueue	105
+#define		ReinitAdapHighCommandQueue	107
+#define		ReinitAdapHighRespQueue		108
+#define		ReinitAdapNormRespQueue		109
+#define		InterfaceShutdown		110
+#define		DmaCommandFib			120
+#define		StartProfile			121
+#define		TermProfile			122
+#define		SpeedTest			123
+#define		TakeABreakPt			124
+#define		RequestPerfData			125
+#define		SetInterruptDefTimer		126
+#define		SetInterruptDefCount		127
+#define		GetInterruptDefStatus		128
+#define		LastCommCommand			129
+/*
+ *	Filesystem commands
+ */
+#define		NuFileSystem			300
+#define		UFS				301
+#define		HostFileSystem			302
+#define		LastFileSystemCommand		303
+/*
+ *	Container Commands
+ */
+#define		ContainerCommand		500
+#define		ContainerCommand64		501
+/*
+ *	Cluster Commands
+ */
+#define		ClusterCommand	 		550
+/*
+ *	Scsi Port commands (scsi passthrough)
+ */
+#define		ScsiPortCommand			600
+/*
+ *	Misc house keeping and generic adapter initiated commands
+ */
+#define		AifRequest			700
+#define		CheckRevision			701
+#define		FsaHostShutdown			702
+#define		RequestAdapterInfo		703
+#define		IsAdapterPaused			704
+#define		SendHostTime			705
+#define		LastMiscCommand			706
+
+//
+// Commands that will target the failover level on the FSA adapter
+//
+
+enum fib_xfer_state {
+	HostOwned 			= (1<<0),
+	AdapterOwned 			= (1<<1),
+	FibInitialized 			= (1<<2),
+	FibEmpty 			= (1<<3),
+	AllocatedFromPool 		= (1<<4),
+	SentFromHost 			= (1<<5),
+	SentFromAdapter 		= (1<<6),
+	ResponseExpected 		= (1<<7),
+	NoResponseExpected 		= (1<<8),
+	AdapterProcessed 		= (1<<9),
+	HostProcessed 			= (1<<10),
+	HighPriority 			= (1<<11),
+	NormalPriority 			= (1<<12),
+	Async				= (1<<13),
+	AsyncIo				= (1<<13),	// rpbfix: remove with new regime
+	PageFileIo			= (1<<14),	// rpbfix: remove with new regime
+	ShutdownRequest			= (1<<15),
+	LazyWrite			= (1<<16),	// rpbfix: remove with new regime
+	AdapterMicroFib			= (1<<17),
+	BIOSFibPath			= (1<<18),
+	FastResponseCapable		= (1<<19),
+	ApiFib				= (1<<20)	// Its an API Fib.
+};
+
+/*
+ *	The following defines needs to be updated any time there is an
+ *	incompatible change made to the aac_init structure.
+ */
+
+#define ADAPTER_INIT_STRUCT_REVISION		3
+
+struct aac_init
+{
+	u32	InitStructRevision;
+	u32	MiniPortRevision;
+	u32	fsrev;
+	u32	CommHeaderAddress;
+	u32	FastIoCommAreaAddress;
+	u32	AdapterFibsPhysicalAddress;
+	u32	AdapterFibsVirtualAddress;
+	u32	AdapterFibsSize;
+	u32	AdapterFibAlign;
+	u32	printfbuf;
+	u32	printfbufsiz;
+	u32	HostPhysMemPages;		// number of 4k pages of host physical memory
+	u32	HostElapsedSeconds;		// number of seconds since 1970.
+};
+
+enum aac_log_level {
+	LOG_INIT			= 10,
+	LOG_INFORMATIONAL		= 20,
+	LOG_WARNING			= 30,
+	LOG_LOW_ERROR			= 40,
+	LOG_MEDIUM_ERROR		= 50,
+	LOG_HIGH_ERROR			= 60,
+	LOG_PANIC			= 70,
+	LOG_DEBUG			= 80,
+	LOG_WINDBG_PRINT		= 90
+};
+
+#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT	0x030b
+#define FSAFS_NTC_FIB_CONTEXT			0x030c
+
+struct aac_dev;
+
+struct adapter_ops
+{
+	void (*adapter_interrupt)(struct aac_dev *dev);
+	void (*adapter_notify)(struct aac_dev *dev, u32 event);
+	void (*adapter_enable_int)(struct aac_dev *dev, u32 event);
+	void (*adapter_disable_int)(struct aac_dev *dev, u32 event);
+};
+
+/*
+ *	Define which interrupt handler needs to be installed
+ */
+
+struct aac_driver_ident
+{
+	u16	vendor;
+	u16	device;
+	u16	subsystem_vendor;
+	u16	subsystem_device;
+	int 	(*init)(struct aac_dev *dev, unsigned long num);
+	char *	name;
+	char *	vname;
+	char *	model;
+};
+
+/*
+ *	The adapter interface specs all queues to be located in the same
+ *	physically contigous block. The host structure that defines the
+ *	commuication queues will assume they are each a seperate physically
+ *	contigous memory region that will support them all being one big
+ *	contigous block. 
+ *	There is a command and response queue for each level and direction of
+ *	commuication. These regions are accessed by both the host and adapter.
+ */
+ 
+struct aac_queue {
+	u64		 	logical;		/* This is the address we give the adapter */
+	struct aac_entry	*base;		   	/* This is the system virtual address */
+	struct aac_qhdr 	headers;       		/* A pointer to the producer and consumer queue headers for this queue */
+	u32	 		entries;	   	/* Number of queue entries on this queue */
+	wait_queue_head_t	qfull;		      	/* Event to wait on if the queue is full */
+	wait_queue_head_t	cmdready;	  	/* Indicates there is a Command ready from the adapter on this queue. */
+                                        		/* This is only valid for adapter to host command queues. */                      
+	spinlock_t	 	*lock;		     	/* Spinlock for this queue must take this lock before accessing the lock */
+	spinlock_t		lockdata;		/* Actual lock (used only on one side of the lock) */
+	unsigned long		SavedIrql;      	/* Previous IRQL when the spin lock is taken */
+	u32			padding;		/* Padding - FIXME - can remove I believe */
+	struct list_head 	cmdq;		   	/* A queue of FIBs which need to be prcessed by the FS thread. This is */
+                                		        /* only valid for command queues which receive entries from the adapter. */
+	struct list_head	pendingq;		/* A queue of outstanding fib's to the adapter. */
+	unsigned long		numpending;		/* Number of entries on outstanding queue. */
+	struct aac_dev *	dev;			/* Back pointer to adapter structure */
+};
+
+/*
+ *	Message queues. The order here is important, see also the 
+ *	queue type ordering
+ */
+
+struct aac_queue_block
+{
+	struct aac_queue queue[8];
+};
+
+/*
+ *	SaP1 Message Unit Registers
+ */
+ 
+struct sa_drawbridge_CSR {
+						//	 Offset |	Name
+	u32	reserved[10];			//	00h-27h |   Reserved
+	u8	LUT_Offset;			//		28h	|	Looup Table Offset
+	u8	reserved1[3];			// 	29h-2bh	|	Reserved
+	u32	LUT_Data;			//		2ch	|	Looup Table Data	
+	u32	reserved2[26];			//	30h-97h	|	Reserved
+	u16	PRICLEARIRQ;			//		98h	|	Primary Clear Irq
+	u16	SECCLEARIRQ;			//		9ah	|	Secondary Clear Irq
+	u16	PRISETIRQ;			//		9ch	|	Primary Set Irq
+	u16	SECSETIRQ;			//		9eh	|	Secondary Set Irq
+	u16	PRICLEARIRQMASK;		//		a0h	|	Primary Clear Irq Mask
+	u16	SECCLEARIRQMASK;		//		a2h	|	Secondary Clear Irq Mask
+	u16	PRISETIRQMASK;			//		a4h	|	Primary Set Irq Mask
+	u16	SECSETIRQMASK;			//		a6h	|	Secondary Set Irq Mask
+	u32	MAILBOX0;			//		a8h	|	Scratchpad 0
+	u32	MAILBOX1;			//		ach	|	Scratchpad 1
+	u32	MAILBOX2;			//		b0h	|	Scratchpad 2
+	u32	MAILBOX3;			//		b4h	|	Scratchpad 3
+	u32	MAILBOX4;			//		b8h	|	Scratchpad 4
+	u32	MAILBOX5;			//		bch	|	Scratchpad 5
+	u32	MAILBOX6;			//		c0h	|	Scratchpad 6
+	u32	MAILBOX7;			//		c4h	|	Scratchpad 7
+
+	u32	ROM_Setup_Data;			//		c8h | 	Rom Setup and Data
+	u32	ROM_Control_Addr;		//		cch | 	Rom Control and Address
+
+	u32	reserved3[12];			//	d0h-ffh	| 	reserved
+	u32	LUT[64];			// 100h-1ffh|	Lookup Table Entries
+
+	//
+	//  TO DO
+	//	need to add DMA, I2O, UART, etc registers form 80h to 364h
+	//
+
+};
+
+#define Mailbox0	SaDbCSR.MAILBOX0
+#define Mailbox1	SaDbCSR.MAILBOX1
+#define Mailbox2	SaDbCSR.MAILBOX2
+#define Mailbox3	SaDbCSR.MAILBOX3
+#define Mailbox4	SaDbCSR.MAILBOX4
+#define Mailbox5	SaDbCSR.MAILBOX5
+#define Mailbox7	SaDbCSR.MAILBOX7
+	
+#define DoorbellReg_p SaDbCSR.PRISETIRQ
+#define DoorbellReg_s SaDbCSR.SECSETIRQ
+#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
+
+
+#define	DOORBELL_0	cpu_to_le16(0x0001)
+#define DOORBELL_1	cpu_to_le16(0x0002)
+#define DOORBELL_2	cpu_to_le16(0x0004)
+#define DOORBELL_3	cpu_to_le16(0x0008)
+#define DOORBELL_4	cpu_to_le16(0x0010)
+#define DOORBELL_5	cpu_to_le16(0x0020)
+#define DOORBELL_6	cpu_to_le16(0x0040)
+
+	
+#define PrintfReady	DOORBELL_5
+#define PrintfDone	DOORBELL_5
+	
+struct sa_registers {
+	struct sa_drawbridge_CSR	SaDbCSR;			/* 98h - c4h */
+};
+	
+
+#define Sa_MINIPORT_REVISION			1
+
+#define sa_readw(AEP, CSR)		readl(&((AEP)->regs.sa->CSR))
+#define sa_readl(AEP,  CSR)		readl(&((AEP)->regs.sa->CSR))
+#define sa_writew(AEP, CSR, value)	writew(value, &((AEP)->regs.sa->CSR))
+#define sa_writel(AEP, CSR, value)	writel(value, &((AEP)->regs.sa->CSR))
+
+/*
+ *	Rx Message Unit Registers
+ */
+
+struct rx_mu_registers {
+						//	 Local	|   PCI*	|	Name
+						//			|		|
+	u32	ARSR;				//	1300h	|	00h	|	APIC Register Select Register
+	u32	reserved0;			//	1304h	|	04h	|	Reserved
+	u32	AWR;				//	1308h	|	08h	|	APIC Window Register
+	u32	reserved1;			//	130Ch	|	0Ch	|	Reserved
+	u32	IMRx[2];			//	1310h	|	10h	|	Inbound Message Registers
+	u32	OMRx[2];			//	1318h	|	18h	|	Outbound Message Registers
+	u32	IDR;				//	1320h	|	20h	|	Inbound Doorbell Register
+	u32	IISR;				//	1324h	|	24h	|	Inbound Interrupt Status Register
+	u32	IIMR;				//	1328h	|	28h	|	Inbound Interrupt Mask Register
+	u32	ODR;				//	132Ch	|	2Ch	|	Outbound Doorbell Register
+	u32	OISR;				//	1330h	|	30h	|	Outbound Interrupt Status Register
+	u32	OIMR;				//	1334h	|	34h	|	Outbound Interrupt Mask Register
+						// * Must access through ATU Inbound Translation Window
+};
+
+struct rx_inbound {
+	u32	Mailbox[8];
+};
+
+#define	InboundMailbox0		IndexRegs.Mailbox[0]
+#define	InboundMailbox1		IndexRegs.Mailbox[1]
+#define	InboundMailbox2		IndexRegs.Mailbox[2]
+#define	InboundMailbox3		IndexRegs.Mailbox[3]
+#define	InboundMailbox4		IndexRegs.Mailbox[4]
+
+#define	INBOUNDDOORBELL_0	cpu_to_le32(0x00000001)
+#define INBOUNDDOORBELL_1	cpu_to_le32(0x00000002)
+#define INBOUNDDOORBELL_2	cpu_to_le32(0x00000004)
+#define INBOUNDDOORBELL_3	cpu_to_le32(0x00000008)
+#define INBOUNDDOORBELL_4	cpu_to_le32(0x00000010)
+#define INBOUNDDOORBELL_5	cpu_to_le32(0x00000020)
+#define INBOUNDDOORBELL_6	cpu_to_le32(0x00000040)
+
+#define	OUTBOUNDDOORBELL_0	cpu_to_le32(0x00000001)
+#define OUTBOUNDDOORBELL_1	cpu_to_le32(0x00000002)
+#define OUTBOUNDDOORBELL_2	cpu_to_le32(0x00000004)
+#define OUTBOUNDDOORBELL_3	cpu_to_le32(0x00000008)
+#define OUTBOUNDDOORBELL_4	cpu_to_le32(0x00000010)
+
+#define InboundDoorbellReg	MUnit.IDR
+#define OutboundDoorbellReg	MUnit.ODR
+
+struct rx_registers {
+	struct rx_mu_registers		MUnit;		// 1300h - 1334h
+	u32				reserved1[6];	// 1338h - 134ch
+	struct rx_inbound		IndexRegs;
+};
+
+#define rx_readb(AEP, CSR)		readb(&((AEP)->regs.rx->CSR))
+#define rx_readl(AEP, CSR)		readl(&((AEP)->regs.rx->CSR))
+#define rx_writeb(AEP, CSR, value)	writeb(value, &((AEP)->regs.rx->CSR))
+#define rx_writel(AEP, CSR, value)	writel(value, &((AEP)->regs.rx->CSR))
+
+struct fib;
+
+typedef void (*fib_callback)(void *ctxt, struct fib *fibctx);
+
+struct aac_fib_context {
+	s16	 		type;		// used for verification of structure	
+	s16	 		size;
+	u32			jiffies;	// used for cleanup
+	struct list_head	next;		// used to link context's into a linked list
+	struct semaphore 	wait_sem;	// this is used to wait for the next fib to arrive.
+	int			wait;		// Set to true when thread is in WaitForSingleObject
+	unsigned long		count;		// total number of FIBs on FibList
+	struct list_head	fibs;
+};
+
+#define MAXIMUM_NUM_CONTAINERS	64		// 4 Luns * 16 Targets
+#define MAXIMUM_NUM_ADAPTERS	8
+
+struct fsa_scsi_hba {
+	unsigned long		size[MAXIMUM_NUM_CONTAINERS];
+	unsigned long		type[MAXIMUM_NUM_CONTAINERS];
+	unsigned char		valid[MAXIMUM_NUM_CONTAINERS];
+	unsigned char		ro[MAXIMUM_NUM_CONTAINERS];
+	unsigned char		locked[MAXIMUM_NUM_CONTAINERS];
+	unsigned char		deleted[MAXIMUM_NUM_CONTAINERS];
+	long			devno[MAXIMUM_NUM_CONTAINERS];
+};
+
+struct fib {
+	void			*next;	/* this is used by the allocator */
+	s16			type;
+	s16			size;
+	/*
+	 *	The Adapter that this I/O is destined for.
+	 */
+	struct aac_dev 		*dev;
+	u64			logicaladdr;	/* 64 bit */
+	/*
+	 *	This is the event the sendfib routine will wait on if the
+	 *	caller did not pass one and this is synch io.
+	 */
+	struct semaphore 	event_wait;
+	spinlock_t		event_lock;
+
+	unsigned long		done;	/* gets set to 1 when fib is complete */
+	fib_callback 		callback;
+	void 			*callback_data;
+	unsigned long		flags;
+	/*
+	 *	The following is used to put this fib context onto the 
+	 *	Outstanding I/O queue.
+	 */
+	struct list_head	queue;
+
+	void 			*data;
+	struct hw_fib		*fib;		/* Actual shared object */
+};
+
+struct aac_dev
+{
+	struct aac_dev		*next;
+	const char		*name;
+	int			id;
+
+	u16			irq_mask;
+	/*
+	 *	Map for 128 fib objects (64k)
+	 */	
+	dma_addr_t		hw_fib_pa;
+	struct hw_fib		*hw_fib_va;
+	/*
+	 *	Fib Headers
+	 */
+	struct fib		fibs[AAC_NUM_FIB];
+	struct fib		*free_fib;
+	struct fib		*timeout_fib;
+	spinlock_t		fib_lock;
+	
+	struct aac_queue_block *queues;
+	/*
+	 *	The user API will use an IOCTL to register itself to receive
+	 *	FIBs from the adapter.  The following list is used to keep
+	 *	track of all the threads that have requested these FIBs.  The
+	 *	mutex is used to synchronize access to all data associated 
+	 *	with the adapter fibs.
+	 */
+	struct list_head	fib_list;
+
+	struct adapter_ops	a_ops;
+	unsigned long		fsrev;		/* Main driver's revision number */
+	
+	struct aac_init		*init;		/* Holds initialization info to communicate with adapter */
+	void *			init_pa; 	/* Holds physical address of the init struct */
+	
+	struct pci_dev		*pdev;		/* Our PCI interface */
+	void *			printfbuf;	/* pointer to buffer used for printf's from the adapter */
+	void *			comm_addr;	/* Base address of Comm area */
+	dma_addr_t		comm_phys;	/* Physical Address of Comm area */
+	size_t			comm_size;
+
+	struct Scsi_Host	*scsi_host_ptr;
+	struct fsa_scsi_hba	fsa_dev;
+	int			thread_pid;
+	int			cardtype;
+	
+	/*
+	 *	The following is the device specific extension.
+	 */
+	union
+	{
+		struct sa_registers *sa;
+		struct rx_registers *rx;
+	} regs;
+	/*
+	 *	The following is the number of the individual adapter
+	 */
+	long			devnum;
+	int			aif_thread;
+	struct completion	aif_completion;
+};
+
+#define AllocateAndMapFibSpace(dev, MapFibContext) \
+	dev->a_ops.AllocateAndMapFibSpace(dev, MapFibContext)
+
+#define UnmapAndFreeFibSpace(dev, MapFibContext) \
+	dev->a_ops.UnmapAndFreeFibSpace(dev, MapFibContext)
+
+#define aac_adapter_interrupt(dev) \
+	dev->a_ops.adapter_interrupt(dev)
+
+#define aac_adapter_notify(dev, event) \
+	dev->a_ops.adapter_notify(dev, event)
+
+#define aac_adapter_enable_int(dev, event) \
+	dev->a_ops.adapter_enable_int(dev, event)
+
+#define aac_adapter_disable_int(dev, event) \
+	dev->a_ops.adapter_disable_int(dev, event)
+
+
+
+#define FIB_CONTEXT_FLAG_TIMED_OUT		(0x00000001)
+
+/*
+ *	Define the command values
+ */
+ 
+#define		Null			0
+#define 	GetAttributes		1
+#define 	SetAttributes		2
+#define 	Lookup			3
+#define 	ReadLink		4
+#define 	Read			5
+#define 	Write			6
+#define		Create			7
+#define		MakeDirectory		8
+#define		SymbolicLink		9
+#define		MakeNode		10
+#define		Removex			11
+#define		RemoveDirectoryx	12
+#define		Rename			13
+#define		Link			14
+#define		ReadDirectory		15
+#define		ReadDirectoryPlus	16
+#define		FileSystemStatus	17
+#define		FileSystemInfo		18
+#define		PathConfigure		19
+#define		Commit			20
+#define		Mount			21
+#define		UnMount			22
+#define		Newfs			23
+#define		FsCheck			24
+#define		FsSync			25
+#define		SimReadWrite		26
+#define		SetFileSystemStatus	27
+#define		BlockRead		28
+#define		BlockWrite		29
+#define		NvramIoctl		30
+#define		FsSyncWait		31
+#define		ClearArchiveBit		32
+#define		SetAcl			33
+#define		GetAcl			34
+#define		AssignAcl		35
+#define		FaultInsertion		36	/* Fault Insertion Command */
+#define		CrazyCache		37	/* Crazycache */
+
+#define		MAX_FSACOMMAND_NUM	38
+
+
+/*
+ *	Define the status returns. These are very unixlike although
+ *	most are not in fact used
+ */
+
+#define		ST_OK		0
+#define		ST_PERM		1
+#define		ST_NOENT	2
+#define		ST_IO		5
+#define		ST_NXIO		6
+#define		ST_E2BIG	7
+#define		ST_ACCES	13
+#define		ST_EXIST	17
+#define		ST_XDEV		18
+#define		ST_NODEV	19
+#define		ST_NOTDIR	20
+#define		ST_ISDIR	21
+#define		ST_INVAL	22
+#define		ST_FBIG		27
+#define		ST_NOSPC	28
+#define		ST_ROFS		30
+#define		ST_MLINK	31
+#define		ST_WOULDBLOCK	35
+#define		ST_NAMETOOLONG	63
+#define		ST_NOTEMPTY	66
+#define		ST_DQUOT	69
+#define		ST_STALE	70
+#define		ST_REMOTE	71
+#define		ST_BADHANDLE	10001
+#define		ST_NOT_SYNC	10002
+#define		ST_BAD_COOKIE	10003
+#define		ST_NOTSUPP	10004
+#define		ST_TOOSMALL	10005
+#define		ST_SERVERFAULT	10006
+#define		ST_BADTYPE	10007
+#define		ST_JUKEBOX	10008
+#define		ST_NOTMOUNTED	10009
+#define		ST_MAINTMODE	10010
+#define		ST_STALEACL	10011
+
+/*
+ *	On writes how does the client want the data written.
+ */
+
+#define	CACHE_CSTABLE		1
+#define CACHE_UNSTABLE		2
+
+/*
+ *	Lets the client know at which level the data was commited on
+ *	a write request
+ */
+
+#define	CMFILE_SYNCH_NVRAM	1
+#define	CMDATA_SYNCH_NVRAM	2
+#define	CMFILE_SYNCH		3
+#define CMDATA_SYNCH		4
+#define CMUNSTABLE		5
+
+struct aac_read
+{
+	u32	 	command;
+	u32 		cid;
+	u32 		block;
+	u32 		count;
+	struct sgmap	sg;	// Must be last in struct because it is variable
+};
+
+struct aac_read_reply
+{
+	u32	 	status;
+	u32 		count;
+};
+
+struct aac_write
+{
+	u32		command;
+	u32 		cid;
+	u32 		block;
+	u32 		count;
+	u32	 	stable;
+	struct sgmap	sg;	// Must be last in struct because it is variable
+};
+
+struct aac_write_reply
+{
+	u32		status;
+	u32 		count;
+	u32		committed;
+};
+
+
+/*
+ * Object-Server / Volume-Manager Dispatch Classes
+ */
+
+#define		VM_Null			0
+#define		VM_NameServe		1
+#define		VM_ContainerConfig	2
+#define		VM_Ioctl		3
+#define		VM_FilesystemIoctl	4
+#define		VM_CloseAll		5
+#define		VM_CtBlockRead		6
+#define		VM_CtBlockWrite		7
+#define		VM_SliceBlockRead	8	/* raw access to configured "storage objects" */
+#define		VM_SliceBlockWrite	9
+#define		VM_DriveBlockRead	10	/* raw access to physical devices */
+#define		VM_DriveBlockWrite	11
+#define		VM_EnclosureMgt		12	/* enclosure management */
+#define		VM_Unused		13	/* used to be diskset management */
+#define		VM_CtBlockVerify	14
+#define		VM_CtPerf		15	/* performance test */
+#define		VM_CtBlockRead64	16
+#define		VM_CtBlockWrite64	17
+#define		VM_CtBlockVerify64	18
+
+#define		MAX_VMCOMMAND_NUM	19	/* used for sizing stats array - leave last */
+
+/*
+ *	Descriptive information (eg, vital stats)
+ *	that a content manager might report.  The
+ *	FileArray filesystem component is one example
+ *	of a content manager.  Raw mode might be
+ *	another.
+ */
+
+struct aac_fsinfo {
+	u32  fsTotalSize;	/* Consumed by fs, incl. metadata */
+	u32  fsBlockSize;
+	u32  fsFragSize;
+	u32  fsMaxExtendSize;
+	u32  fsSpaceUnits;
+	u32  fsMaxNumFiles;
+	u32  fsNumFreeFiles;
+	u32  fsInodeDensity;
+};	/* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+
+union aac_contentinfo {
+	struct aac_fsinfo filesys;	/* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+};
+
+/*
+ *	Query for "mountable" objects, ie, objects that are typically
+ *	associated with a drive letter on the client (host) side.
+ */
+
+struct aac_mntent {
+	u32    			oid;
+	char			name[16];	// if applicable
+	struct creation_info	create_info;	// if applicable
+	u32			capacity;
+	u32			vol;    	// substrate structure
+	u32			obj;	        // FT_FILESYS, FT_DATABASE, etc.
+	u32			state;		// unready for mounting, readonly, etc.
+	union aac_contentinfo	fileinfo;	// Info specific to content manager (eg, filesystem)
+	u32			altoid;		// != oid <==> snapshot or broken mirror exists
+};
+
+#define FSCS_READONLY	0x0002	/*	possible result of broken mirror */
+
+struct aac_query_mount {
+	u32		command;
+	u32		type;
+	u32		count;
+};
+
+struct aac_mount {
+	u32		status;
+	u32	   	type;           /* should be same as that requested */
+	u32		count;
+	struct aac_mntent mnt[1];
+};
+
+/*
+ * The following command is sent to shut down each container.
+ */
+
+struct aac_close {
+	u32	command;
+	u32	cid;
+};
+
+struct aac_query_disk
+{
+	s32	cnum;
+	s32	bus;
+	s32	target;
+	s32	lun;
+	u32	valid;
+	u32	locked;
+	u32	deleted;
+	s32	instance;
+	s8	name[10];
+	u32	unmapped;
+};
+
+struct aac_delete_disk {
+	u32	disknum;
+	u32	cnum;
+};
+
+struct fib_ioctl
+{
+	char	*fibctx;
+	int	wait;
+	char	*fib;
+};
+
+struct revision
+{
+	int compat;
+	unsigned long version;
+	unsigned long build;
+};
+	
+/*
+ * 	Ugly - non Linux like ioctl coding for back compat.
+ */
+
+#define CTL_CODE(function, method) (                 \
+    (4<< 16) | ((function) << 2) | (method) \
+)
+
+/*
+ *	Define the method codes for how buffers are passed for I/O and FS 
+ *	controls
+ */
+
+#define METHOD_BUFFERED                 0
+#define METHOD_NEITHER                  3
+
+/*
+ *	Filesystem ioctls
+ */
+
+#define FSACTL_SENDFIB                  	CTL_CODE(2050, METHOD_BUFFERED)
+#define FSACTL_DELETE_DISK			0x163
+#define FSACTL_QUERY_DISK			0x173
+#define FSACTL_OPEN_GET_ADAPTER_FIB		CTL_CODE(2100, METHOD_BUFFERED)
+#define FSACTL_GET_NEXT_ADAPTER_FIB		CTL_CODE(2101, METHOD_BUFFERED)
+#define FSACTL_CLOSE_GET_ADAPTER_FIB		CTL_CODE(2102, METHOD_BUFFERED)
+#define FSACTL_MINIPORT_REV_CHECK               CTL_CODE(2107, METHOD_BUFFERED)
+#define FSACTL_FORCE_DELETE_DISK		CTL_CODE(2120, METHOD_NEITHER)
+
+struct aac_common
+{
+	/*
+	 *	If this value is set to 1 then interrupt moderation will occur 
+	 *	in the base commuication support.
+	 */
+	unsigned long irq_mod;
+	int peak_fibs;
+	int zero_fibs;
+	unsigned long fib_timeouts;
+	/*
+	 *	Statistical counters in debug mode
+	 */
+#ifdef DBG
+	unsigned long FibsSent;
+	unsigned long FibRecved;
+	unsigned long NoResponseSent;
+	unsigned long NoResponseRecved;
+	unsigned long AsyncSent;
+	unsigned long AsyncRecved;
+	unsigned long NormalSent;
+	unsigned long NormalRecved;
+#endif
+};
+
+extern struct aac_common aac_config;
+
+
+/*
+ *	The following macro is used when sending and receiving FIBs. It is
+ *	only used for debugging.
+ */
+ 
+#if DBG
+#define	FIB_COUNTER_INCREMENT(counter)		(counter)++
+#else
+#define	FIB_COUNTER_INCREMENT(counter)		
+#endif
+
+/*
+ *	Adapter direct commands
+ */
+
+#define	BREAKPOINT_REQUEST		0x00000004
+#define	INIT_STRUCT_BASE_ADDRESS	0x00000005
+#define	SEND_SYNCHRONOUS_FIB		0x0000000c
+
+/*
+ *	Adapter Status Register
+ *
+ *  Phase Staus mailbox is 32bits:
+ *	<31:16> = Phase Status
+ *	<15:0>  = Phase
+ *
+ *	The adapter reports is present state through the phase.  Only
+ *	a single phase should be ever be set.  Each phase can have multiple
+ *	phase status bits to provide more detailed information about the 
+ *	state of the board.  Care should be taken to ensure that any phase 
+ *	status bits that are set when changing the phase are also valid
+ *	for the new phase or be cleared out.  Adapter software (monitor,
+ *	iflash, kernel) is responsible for properly maintining the phase 
+ *	status mailbox when it is running.
+ *											
+ *	MONKER_API Phases							
+ *
+ *	Phases are bit oriented.  It is NOT valid  to have multiple bits set						
+ */					
+
+#define	SELF_TEST_FAILED		cpu_to_le32(0x00000004)
+#define	KERNEL_UP_AND_RUNNING		cpu_to_le32(0x00000080)
+#define	KERNEL_PANIC			cpu_to_le32(0x00000100)
+
+/*
+ *	Doorbell bit defines
+ */
+
+#define DoorBellPrintfDone		cpu_to_le32(1<<5)	// Host -> Adapter
+#define DoorBellAdapterNormCmdReady	cpu_to_le32(1<<1)	// Adapter -> Host
+#define DoorBellAdapterNormRespReady	cpu_to_le32(1<<2)	// Adapter -> Host
+#define DoorBellAdapterNormCmdNotFull	cpu_to_le32(1<<3)	// Adapter -> Host
+#define DoorBellAdapterNormRespNotFull	cpu_to_le32(1<<4)	// Adapter -> Host
+#define DoorBellPrintfReady		cpu_to_le32(1<<5)	// Adapter -> Host
+
+/*
+ *	For FIB communication, we need all of the following things
+ *	to send back to the user.
+ */
+ 
+#define 	AifCmdEventNotify	1	/* Notify of event */
+#define		AifCmdJobProgress	2	/* Progress report */
+#define		AifCmdAPIReport		3	/* Report from other user of API */
+#define		AifCmdDriverNotify	4	/* Notify host driver of event */
+#define		AifReqJobList		100	/* Gets back complete job list */
+#define		AifReqJobsForCtr	101	/* Gets back jobs for specific container */
+#define		AifReqJobsForScsi	102	/* Gets back jobs for specific SCSI device */ 
+#define		AifReqJobReport		103	/* Gets back a specific job report or list of them */ 
+#define		AifReqTerminateJob	104	/* Terminates job */
+#define		AifReqSuspendJob	105	/* Suspends a job */
+#define		AifReqResumeJob		106	/* Resumes a job */ 
+#define		AifReqSendAPIReport	107	/* API generic report requests */
+#define		AifReqAPIJobStart	108	/* Start a job from the API */
+#define		AifReqAPIJobUpdate	109	/* Update a job report from the API */
+#define		AifReqAPIJobFinish	110	/* Finish a job from the API */
+
+/*
+ *	Adapter Initiated FIB command structures. Start with the adapter
+ *	initiated FIBs that really come from the adapter, and get responded
+ *	to by the host.
+ */
+
+struct aac_aifcmd {
+	u32 command;		/* Tell host what type of notify this is */
+	u32 seqnum;		/* To allow ordering of reports (if necessary) */
+	u8 data[1];		/* Undefined length (from kernel viewpoint) */
+};
+
+/*
+ *	Adapter Information Block
+ *
+ *	This is returned by the RequestAdapterInfo block
+ */
+ 
+struct aac_adapter_info
+{
+	u32	platform;
+	u32	cpu;
+	u32	subcpu;
+	u32	clock;
+	u32	execmem;
+	u32	buffermem;
+	u32	totalmem;
+	u32	kernelrev;
+	u32	kernelbuild;
+	u32	monitorrev;
+	u32	monitorbuild;
+	u32	hwrev;
+	u32	hwbuild;
+	u32	biosrev;
+	u32	biosbuild;
+	u32	clustering;
+	u32	clustermask;
+	u64	serial;
+	u32	battery;
+	u32	options;
+	u32	OEM;
+};
+	
+const char *aac_driverinfo(struct Scsi_Host *);
+struct fib *fib_alloc(struct aac_dev *dev);
+int fib_setup(struct aac_dev *dev);
+void fib_map_free(struct aac_dev *dev);
+void fib_free(struct fib * context);
+void fib_init(struct fib * context);
+void fib_dealloc(struct fib * context);
+void aac_printf(struct aac_dev *dev, u32 val);
+int fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt);
+int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry);
+int aac_consumer_avail(struct aac_dev * dev, struct aac_queue * q);
+void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
+int fib_complete(struct fib * context);
+#define fib_data(fibctx) ((void *)(fibctx)->fib->data)
+int aac_detach(struct aac_dev *dev);
+struct aac_dev *aac_init_adapter(struct aac_dev *dev);
+int aac_get_containers(struct aac_dev *dev);
+int aac_scsi_cmd(Scsi_Cmnd *scsi_cmnd_ptr);
+int aac_dev_ioctl(struct aac_dev *dev, int cmd, void *arg);
+int aac_do_ioctl(struct aac_dev * dev, int cmd, void *arg);
+int aac_rx_init(struct aac_dev *dev, unsigned long devNumber);
+int aac_sa_init(struct aac_dev *dev, unsigned long devNumber);
+unsigned int aac_response_normal(struct aac_queue * q);
+unsigned int aac_command_normal(struct aac_queue * q);
+int aac_command_thread(struct aac_dev * dev);
+int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
+int fib_adapter_complete(struct fib * fibptr, unsigned short size);
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
--- linux-2.4.17-pre6/drivers/scsi/aacraid/commctrl.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/commctrl.c	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,410 @@
+/*
+ *	Adaptec AAC series RAID controller driver
+ *	(c) Copyright 2001 Red Hat Inc.	<alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ *
+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Module Name:
+ *  commctrl.c
+ *
+ * Abstract: Contains all routines for control of the AFA comm layer
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/completion.h>
+#include <linux/blk.h>
+#include <asm/semaphore.h>
+#include <asm/uaccess.h>
+#include "scsi.h"
+#include "hosts.h"
+
+#include "aacraid.h"
+
+/**
+ *	ioctl_send_fib	-	send a FIB from userspace
+ *	@dev:	adapter is being processed
+ *	@arg:	arguments to the ioctl call
+ *	
+ *	This routine sends a fib to the adapter on behalf of a user level
+ *	program.
+ */
+ 
+static int ioctl_send_fib(struct aac_dev * dev, void *arg)
+{
+	struct hw_fib * kfib;
+	struct fib *fibptr;
+
+	fibptr = fib_alloc(dev);
+	if(fibptr == NULL)
+		return -ENOMEM;
+		
+	kfib = fibptr->fib;
+	/*
+	 *	First copy in the header so that we can check the size field.
+	 */
+	if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) {
+		fib_free(fibptr);
+		return -EFAULT;
+	}
+	/*
+	 *	Since we copy based on the fib header size, make sure that we
+	 *	will not overrun the buffer when we copy the memory. Return
+	 *	an error if we would.
+	 */
+	if(le32_to_cpu(kfib->header.Size) > sizeof(struct hw_fib) - sizeof(struct aac_fibhdr)) {
+		fib_free(fibptr);
+		return -EINVAL;
+	}
+
+	if (copy_from_user((void *) kfib, arg, le32_to_cpu(kfib->header.Size) + sizeof(struct aac_fibhdr))) {
+		fib_free(fibptr);
+		return -EFAULT;
+	}
+
+	if (kfib->header.Command == cpu_to_le32(TakeABreakPt)) {
+		aac_adapter_interrupt(dev);
+		/*
+		 * Since we didn't really send a fib, zero out the state to allow 
+		 * cleanup code not to assert.
+		 */
+		kfib->header.XferState = 0;
+	} else {
+		if (fib_send(kfib->header.Command, fibptr, le32_to_cpu(kfib->header.Size) , FsaNormal,
+			1, 1, NULL, NULL) != 0) 
+		{
+			fib_free(fibptr);
+			return -EINVAL;
+		}
+		if (fib_complete(fibptr) != 0) {
+			fib_free(fibptr);
+			return -EINVAL;
+		}
+	}
+	/*
+	 *	Make sure that the size returned by the adapter (which includes
+	 *	the header) is less than or equal to the size of a fib, so we
+	 *	don't corrupt application data. Then copy that size to the user
+	 *	buffer. (Don't try to add the header information again, since it
+	 *	was already included by the adapter.)
+	 */
+
+	if (copy_to_user(arg, (void *)kfib, kfib->header.Size)) {
+		fib_free(fibptr);
+		return -EFAULT;
+	}
+	fib_free(fibptr);
+	return 0;
+}
+
+/**
+ *	open_getadapter_fib	-	Get the next fib
+ *
+ *	This routine will get the next Fib, if available, from the AdapterFibContext
+ *	passed in from the user.
+ */
+
+static int open_getadapter_fib(struct aac_dev * dev, void *arg)
+{
+	struct aac_fib_context * fibctx;
+	int status;
+	unsigned long flags;
+
+	fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL);
+	if (fibctx == NULL) {
+		status = -ENOMEM;
+	} else {
+		fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
+		fibctx->size = sizeof(struct aac_fib_context);
+		/*
+		 *	Initialize the mutex used to wait for the next AIF.
+		 */
+		init_MUTEX_LOCKED(&fibctx->wait_sem);
+		fibctx->wait = 0;
+		/*
+		 *	Initialize the fibs and set the count of fibs on
+		 *	the list to 0.
+		 */
+		fibctx->count = 0;
+		INIT_LIST_HEAD(&fibctx->fibs);
+		fibctx->jiffies = jiffies/HZ;
+		/*
+		 *	Now add this context onto the adapter's 
+		 *	AdapterFibContext list.
+		 */
+		spin_lock_irqsave(&dev->fib_lock, flags);
+		list_add_tail(&fibctx->next, &dev->fib_list);
+		spin_unlock_irqrestore(&dev->fib_lock, flags);
+		if (copy_to_user(arg,  &fibctx, sizeof(struct aac_fib_context *))) {
+			status = -EFAULT;
+		} else {
+			status = 0;
+		}	
+	}
+	return status;
+}
+
+/**
+ *	next_getadapter_fib	-	get the next fib
+ *	@dev: adapter to use
+ *	@arg: ioctl argument
+ *	
+ * 	This routine will get the next Fib, if available, from the AdapterFibContext
+ *	passed in from the user.
+ */
+
+static int next_getadapter_fib(struct aac_dev * dev, void *arg)
+{
+	struct fib_ioctl f;
+	struct aac_fib_context *fibctx, *aifcp;
+	struct hw_fib * fib;
+	int status;
+	struct list_head * entry;
+	int found;
+	unsigned long flags;
+	
+	if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
+		return -EFAULT;
+	/*
+	 *	Extract the AdapterFibContext from the Input parameters.
+	 */
+	fibctx = (struct aac_fib_context *) f.fibctx;
+
+	/*
+	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
+	 *
+	 *	Search the list of AdapterFibContext addresses on the adapter
+	 *	to be sure this is a valid address
+	 */
+	found = 0;
+	entry = dev->fib_list.next;
+
+	while(entry != &dev->fib_list) {
+		aifcp = list_entry(entry, struct aac_fib_context, next);
+		if(fibctx == aifcp) {   /* We found a winner */
+			found = 1;
+			break;
+		}
+		entry = entry->next;
+	}
+	if (found == 0)
+		return -EINVAL;
+
+	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
+		 (fibctx->size != sizeof(struct aac_fib_context)))
+		return -EINVAL;
+	status = 0;
+	spin_lock_irqsave(&dev->fib_lock, flags);
+	/*
+	 *	If there are no fibs to send back, then either wait or return
+	 *	-EAGAIN
+	 */
+return_fib:
+	if (!list_empty(&fibctx->fibs)) {
+		struct list_head * entry;
+		/*
+		 *	Pull the next fib from the fibs
+		 */
+		entry = fibctx->fibs.next;
+		list_del(entry);
+		
+		fib = list_entry(entry, struct hw_fib, header.FibLinks);
+		fibctx->count--;
+		spin_unlock_irqrestore(&dev->fib_lock, flags);
+		if (copy_to_user(f.fib, fib, sizeof(struct hw_fib))) {
+			kfree(fib);
+			return -EFAULT;
+		}	
+		/*
+		 *	Free the space occupied by this copy of the fib.
+		 */
+		kfree(fib);
+		status = 0;
+		fibctx->jiffies = jiffies/HZ;
+	} else {
+		spin_unlock_irqrestore(&dev->fib_lock, flags);
+		if (f.wait) {
+			if(down_interruptible(&fibctx->wait_sem) < 0) {
+				status = -EINTR;
+			} else {
+				/* Lock again and retry */
+				spin_lock_irqsave(&dev->fib_lock, flags);
+				goto return_fib;
+			}
+		} else {
+			status = -EAGAIN;
+		}	
+	}
+	return status;
+}
+
+int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
+{
+	struct hw_fib *fib;
+
+	/*
+	 *	First free any FIBs that have not been consumed.
+	 */
+	while (!list_empty(&fibctx->fibs)) {
+		struct list_head * entry;
+		/*
+		 *	Pull the next fib from the fibs
+		 */
+		entry = fibctx->fibs.next;
+		list_del(entry);
+		fib = list_entry(entry, struct hw_fib, header.FibLinks);
+		fibctx->count--;
+		/*
+		 *	Free the space occupied by this copy of the fib.
+		 */
+		kfree(fib);
+	}
+	/*
+	 *	Remove the Context from the AdapterFibContext List
+	 */
+	list_del(&fibctx->next);
+	/*
+	 *	Invalidate context
+	 */
+	fibctx->type = 0;
+	/*
+	 *	Free the space occupied by the Context
+	 */
+	kfree(fibctx);
+	return 0;
+}
+
+/**
+ *	close_getadapter_fib	-	close down user fib context
+ *	@dev: adapter
+ *	@arg: ioctl arguments
+ *
+ *	This routine will close down the fibctx passed in from the user.
+ */
+ 
+static int close_getadapter_fib(struct aac_dev * dev, void *arg)
+{
+	struct aac_fib_context *fibctx, *aifcp;
+	int status;
+	unsigned long flags;
+	struct list_head * entry;
+	int found;
+
+	/*
+	 *	Extract the fibctx from the input parameters
+	 */
+	fibctx = arg;
+
+	/*
+	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
+	 *
+	 *	Search the list of AdapterFibContext addresses on the adapter
+	 *	to be sure this is a valid address
+	 */
+
+	found = 0;
+	entry = dev->fib_list.next;
+
+	while(entry != &dev->fib_list) {
+		aifcp = list_entry(entry, struct aac_fib_context, next);
+		if(fibctx == aifcp) {   /* We found a winner */
+			found = 1;
+			break;
+		}
+		entry = entry->next;
+	}
+
+	if(found == 0)
+		return 0; /* Already gone */
+
+	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
+		 (fibctx->size != sizeof(struct aac_fib_context)))
+		return -EINVAL;
+	spin_lock_irqsave(&dev->fib_lock, flags);
+	status = aac_close_fib_context(dev, fibctx);
+	spin_unlock_irqrestore(&dev->fib_lock, flags);
+	return status;
+}
+
+/**
+ *	check_revision	-	close down user fib context
+ *	@dev: adapter
+ *	@arg: ioctl arguments
+ *
+ *	This routine returns the firmware version.
+ *      Under Linux, there have been no version incompatibilities, so this is simple!
+ */
+
+static int check_revision(struct aac_dev *dev, void *arg)
+{
+	struct revision response;
+
+	response.compat = 1;
+	response.version = 0x03000400;
+	response.build = 0x5125;
+
+	if (copy_to_user(arg, &response, sizeof(response)))
+		return -EFAULT;
+	return 0;
+}
+
+
+int aac_do_ioctl(struct aac_dev * dev, int cmd, void *arg)
+{
+	int status;
+	
+	/*
+	 *	HBA gets first crack
+	 */
+	 
+	status = aac_dev_ioctl(dev, cmd, arg);
+	if(status != -ENOTTY)
+		return status;
+
+	switch (cmd) {
+	case FSACTL_MINIPORT_REV_CHECK:
+		status = check_revision(dev, arg);
+		break;
+	case FSACTL_SENDFIB:
+		status = ioctl_send_fib(dev, arg);
+		break;
+	case FSACTL_OPEN_GET_ADAPTER_FIB:
+		status = open_getadapter_fib(dev, arg);
+		break;
+	case FSACTL_GET_NEXT_ADAPTER_FIB:
+		status = next_getadapter_fib(dev, arg);
+		break;
+	case FSACTL_CLOSE_GET_ADAPTER_FIB:
+		status = close_getadapter_fib(dev, arg);
+		break;
+	default:
+		status = -ENOTTY;
+	  	break;	
+	}
+	return status;
+}
+
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
--- linux-2.4.17-pre6/drivers/scsi/aacraid/comminit.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/comminit.c	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,332 @@
+/*
+ *	Adaptec AAC series RAID controller driver
+ *	(c) Copyright 2001 Red Hat Inc.	<alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ *
+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Module Name:
+ *  comminit.c
+ *
+ * Abstract: This supports the initialization of the host adapter commuication interface.
+ *    This is a platform dependent module for the pci cyclone board.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/blk.h>
+#include <asm/semaphore.h>
+#include "scsi.h"
+#include "hosts.h"
+
+#include "aacraid.h"
+
+struct aac_common aac_config;
+
+static struct aac_dev *devices;
+
+static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
+{
+	unsigned char *base;
+	unsigned long size, align;
+	unsigned long fibsize = 4096;
+	unsigned long printfbufsiz = 256;
+	struct aac_init *init;
+	dma_addr_t phys;
+
+	size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz;
+
+	base = pci_alloc_consistent(dev->pdev, size, &phys);
+	if(base == NULL)
+	{
+		printk(KERN_ERR "aacraid: unable to create mapping.\n");
+		return 0;
+	}
+	dev->comm_addr  = (void *)base;
+	dev->comm_phys = phys;
+	dev->comm_size     = size;
+
+	dev->init = (struct aac_init *)(base + fibsize);
+	dev->init_pa = (struct aac_init *)(phys + fibsize);
+
+	init = dev->init;
+
+	init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
+	init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION);
+	init->fsrev = cpu_to_le32(dev->fsrev);
+
+	/*
+	 *	Adapter Fibs are the first thing allocated so that they
+	 *	start page aligned
+	 */
+	init->AdapterFibsVirtualAddress = cpu_to_le32(base);
+	init->AdapterFibsPhysicalAddress = cpu_to_le32(phys);
+	init->AdapterFibsSize = cpu_to_le32(fibsize);
+	init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
+
+	/*
+	 * Increment the base address by the amount already used
+	 */
+	base = base + fibsize + sizeof(struct aac_init);
+	phys = phys + fibsize + sizeof(struct aac_init);
+	/*
+	 *	Align the beginning of Headers to commalign
+	 */
+	align = (commalign - ((unsigned long)(base) & (commalign - 1)));
+	base = base + align;
+	phys = phys + align;
+	/*
+	 *	Fill in addresses of the Comm Area Headers and Queues
+	 */
+	*commaddr = (unsigned long *)base;
+	init->CommHeaderAddress = cpu_to_le32(phys);
+	/*
+	 *	Increment the base address by the size of the CommArea
+	 */
+	base = base + commsize;
+	phys = phys + commsize;
+	/*
+	 *	 Place the Printf buffer area after the Fast I/O comm area.
+	 */
+	dev->printfbuf = (void *)base;
+	init->printfbuf = cpu_to_le32(phys);
+	init->printfbufsiz = cpu_to_le32(printfbufsiz);
+	memset(base, 0, printfbufsiz);
+	return 1;
+}
+    
+static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, int qsize)
+{
+	q->numpending = 0;
+	q->dev = dev;
+	INIT_LIST_HEAD(&q->pendingq);
+	init_waitqueue_head(&q->cmdready);
+	INIT_LIST_HEAD(&q->cmdq);
+	init_waitqueue_head(&q->qfull);
+	spin_lock_init(&q->lockdata);
+	q->lock = &q->lockdata;
+	q->headers.producer = mem;
+	q->headers.consumer = mem+1;
+	*q->headers.producer = cpu_to_le32(qsize);
+	*q->headers.consumer = cpu_to_le32(qsize);
+	q->entries = qsize;
+}
+
+/**
+ *	aac_send_shutdown		-	shutdown an adapter
+ *	@dev: Adapter to shutdown
+ *
+ *	This routine will send a VM_CloseAll (shutdown) request to the adapter.
+ */
+
+static int aac_send_shutdown(struct aac_dev * dev)
+{
+	struct fib * fibctx;
+	struct aac_close *cmd;
+	int status;
+
+	fibctx = fib_alloc(dev);
+	fib_init(fibctx);
+
+	cmd = (struct aac_close *) fib_data(fibctx);
+
+	cmd->command = cpu_to_le32(VM_CloseAll);
+	cmd->cid = cpu_to_le32(0xffffffff);
+
+	status = fib_send(ContainerCommand,
+			  fibctx,
+			  sizeof(struct aac_close),
+			  FsaNormal,
+			  1, 1,
+			  NULL, NULL);
+
+	if (status == 0)
+		fib_complete(fibctx);
+	fib_free(fibctx);
+	return status;
+}
+
+/**
+ *	aac_detach	-	detach adapter
+ *	@detach: adapter to disconnect
+ *
+ *	Disconnect and shutdown an AAC based adapter, freeing resources
+ *	as we go.
+ */
+
+int aac_detach(struct aac_dev *detach)
+{
+	struct aac_dev **dev = &devices;
+	
+	while(*dev)
+	{
+		if(*dev == detach)
+		{
+			*dev = detach->next;
+			aac_send_shutdown(detach);
+			fib_map_free(detach);
+			pci_free_consistent(detach->pdev, detach->comm_size, detach->comm_addr, detach->comm_phys);
+			kfree(detach->queues);
+			return 1;
+		}
+		dev=&((*dev)->next);
+	}
+	BUG();
+	return 0;
+}
+
+/**
+ *	aac_comm_init	-	Initialise FSA data structures
+ *	@dev:	Adapter to intialise
+ *
+ *	Initializes the data structures that are required for the FSA commuication
+ *	interface to operate. 
+ *	Returns
+ *		1 - if we were able to init the commuication interface.
+ *		0 - If there were errors initing. This is a fatal error.
+ */
+ 
+int aac_comm_init(struct aac_dev * dev)
+{
+	unsigned long hdrsize = (sizeof(u32) * NUMBER_OF_COMM_QUEUES) * 2;
+	unsigned long queuesize = sizeof(struct aac_entry) * TOTAL_QUEUE_ENTRIES;
+	u32 *headers;
+	struct aac_entry * queues;
+	unsigned long size;
+	struct aac_queue_block * comm = dev->queues;
+
+	/*
+	 *	Now allocate and initialize the zone structures used as our 
+	 *	pool of FIB context records.  The size of the zone is based
+	 *	on the system memory size.  We also initialize the mutex used
+	 *	to protect the zone.
+	 */
+	spin_lock_init(&dev->fib_lock);
+
+	/*
+	 *	Allocate the physically contigous space for the commuication
+	 *	queue headers. 
+	 */
+
+	size = hdrsize + queuesize;
+
+	if (!aac_alloc_comm(dev, (void * *)&headers, size, QUEUE_ALIGNMENT))
+		return -ENOMEM;
+
+	queues = (struct aac_entry *)((unsigned char *)headers + hdrsize);
+
+	/* Adapter to Host normal priority Command queue */ 
+	comm->queue[HostNormCmdQueue].base = queues;
+	aac_queue_init(dev, &comm->queue[HostNormCmdQueue], headers, HOST_NORM_CMD_ENTRIES);
+	queues += HOST_NORM_CMD_ENTRIES;
+	headers += 2;
+
+	/* Adapter to Host high priority command queue */
+	comm->queue[HostHighCmdQueue].base = queues;
+	aac_queue_init(dev, &comm->queue[HostHighCmdQueue], headers, HOST_HIGH_CMD_ENTRIES);
+    
+	queues += HOST_HIGH_CMD_ENTRIES;
+	headers +=2;
+
+	/* Host to adapter normal priority command queue */
+	comm->queue[AdapNormCmdQueue].base = queues;
+	aac_queue_init(dev, &comm->queue[AdapNormCmdQueue], headers, ADAP_NORM_CMD_ENTRIES);
+    
+	queues += ADAP_NORM_CMD_ENTRIES;
+	headers += 2;
+
+	/* host to adapter high priority command queue */
+	comm->queue[AdapHighCmdQueue].base = queues;
+	aac_queue_init(dev, &comm->queue[AdapHighCmdQueue], headers, ADAP_HIGH_CMD_ENTRIES);
+    
+	queues += ADAP_HIGH_CMD_ENTRIES;
+	headers += 2;
+
+	/* adapter to host normal priority response queue */
+	comm->queue[HostNormRespQueue].base = queues;
+	aac_queue_init(dev, &comm->queue[HostNormRespQueue], headers, HOST_NORM_RESP_ENTRIES);
+    
+	queues += HOST_NORM_RESP_ENTRIES;
+	headers += 2;
+
+	/* adapter to host high priority response queue */
+	comm->queue[HostHighRespQueue].base = queues;
+	aac_queue_init(dev, &comm->queue[HostHighRespQueue], headers, HOST_HIGH_RESP_ENTRIES);
+   
+	queues += HOST_HIGH_RESP_ENTRIES;
+	headers += 2;
+
+	/* host to adapter normal priority response queue */
+	comm->queue[AdapNormRespQueue].base = queues;
+	aac_queue_init(dev, &comm->queue[AdapNormRespQueue], headers, ADAP_NORM_RESP_ENTRIES);
+
+	queues += ADAP_NORM_RESP_ENTRIES;
+	headers += 2;
+	
+	/* host to adapter high priority response queue */ 
+	comm->queue[AdapHighRespQueue].base = queues;
+	aac_queue_init(dev, &comm->queue[AdapHighRespQueue], headers, ADAP_HIGH_RESP_ENTRIES);
+
+	comm->queue[AdapNormCmdQueue].lock = comm->queue[HostNormRespQueue].lock;
+	comm->queue[AdapHighCmdQueue].lock = comm->queue[HostHighRespQueue].lock;
+	comm->queue[AdapNormRespQueue].lock = comm->queue[HostNormCmdQueue].lock;
+	comm->queue[AdapHighRespQueue].lock = comm->queue[HostHighCmdQueue].lock;
+
+	return 0;
+}
+
+struct aac_dev *aac_init_adapter(struct aac_dev *dev)
+{
+	/*
+	 *	Ok now init the communication subsystem
+	 */
+	dev->queues = (struct aac_queue_block *) kmalloc(sizeof(struct aac_queue_block), GFP_KERNEL);
+	if (dev->queues == NULL) {
+		printk(KERN_ERR "Error could not allocate comm region.\n");
+		return NULL;
+	}
+	memset(dev->queues, 0, sizeof(struct aac_queue_block));
+
+	if (aac_comm_init(dev)<0)
+		return NULL;
+	/*
+	 *	Initialize the list of fibs
+	 */
+	if(fib_setup(dev)<0)
+		return NULL;
+		
+	INIT_LIST_HEAD(&dev->fib_list);
+	spin_lock_init(&dev->fib_lock);
+	init_completion(&dev->aif_completion);
+	/*
+	 *	Add this adapter in to our dev List.
+	 */
+	dev->next = devices;
+	devices = dev;
+	return dev;
+}
+
+    
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
--- linux-2.4.17-pre6/drivers/scsi/aacraid/commsup.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/commsup.c	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,944 @@
+/*
+ *	Adaptec AAC series RAID controller driver
+ *	(c) Copyright 2001 Red Hat Inc.	<alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+
+ * Adaptec aacraid device driver for Linux.
+ *
+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Module Name:
+ *  commsup.c
+ *
+ * Abstract: Contain all routines that are required for FSA host/adapter
+ *    commuication.
+ *
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/completion.h>
+#include <asm/semaphore.h>
+#include <linux/blk.h>
+#include "scsi.h"
+#include "hosts.h"
+
+#include "aacraid.h"
+
+/**
+ *	fib_map_alloc		-	allocate the fib objects
+ *	@dev: Adapter to allocate for
+ *
+ *	Allocate and map the shared PCI space for the FIB blocks used to
+ *	talk to the Adaptec firmware.
+ */
+ 
+static int fib_map_alloc(struct aac_dev *dev)
+{
+	if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, &dev->hw_fib_pa))==NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+/**
+ *	fib_map_free		-	free the fib objects
+ *	@dev: Adapter to free
+ *
+ *	Free the PCI mappings and the memory allocated for FIB blocks
+ *	on this adapter.
+ */
+
+void fib_map_free(struct aac_dev *dev)
+{
+	pci_free_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, dev->hw_fib_va, dev->hw_fib_pa);
+}
+
+/**
+ *	fib_setup	-	setup the fibs
+ *	@dev: Adapter to set up
+ *
+ *	Allocate the PCI space for the fibs, map it and then intialise the
+ *	fib area, the unmapped fib data and also the free list
+ */
+
+int fib_setup(struct aac_dev * dev)
+{
+	struct fib *fibptr;
+	struct hw_fib *fib;
+	dma_addr_t fibpa;
+	int i;
+	
+	if(fib_map_alloc(dev)<0)
+		return -ENOMEM;
+		
+	fib = dev->hw_fib_va;
+	fibpa = dev->hw_fib_pa;
+	memset(fib, 0, sizeof(struct hw_fib) * AAC_NUM_FIB);
+	/*
+	 *	Initialise the fibs
+	 */
+	for (i = 0, fibptr = &dev->fibs[i]; i < AAC_NUM_FIB; i++, fibptr++) 
+	{
+		fibptr->dev = dev;
+		fibptr->fib = fib;
+		fibptr->data = (void *) fibptr->fib->data;
+		fibptr->next = fibptr+1;	/* Forward chain the fibs */
+		init_MUTEX_LOCKED(&fibptr->event_wait);
+		spin_lock_init(&fibptr->event_lock);
+		fib->header.XferState = cpu_to_le32(0xffffffff);
+		fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
+		fibptr->logicaladdr = (unsigned long) fibpa;
+		fib = (struct hw_fib *)((unsigned char *)fib + sizeof(struct hw_fib));
+		fibpa = fibpa + sizeof(struct hw_fib);
+	}
+	/*
+	 *	Add the fib chain to the free list
+	 */
+	dev->fibs[AAC_NUM_FIB-1].next = NULL;
+	/*
+	 *	Enable this to debug out of queue space
+	 */
+	dev->free_fib = &dev->fibs[0];
+	return 0;
+}
+
+/**
+ *	fib_alloc	-	allocate a fib
+ *	@dev: Adapter to allocate the fib for
+ *
+ *	Allocate a fib from the adapter fib pool. If the pool is empty we
+ *	wait for fibs to become free.
+ */
+ 
+struct fib * fib_alloc(struct aac_dev *dev)
+{
+	struct fib * fibptr;
+	unsigned long flags;
+	
+	spin_lock_irqsave(&dev->fib_lock, flags);
+	fibptr = dev->free_fib;	
+	if(!fibptr)
+		BUG();
+	dev->free_fib = fibptr->next;
+	spin_unlock_irqrestore(&dev->fib_lock, flags);
+	/*
+	 *	Set the proper node type code and node byte size
+	 */
+	fibptr->type = FSAFS_NTC_FIB_CONTEXT;
+	fibptr->size = sizeof(struct fib);
+	/*
+	 *	Null out fields that depend on being zero at the start of
+	 *	each I/O
+	 */
+	fibptr->fib->header.XferState = cpu_to_le32(0);
+	fibptr->callback = NULL;
+	fibptr->callback_data = NULL;
+
+	return fibptr;
+}
+
+/**
+ *	fib_free	-	free a fib
+ *	@fibptr: fib to free up
+ *
+ *	Frees up a fib and places it on the appropriate queue
+ *	(either free or timed out)
+ */
+ 
+void fib_free(struct fib * fibptr)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
+
+	if (fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
+		aac_config.fib_timeouts++;
+		fibptr->next = fibptr->dev->timeout_fib;
+		fibptr->dev->timeout_fib = fibptr;
+	} else {
+		if (fibptr->fib->header.XferState != 0) {
+			printk(KERN_WARNING "fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", 
+					 fibptr, fibptr->fib->header.XferState);
+		}
+		fibptr->next = fibptr->dev->free_fib;
+		fibptr->dev->free_fib = fibptr;
+	}	
+	spin_unlock_irqrestore(&fibptr->dev->fib_lock, flags);
+}
+
+/**
+ *	fib_init	-	initialise a fib
+ *	@fibptr: The fib to initialize
+ *	
+ *	Set up the generic fib fields ready for use
+ */
+ 
+void fib_init(struct fib *fibptr)
+{
+	struct hw_fib *fib = fibptr->fib;
+
+	fib->header.StructType = FIB_MAGIC;
+	fib->header.Size = cpu_to_le16(sizeof(struct hw_fib));
+        fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
+	fib->header.SenderFibAddress = cpu_to_le32(0);
+	fib->header.ReceiverFibAddress = cpu_to_le32(0);
+	fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
+}
+
+/**
+ *	fib_deallocate		-	deallocate a fib
+ *	@fibptr: fib to deallocate
+ *
+ *	Will deallocate and return to the free pool the FIB pointed to by the
+ *	caller.
+ */
+ 
+void fib_dealloc(struct fib * fibptr)
+{
+	struct hw_fib *fib = fibptr->fib;
+	if(fib->header.StructType != FIB_MAGIC) 
+		BUG();
+	fib->header.XferState = cpu_to_le32(0);        
+}
+
+/*
+ *	Commuication primitives define and support the queuing method we use to
+ *	support host to adapter commuication. All queue accesses happen through
+ *	these routines and are the only routines which have a knowledge of the
+ *	 how these queues are implemented.
+ */
+ 
+/**
+ *	aac_get_entry		-	get a queue entry
+ *	@dev: Adapter
+ *	@qid: Queue Number
+ *	@entry: Entry return
+ *	@index: Index return
+ *	@nonotify: notification control
+ *
+ *	With a priority the routine returns a queue entry if the queue has free entries. If the queue
+ *	is full(no free entries) than no entry is returned and the function returns 0 otherwise 1 is
+ *	returned.
+ */
+ 
+static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entry, u32 * index, unsigned long *nonotify)
+{
+	struct aac_queue * q;
+
+	/*
+	 *	All of the queues wrap when they reach the end, so we check
+	 *	to see if they have reached the end and if they have we just
+	 *	set the index back to zero. This is a wrap. You could or off
+	 *	the high bits in all updates but this is a bit faster I think.
+	 */
+
+	q = &dev->queues->queue[qid];
+	
+	*index = le32_to_cpu(*(q->headers.producer));
+		if (*index - 2 == le32_to_cpu(*(q->headers.consumer)))
+			*nonotify = 1; 
+
+	if (qid == AdapHighCmdQueue) {
+	        if (*index >= ADAP_HIGH_CMD_ENTRIES)
+        		*index = 0;
+	} else if (qid == AdapNormCmdQueue) {
+	        if (*index >= ADAP_NORM_CMD_ENTRIES) 
+			*index = 0; /* Wrap to front of the Producer Queue. */
+	}
+	else if (qid == AdapHighRespQueue) 
+	{
+	        if (*index >= ADAP_HIGH_RESP_ENTRIES)
+			*index = 0;
+	}
+	else if (qid == AdapNormRespQueue) 
+	{
+		if (*index >= ADAP_NORM_RESP_ENTRIES) 
+			*index = 0; /* Wrap to front of the Producer Queue. */
+	}
+	else BUG();
+
+        if (*index + 1 == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */
+		printk(KERN_WARNING "Queue %d full, %ld outstanding.\n",
+				qid, q->numpending);
+		return 0;
+	} else {
+	        *entry = q->base + *index;
+		return 1;
+	}
+}   
+
+/**
+ *	aac_queue_get		-	get the next free QE
+ *	@dev: Adapter
+ *	@index: Returned index
+ *	@priority: Priority of fib
+ *	@fib: Fib to associate with the queue entry
+ *	@wait: Wait if queue full
+ *	@fibptr: Driver fib object to go with fib
+ *	@nonotify: Don't notify the adapter
+ *
+ *	Gets the next free QE off the requested priorty adapter command
+ *	queue and associates the Fib with the QE. The QE represented by
+ *	index is ready to insert on the queue when this routine returns
+ *	success.
+ */
+
+static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * fib, int wait, struct fib * fibptr, unsigned long *nonotify)
+{
+	struct aac_entry * entry = NULL;
+	int map = 0;
+	struct aac_queue * q = &dev->queues->queue[qid];
+		
+	spin_lock_irqsave(q->lock, q->SavedIrql);
+	    
+	if (qid == AdapHighCmdQueue || qid == AdapNormCmdQueue) 
+	{
+		/*  if no entries wait for some if caller wants to */
+        	while (!aac_get_entry(dev, qid, &entry, index, nonotify)) 
+        	{
+			printk(KERN_ERR "GetEntries failed\n");
+		}
+	        /*
+	         *	Setup queue entry with a command, status and fib mapped
+	         */
+	        entry->size = cpu_to_le32(le16_to_cpu(fib->header.Size));
+	        map = 1;
+	}
+	else if (qid == AdapHighRespQueue || qid == AdapNormRespQueue)
+	{
+	        while(!aac_get_entry(dev, qid, &entry, index, nonotify)) 
+	        {
+			/* if no entries wait for some if caller wants to */
+		}
+        	/*
+        	 *	Setup queue entry with command, status and fib mapped
+        	 */
+        	entry->size = cpu_to_le32(le16_to_cpu(fib->header.Size));
+        	entry->addr = cpu_to_le32(fib->header.SenderFibAddress);     			/* Restore adapters pointer to the FIB */
+		fib->header.ReceiverFibAddress = fib->header.SenderFibAddress;		/* Let the adapter now where to find its data */
+        	map = 0;
+	} 
+	/*
+	 *	If MapFib is true than we need to map the Fib and put pointers
+	 *	in the queue entry.
+	 */
+	if (map)
+		entry->addr = cpu_to_le32((unsigned long)(fibptr->logicaladdr));
+	return 0;
+}
+
+
+/**
+ *	aac_insert_entry	-	insert a queue entry
+ *	@dev: Adapter
+ *	@index: Index of entry to insert
+ *	@qid: Queue number
+ *	@nonotify: Suppress adapter notification
+ *
+ *	Gets the next free QE off the requested priorty adapter command
+ *	queue and associates the Fib with the QE. The QE represented by
+ *	index is ready to insert on the queue when this routine returns
+ *	success.
+ */
+ 
+static int aac_insert_entry(struct aac_dev * dev, u32 index, u32 qid, unsigned long nonotify) 
+{
+	struct aac_queue * q = &dev->queues->queue[qid];
+
+	if(q == NULL)
+		BUG();
+	*(q->headers.producer) = cpu_to_le32(index + 1);
+	spin_unlock_irqrestore(q->lock, q->SavedIrql);
+
+	if (qid == AdapHighCmdQueue ||
+	    qid == AdapNormCmdQueue ||
+	    qid == AdapHighRespQueue ||
+	    qid == AdapNormRespQueue)
+	{
+		if (!nonotify)
+			aac_adapter_notify(dev, qid);
+	}
+	else
+		printk("Suprise insert!\n");
+	return 0;
+}
+
+/*
+ *	Define the highest level of host to adapter communication routines. 
+ *	These routines will support host to adapter FS commuication. These 
+ *	routines have no knowledge of the commuication method used. This level
+ *	sends and receives FIBs. This level has no knowledge of how these FIBs
+ *	get passed back and forth.
+ */
+
+/**
+ *	fib_send	-	send a fib to the adapter
+ *	@command: Command to send
+ *	@fibptr: The fib
+ *	@size: Size of fib data area
+ *	@priority: Priority of Fib
+ *	@wait: Async/sync select
+ *	@reply: True if a reply is wanted
+ *	@callback: Called with reply
+ *	@callback_data: Passed to callback
+ *
+ *	Sends the requested FIB to the adapter and optionally will wait for a
+ *	response FIB. If the caller does not wish to wait for a response than
+ *	an event to wait on must be supplied. This event will be set when a
+ *	response FIB is received from the adapter.
+ */
+ 
+int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority, int wait, int reply, fib_callback callback, void * callback_data)
+{
+	u32 index;
+	u32 qid;
+	struct aac_dev * dev = fibptr->dev;
+	unsigned long nointr = 0;
+	struct hw_fib * fib = fibptr->fib;
+	struct aac_queue * q;
+	unsigned long flags = 0;
+
+	if (!(le32_to_cpu(fib->header.XferState) & HostOwned))
+		return -EBUSY;
+	/*
+	 *	There are 5 cases with the wait and reponse requested flags. 
+	 *	The only invalid cases are if the caller requests to wait and
+	 *	does not request a response and if the caller does not want a
+	 *	response and the Fibis not allocated from pool. If a response
+	 *	is not requesed the Fib will just be deallocaed by the DPC
+	 *	routine when the response comes back from the adapter. No
+	 *	further processing will be done besides deleting the Fib. We 
+	 *	will have a debug mode where the adapter can notify the host
+	 *	it had a problem and the host can log that fact.
+	 */
+	if (wait && !reply) {
+		return -EINVAL;
+	} else if (!wait && reply) {
+		fib->header.XferState |= cpu_to_le32(Async | ResponseExpected);
+		FIB_COUNTER_INCREMENT(aac_config.AsyncSent);
+	} else if (!wait && !reply) {
+		fib->header.XferState |= cpu_to_le32(NoResponseExpected);
+		FIB_COUNTER_INCREMENT(aac_config.NoResponseSent);
+	} else if (wait && reply) {
+		fib->header.XferState |= cpu_to_le32(ResponseExpected);
+		FIB_COUNTER_INCREMENT(aac_config.NormalSent);
+	} 
+	fib->header.SenderData = (unsigned long)fibptr;	/* for callback */
+	/*
+	 *	Set FIB state to indicate where it came from and if we want a
+	 *	response from the adapter. Also load the command from the
+	 *	caller.
+	 */
+	fib->header.SenderFibAddress = cpu_to_le32((u32)fib);
+	fib->header.Command = cpu_to_le16(command);
+	fib->header.XferState |= cpu_to_le32(SentFromHost);
+	fibptr->fib->header.Flags = 0;				/* Zero the flags field - its internal only...	 */
+	/*
+	 *	Set the size of the Fib we want to send to the adapter
+	 */
+	fib->header.Size = cpu_to_le16(sizeof(struct aac_fibhdr) + size);
+	if (le16_to_cpu(fib->header.Size) > le16_to_cpu(fib->header.SenderSize)) {
+		return -EMSGSIZE;
+	}                
+	/*
+	 *	Get a queue entry connect the FIB to it and send an notify
+	 *	the adapter a command is ready.
+	 */
+	if (priority == FsaHigh) {
+		fib->header.XferState |= cpu_to_le32(HighPriority);
+		qid = AdapHighCmdQueue;
+	} else {
+		fib->header.XferState |= cpu_to_le32(NormalPriority);
+		qid = AdapNormCmdQueue;
+	}
+	q = &dev->queues->queue[qid];
+
+	if(wait)
+		spin_lock_irqsave(&fibptr->event_lock, flags);
+	if(aac_queue_get( dev, &index, qid, fib, 1, fibptr, &nointr)<0)
+		return -EWOULDBLOCK;
+	dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
+	dprintk((KERN_DEBUG "Fib contents:.\n"));
+	dprintk((KERN_DEBUG "  Command =               %d.\n", fib->header.Command));
+	dprintk((KERN_DEBUG "  XferState  =            %x.\n", fib->header.XferState));
+	/*
+	 *	Fill in the Callback and CallbackContext if we are not
+	 *	going to wait.
+	 */
+	if (!wait) {
+		fibptr->callback = callback;
+		fibptr->callback_data = callback_data;
+	}
+	FIB_COUNTER_INCREMENT(aac_config.FibsSent);
+	list_add_tail(&fibptr->queue, &q->pendingq);
+	q->numpending++;
+
+	fibptr->done = 0;
+
+	if(aac_insert_entry(dev, index, qid, (nointr & aac_config.irq_mod)) < 0)
+		return -EWOULDBLOCK;
+	/*
+	 *	If the caller wanted us to wait for response wait now. 
+	 */
+    
+	if (wait) {
+		spin_unlock_irqrestore(&fibptr->event_lock, flags);
+		down(&fibptr->event_wait);
+		if(fibptr->done == 0)
+			BUG();
+			
+		if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
+			return -ETIMEDOUT;
+		else
+			return 0;
+	}
+	/*
+	 *	If the user does not want a response than return success otherwise
+	 *	return pending
+	 */
+	if (reply)
+		return -EINPROGRESS;
+	else
+		return 0;
+}
+
+/** 
+ *	aac_consumer_get	-	get the top of the queue
+ *	@dev: Adapter
+ *	@q: Queue
+ *	@entry: Return entry
+ *
+ *	Will return a pointer to the entry on the top of the queue requested that
+ * 	we are a consumer of, and return the address of the queue entry. It does
+ *	not change the state of the queue. 
+ */
+
+int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry)
+{
+	u32 index;
+	int status;
+
+	if (*q->headers.producer == *q->headers.consumer) {
+		status = 0;
+	} else {
+		/*
+		 *	The consumer index must be wrapped if we have reached
+		 *	the end of the queue, else we just use the entry
+		 *	pointed to by the header index
+		 */
+		if (le32_to_cpu(*q->headers.consumer) >= q->entries) 
+			index = 0;		
+		else
+		        index = le32_to_cpu(*q->headers.consumer);
+		*entry = q->base + index;
+		status = 1;
+	}
+	return(status);
+}
+
+int aac_consumer_avail(struct aac_dev *dev, struct aac_queue * q)
+{
+	return (*q->headers.producer != *q->headers.consumer);
+}
+
+
+/**
+ *	aac_consumer_free	-	free consumer entry
+ *	@dev: Adapter
+ *	@q: Queue
+ *	@qid: Queue ident
+ *
+ *	Frees up the current top of the queue we are a consumer of. If the
+ *	queue was full notify the producer that the queue is no longer full.
+ */
+
+void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
+{
+	int wasfull = 0;
+	u32 notify;
+
+	if (*q->headers.producer+1 == *q->headers.consumer)
+		wasfull = 1;
+        
+	if (le32_to_cpu(*q->headers.consumer) >= q->entries)
+		*q->headers.consumer = cpu_to_le32(1);
+	else
+		*q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1);
+        
+	if (wasfull) {
+		switch (qid) {
+
+		case HostNormCmdQueue:
+			notify = HostNormCmdNotFull;
+			break;
+		case HostHighCmdQueue:
+			notify = HostHighCmdNotFull;
+			break;
+		case HostNormRespQueue:
+			notify = HostNormRespNotFull;
+			break;
+		case HostHighRespQueue:
+			notify = HostHighRespNotFull;
+			break;
+		default:
+			BUG();
+			return;
+		}
+		aac_adapter_notify(dev, notify);
+	}
+}        
+
+/**
+ *	fib_adapter_complete	-	complete adapter issued fib
+ *	@fibptr: fib to complete
+ *	@size: size of fib
+ *
+ *	Will do all necessary work to complete a FIB that was sent from
+ *	the adapter.
+ */
+
+int fib_adapter_complete(struct fib * fibptr, unsigned short size)
+{
+	struct hw_fib * fib = fibptr->fib;
+	struct aac_dev * dev = fibptr->dev;
+	unsigned long nointr = 0;
+
+	if (le32_to_cpu(fib->header.XferState) == 0)
+        	return 0;
+	/*
+	 *	If we plan to do anything check the structure type first.
+	 */ 
+	if ( fib->header.StructType != FIB_MAGIC ) {
+        	return -EINVAL;
+	}
+	/*
+	 *	This block handles the case where the adapter had sent us a
+	 *	command and we have finished processing the command. We
+	 *	call completeFib when we are done processing the command 
+	 *	and want to send a response back to the adapter. This will 
+	 *	send the completed cdb to the adapter.
+	 */
+	if (fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
+	        fib->header.XferState |= cpu_to_le32(HostProcessed);
+	        if (fib->header.XferState & cpu_to_le32(HighPriority)) {
+        		u32 index;
+       			if (size) 
+			{
+				size += sizeof(struct aac_fibhdr);
+				if (size > le16_to_cpu(fib->header.SenderSize))
+					return -EMSGSIZE;
+				fib->header.Size = cpu_to_le16(size);
+			}
+			if(aac_queue_get(dev, &index, AdapHighRespQueue, fib, 1, NULL, &nointr) < 0) {
+				return -EWOULDBLOCK;
+			}
+			if (aac_insert_entry(dev, index, AdapHighRespQueue,  (nointr & (int)aac_config.irq_mod)) != 0) {
+			}
+		}
+		else if (fib->header.XferState & NormalPriority) 
+		{
+			u32 index;
+
+			if (size) {
+				size += sizeof(struct aac_fibhdr);
+				if (size > le16_to_cpu(fib->header.SenderSize)) 
+					return -EMSGSIZE;
+				fib->header.Size = cpu_to_le16(size);
+			}
+			if (aac_queue_get(dev, &index, AdapNormRespQueue, fib, 1, NULL, &nointr) < 0) 
+				return -EWOULDBLOCK;
+			if (aac_insert_entry(dev, index, AdapNormRespQueue, 
+				(nointr & (int)aac_config.irq_mod)) != 0) 
+			{
+			}
+		}
+	}
+	else 
+	{
+        	printk(KERN_WARNING "fib_complete: Unknown xferstate detected.\n");
+        	BUG();
+	}   
+	return 0;
+}
+
+/**
+ *	fib_complete	-	fib completion handler
+ *	@fib: FIB to complete
+ *
+ *	Will do all necessary work to complete a FIB.
+ */
+ 
+int fib_complete(struct fib * fibptr)
+{
+	struct hw_fib * fib = fibptr->fib;
+
+	/*
+	 *	Check for a fib which has already been completed
+	 */
+
+	if (fib->header.XferState == cpu_to_le32(0))
+        	return 0;
+	/*
+	 *	If we plan to do anything check the structure type first.
+	 */ 
+
+	if (fib->header.StructType != FIB_MAGIC)
+	        return -EINVAL;
+	/*
+	 *	This block completes a cdb which orginated on the host and we 
+	 *	just need to deallocate the cdb or reinit it. At this point the
+	 *	command is complete that we had sent to the adapter and this
+	 *	cdb could be reused.
+	 */
+	if((fib->header.XferState & cpu_to_le32(SentFromHost)) &&
+		(fib->header.XferState & cpu_to_le32(AdapterProcessed)))
+	{
+		fib_dealloc(fibptr);
+	}
+	else if(fib->header.XferState & cpu_to_le32(SentFromHost))
+	{
+		/*
+		 *	This handles the case when the host has aborted the I/O
+		 *	to the adapter because the adapter is not responding
+		 */
+		fib_dealloc(fibptr);
+	} else if(fib->header.XferState & cpu_to_le32(HostOwned)) {
+		fib_dealloc(fibptr);
+	} else {
+		BUG();
+	}   
+	return 0;
+}
+
+/**
+ *	aac_printf	-	handle printf from firmware
+ *	@dev: Adapter
+ *	@val: Message info
+ *
+ *	Print a message passed to us by the controller firmware on the
+ *	Adaptec board
+ */
+
+void aac_printf(struct aac_dev *dev, u32 val)
+{
+	int length = val & 0xffff;
+	int level = (val >> 16) & 0xffff;
+	char *cp = dev->printfbuf;
+	
+	/*
+	 *	The size of the printfbuf is set in port.c
+	 *	There is no variable or define for it
+	 */
+	if (length > 255)
+		length = 255;
+	if (cp[length] != 0)
+		cp[length] = 0;
+	if (level == LOG_HIGH_ERROR)
+		printk(KERN_WARNING "aacraid:%s.\n", cp);
+	else
+		printk(KERN_INFO "aacraid:%s.\n", cp);
+	memset(cp, 0,  256);
+}
+
+
+/**
+ *	aac_handle_aif		-	Handle a message from the firmware
+ *	@dev: Which adapter this fib is from
+ *	@fibptr: Pointer to fibptr from adapter
+ *
+ *	This routine handles a driver notify fib from the adapter and
+ *	dispatches it to the appropriate routine for handling.
+ */
+
+static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
+{
+	struct hw_fib * fib = fibptr->fib;
+	/*
+	 * Set the status of this FIB to be Invalid parameter.
+	 *
+	 *	*(u32 *)fib->data = ST_INVAL;
+	 */
+	*(u32 *)fib->data = cpu_to_le32(ST_OK);
+	fib_adapter_complete(fibptr, sizeof(u32));
+}
+
+/**
+ *	aac_command_thread	-	command processing thread
+ *	@dev: Adapter to monitor
+ *
+ *	Waits on the commandready event in it's queue. When the event gets set
+ *	it will pull FIBs off it's queue. It will continue to pull FIBs off
+ *	until the queue is empty. When the queue is empty it will wait for
+ *	more FIBs.
+ */
+ 
+int aac_command_thread(struct aac_dev * dev)
+{
+	struct hw_fib *fib, *newfib;
+	struct fib fibptr; /* for error logging */
+	struct aac_queue_block *queues = dev->queues;
+	struct aac_fib_context *fibctx;
+	unsigned long flags;
+	DECLARE_WAITQUEUE(wait, current);
+
+	/*
+	 *	We can only have one thread per adapter for AIF's.
+	 */
+	if (dev->aif_thread)
+		return -EINVAL;
+	/*
+	 *	Set up the name that will appear in 'ps'
+	 *	stored in  task_struct.comm[16].
+	 */
+	sprintf(current->comm, "aacraid");
+	daemonize();
+	/*
+	 *	Let the DPC know it has a place to send the AIF's to.
+	 */
+	dev->aif_thread = 1;
+	memset(&fibptr, 0, sizeof(struct fib));
+	add_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	while(1) 
+	{
+		spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
+		while(!list_empty(&(queues->queue[HostNormCmdQueue].cmdq))) {
+			struct list_head *entry;
+			struct aac_aifcmd * aifcmd;
+
+			set_current_state(TASK_RUNNING);
+		
+			entry = queues->queue[HostNormCmdQueue].cmdq.next;
+			list_del(entry);
+			
+			spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);
+			fib = list_entry(entry, struct hw_fib, header.FibLinks);
+			/*
+			 *	We will process the FIB here or pass it to a 
+			 *	worker thread that is TBD. We Really can't 
+			 *	do anything at this point since we don't have
+			 *	anything defined for this thread to do.
+			 */
+			memset(&fibptr, 0, sizeof(struct fib));
+			fibptr.type = FSAFS_NTC_FIB_CONTEXT;
+			fibptr.size = sizeof( struct fib );
+			fibptr.fib = fib;
+			fibptr.data = fib->data;
+			fibptr.dev = dev;
+			/*
+			 *	We only handle AifRequest fibs from the adapter.
+			 */
+			aifcmd = (struct aac_aifcmd *) fib->data;
+			if (aifcmd->command == le16_to_cpu(AifCmdDriverNotify)) {
+				aac_handle_aif(dev, &fibptr);
+			} else {
+				/* The u32 here is important and intended. We are using
+				   32bit wrapping time to fit the adapter field */
+				   
+				u32 time_now, time_last;
+				unsigned long flagv;
+				
+				time_now = jiffies/HZ;
+
+				spin_lock_irqsave(&dev->fib_lock, flagv);
+				entry = dev->fib_list.next;
+				/*
+				 * For each Context that is on the 
+				 * fibctxList, make a copy of the
+				 * fib, and then set the event to wake up the
+				 * thread that is waiting for it.
+				 */
+				while (entry != &dev->fib_list) {
+					/*
+					 * Extract the fibctx
+					 */
+					fibctx = list_entry(entry, struct aac_fib_context, next);
+					/*
+					 * Check if the queue is getting
+					 * backlogged
+					 */
+					if (fibctx->count > 20)
+					{
+						time_last = fibctx->jiffies;
+						/*
+						 * Has it been > 2 minutes 
+						 * since the last read off
+						 * the queue?
+						 */
+						if ((time_now - time_last) > 120) {
+							entry = entry->next;
+							aac_close_fib_context(dev, fibctx);
+							continue;
+						}
+					}
+					/*
+					 * Warning: no sleep allowed while
+					 * holding spinlock
+					 */
+					newfib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC);
+					if (newfib) {
+						/*
+						 * Make the copy of the FIB
+						 */
+						memcpy(newfib, fib, sizeof(struct hw_fib));
+						/*
+						 * Put the FIB onto the
+						 * fibctx's fibs
+						 */
+						list_add_tail(&newfib->header.FibLinks, &fibctx->fibs);
+						fibctx->count++;
+						/* 
+						 * Set the event to wake up the
+						 * thread that will waiting.
+						 */
+						up(&fibctx->wait_sem);
+					} else {
+						printk(KERN_WARNING "aifd: didn't allocate NewFib.\n");
+					}
+					entry = entry->next;
+				}
+				/*
+				 *	Set the status of this FIB
+				 */
+				*(u32 *)fib->data = cpu_to_le32(ST_OK);
+				fib_adapter_complete(&fibptr, sizeof(u32));
+				spin_unlock_irqrestore(&dev->fib_lock, flagv);
+			}
+			spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);
+		}
+		/*
+		 *	There are no more AIF's
+		 */
+		spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);
+		schedule();
+
+		if(signal_pending(current))
+			break;
+		set_current_state(TASK_INTERRUPTIBLE);
+	}
+	remove_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);
+	dev->aif_thread = 0;
+	complete_and_exit(&dev->aif_completion, 0);
+}
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
--- linux-2.4.17-pre6/drivers/scsi/aacraid/dpcsup.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/dpcsup.c	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,201 @@
+/*
+ *	Adaptec AAC series RAID controller driver
+ *	(c) Copyright 2001 Red Hat Inc.	<alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ *
+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Module Name:
+ *  dpcsup.c
+ *
+ * Abstract: All DPC processing routines for the cyclone board occur here.
+ *
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/completion.h>
+#include <linux/blk.h>
+#include <asm/semaphore.h>
+#include "scsi.h"
+#include "hosts.h"
+
+#include "aacraid.h"
+
+/**
+ *	aac_response_normal	-	Handle command replies
+ *	@q: Queue to read from
+ *
+ *	This DPC routine will be run when the adapter interrupts us to let us
+ *	know there is a response on our normal priority queue. We will pull off
+ *	all QE there are and wake up all the waiters before exiting. We will
+ *	take a spinlock out on the queue before operating on it.
+ */
+
+unsigned int aac_response_normal(struct aac_queue * q)
+{
+	struct aac_dev * dev = q->dev;
+	struct aac_entry *entry;
+	struct hw_fib * fib;
+	struct fib * fibctx;
+	int consumed = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(q->lock, flags);	
+
+	/*
+	 *	Keep pulling response QEs off the response queue and waking
+	 *	up the waiters until there are no more QEs. We then return
+	 *	back to the system. If no response was requesed we just
+	 *	deallocate the Fib here and continue.
+	 */
+	while(aac_consumer_get(dev, q, &entry))
+	{
+		int fast;
+
+		fast = (int) (entry->addr & 0x01);
+		fib = (struct hw_fib *) (entry->addr & ~0x01);
+		aac_consumer_free(dev, q, HostNormRespQueue);
+		fibctx = (struct fib *)fib->header.SenderData;
+		/*
+		 *	Remove this fibctx from the Outstanding I/O queue.
+		 *	But only if it has not already been timed out.
+		 *
+		 *	If the fib has been timed out already, then just 
+		 *	continue. The caller has already been notified that
+		 *	the fib timed out.
+		 */
+		if (!(fibctx->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
+			list_del(&fibctx->queue);
+			dev->queues->queue[AdapNormCmdQueue].numpending--;
+		} else {
+			printk(KERN_WARNING "aacraid: FIB timeout.\n");
+			continue;
+		}
+		spin_unlock_irqrestore(q->lock, flags);
+
+		if (fast) {
+			/*
+			 *	Doctor the fib
+			 */
+			*(u32 *)fib->data = cpu_to_le32(ST_OK);
+			fib->header.XferState |= cpu_to_le32(AdapterProcessed);
+		}
+
+		FIB_COUNTER_INCREMENT(aac_config.FibRecved);
+
+		if (fib->header.Command == cpu_to_le16(NuFileSystem))
+		{
+			u32 *pstatus = (u32 *)fib->data;
+			if (*pstatus & cpu_to_le32(0xffff0000))
+				*pstatus = cpu_to_le32(ST_OK);
+		}
+		if (fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) 
+		{
+	        	if (fib->header.XferState & cpu_to_le32(NoResponseExpected))
+				FIB_COUNTER_INCREMENT(aac_config.NoResponseRecved);
+			else 
+				FIB_COUNTER_INCREMENT(aac_config.AsyncRecved);
+			/*
+			 *	NOTE:  we cannot touch the fibctx after this
+			 *	    call, because it may have been deallocated.
+			 */
+			fibctx->callback(fibctx->callback_data, fibctx);
+		} else {
+			unsigned long flagv;
+			spin_lock_irqsave(&fibctx->event_lock, flagv);
+			fibctx->done = 1;
+			up(&fibctx->event_wait);
+			spin_unlock_irqrestore(&fibctx->event_lock, flagv);
+			FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
+		}
+		consumed++;
+		spin_lock_irqsave(q->lock, flags);
+	}
+
+	if (consumed > aac_config.peak_fibs)
+		aac_config.peak_fibs = consumed;
+	if (consumed == 0) 
+		aac_config.zero_fibs++;
+
+	spin_unlock_irqrestore(q->lock, flags);
+	return 0;
+}
+
+
+/**
+ *	aac_command_normal	-	handle commands
+ *	@q: queue to process
+ *
+ *	This DPC routine will be queued when the adapter interrupts us to 
+ *	let us know there is a command on our normal priority queue. We will 
+ *	pull off all QE there are and wake up all the waiters before exiting.
+ *	We will take a spinlock out on the queue before operating on it.
+ */
+ 
+unsigned int aac_command_normal(struct aac_queue *q)
+{
+	struct aac_dev * dev = q->dev;
+	struct aac_entry *entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(q->lock, flags);
+
+	/*
+	 *	Keep pulling response QEs off the response queue and waking
+	 *	up the waiters until there are no more QEs. We then return
+	 *	back to the system.
+	 */
+	while(aac_consumer_get(dev, q, &entry))
+	{
+		struct hw_fib * fib;
+		fib = (struct hw_fib *)entry->addr;
+
+		if (dev->aif_thread) {
+		        list_add_tail(&fib->header.FibLinks, &q->cmdq);
+	 	        aac_consumer_free(dev, q, HostNormCmdQueue);
+		        wake_up_interruptible(&q->cmdready);
+		} else {
+			struct fib fibctx;
+	 	        aac_consumer_free(dev, q, HostNormCmdQueue);
+			spin_unlock_irqrestore(q->lock, flags);
+			memset(&fibctx, 0, sizeof(struct fib));
+			fibctx.type = FSAFS_NTC_FIB_CONTEXT;
+			fibctx.size = sizeof(struct fib);
+			fibctx.fib = fib;
+			fibctx.data = fib->data;
+			fibctx.dev = dev;
+			/*
+			 *	Set the status of this FIB
+			 */
+			*(u32 *)fib->data = cpu_to_le32(ST_OK);
+			fib_adapter_complete(&fibctx, sizeof(u32));
+			spin_lock_irqsave(q->lock, flags);
+		}		
+	}
+	spin_unlock_irqrestore(q->lock, flags);
+	return 0;
+}
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
--- linux-2.4.17-pre6/drivers/scsi/aacraid/linit.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/linit.c	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,691 @@
+/*
+ *	Adaptec AAC series RAID controller driver
+ *	(c) Copyright 2001 Red Hat Inc.	<alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ *
+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Module Name:
+ *   linit.c
+ *
+ * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
+ *				
+ *	Provides the following driver entry points:
+ *		aac_detect()
+ *		aac_release()
+ *		aac_queuecommand()
+ *		aac_resetcommand()
+ *		aac_biosparm()
+ *	
+ */
+
+#define AAC_DRIVER_VERSION		"0.9.9ac2-rel"
+#define AAC_DRIVER_BUILD_DATE		__DATE__
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/completion.h>
+#include <asm/semaphore.h>
+#include <linux/blk.h>
+#include "scsi.h"
+#include "hosts.h"
+
+#include "aacraid.h"
+#include "sd.h"
+
+#define AAC_DRIVERNAME	"aacraid"
+
+MODULE_AUTHOR("Red Hat Inc and Adaptec OEM RAID Solutions");
+MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, and HP NetRAID-4M devices.  http://domsch.com/linux/");
+MODULE_LICENSE("GPL");
+
+struct aac_dev *aac_devices[MAXIMUM_NUM_ADAPTERS];
+
+static unsigned aac_count = 0;
+static int aac_cfg_major = -1;
+static int single_command_done = 0;
+
+/*
+ * Because of the way Linux names scsi devices, the order in this table has
+ * become important.  Check for on-board Raid first, add-in cards second.
+ */
+
+/* FIXME static */struct aac_driver_ident aac_drivers[] = {
+	{ 0x1028, 0x0001, 0x1028, 0x0001, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 2/Si */
+	{ 0x1028, 0x0002, 0x1028, 0x0002, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
+	{ 0x1028, 0x0003, 0x1028, 0x0003, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
+	{ 0x1028, 0x0004, 0x1028, 0x00d0, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
+	{ 0x1028, 0x0002, 0x1028, 0x00d1, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
+	{ 0x1028, 0x0002, 0x1028, 0x00d9, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
+	{ 0x1028, 0x000a, 0x1028, 0x0106, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
+	{ 0x1028, 0x000a, 0x1028, 0x011b, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
+	{ 0x1028, 0x000a, 0x1028, 0x0121, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
+	{ 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL    ", "PERCRAID        " }, /* Dell PERC2 "Quad Channel" */
+	{ 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   " }, /* Adaptec 5400S */
+	{ 0x1011, 0x0046, 0x103c, 0x10c2, aac_sa_init, "hpnraid",  "HP      ", "NetRAID-4M      " }  /* HP NetRAID-4M */
+};
+
+#define NUM_AACTYPES	(sizeof(aac_drivers) / sizeof(struct aac_driver_ident))
+static int num_aacdrivers = NUM_AACTYPES;
+
+static int aac_cfg_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
+static int aac_cfg_open(struct inode * inode, struct file * file);
+static int aac_cfg_release(struct inode * inode,struct file * file);
+
+static struct file_operations aac_cfg_fops = {
+	owner: THIS_MODULE,
+	ioctl: aac_cfg_ioctl,
+	open: aac_cfg_open,
+	release: aac_cfg_release
+};
+
+static int aac_detect(Scsi_Host_Template *);
+static int aac_release(struct Scsi_Host *);
+static int aac_queuecommand(Scsi_Cmnd *, void (*CompletionRoutine)(Scsi_Cmnd *));
+static int aac_command(Scsi_Cmnd *);
+static int aac_abortcommand(Scsi_Cmnd *scsi_cmnd_ptr);
+static int aac_resetcommand(Scsi_Cmnd *, unsigned int);
+static int aac_biosparm(Scsi_Disk *, kdev_t, int *);
+static int aac_procinfo(char *, char **, off_t, int, int, int);
+static int aac_ioctl(Scsi_Device *, int, void *);
+
+static void aac_queuedepth(struct Scsi_Host *, Scsi_Device *);
+
+/**
+ *	aac_detect	-	Probe for aacraid cards
+ *	@template: SCSI driver template
+ *
+ *	Probe for AAC Host Adapters initialize, register, and report the 
+ *	configuration of each AAC Host Adapter found.
+ *	Returns the number of adapters successfully initialized and 
+ *	registered.
+ *	Initializes all data necessary for this particular SCSI driver.
+ *	Notes:
+ *	The detect routine must not call any of the mid level functions 
+ *	to queue commands because things are not guaranteed to be set 
+ *	up yet. The detect routine can send commands to the host adapter 
+ *	as long as the program control will not be passed to scsi.c in 
+ *	the processing of the command. Note especially that 
+ *	scsi_malloc/scsi_free must not be called.
+ *
+ */
+ 
+static int aac_detect(Scsi_Host_Template *template)
+{
+	int index;
+	int container;
+	u16 vendor_id, device_id;
+	struct Scsi_Host *host_ptr;
+	struct pci_dev *dev = NULL;
+	struct aac_dev *aac;
+	struct fsa_scsi_hba *fsa_dev_ptr;
+	char *name = NULL;
+	
+	printk(KERN_INFO "Red Hat/Adaptec aacraid driver, %s\n", AAC_DRIVER_BUILD_DATE);
+
+	/* setting up the proc directory structure */
+	template->proc_name = "aacraid";
+
+	for( index = 0; index != num_aacdrivers; index++ )
+	{
+		device_id = aac_drivers[index].device;
+		vendor_id = aac_drivers[index].vendor;
+		name = aac_drivers[index].name;
+		dprintk((KERN_DEBUG "Checking %s %x/%x/%x/%x.\n", 
+			name, vendor_id, device_id,
+			aac_drivers[index].subsystem_vendor,
+			aac_drivers[index].subsystem_device));
+
+		dev = NULL;
+		while((dev = pci_find_device(vendor_id, device_id, dev)))
+		{
+			if (pci_enable_device(dev))
+				continue;
+			pci_set_master(dev);
+			pci_set_dma_mask(dev, 0xFFFFFFFFULL);
+
+			if((dev->subsystem_vendor != aac_drivers[index].subsystem_vendor) || 
+			   (dev->subsystem_device != aac_drivers[index].subsystem_device))
+					continue;
+
+			dprintk((KERN_DEBUG "%s device detected.\n", name));
+			dprintk((KERN_DEBUG "%x/%x/%x/%x.\n", vendor_id, device_id, 
+				aac_drivers[index].subsystem_vendor, aac_drivers[index].subsystem_device));
+			/* Increment the host adapter count */
+			aac_count++;
+			/*
+			 * scsi_register() allocates memory for a Scsi_Hosts structure and
+			 * links it into the linked list of host adapters. This linked list
+			 * contains the data for all possible <supported> scsi hosts.
+			 * This is similar to the Scsi_Host_Template, except that we have
+			 * one entry for each actual physical host adapter on the system,
+			 * stored as a linked list. If there are two AAC boards, then we
+			 * will need to make two Scsi_Host entries, but there will be only
+			 * one Scsi_Host_Template entry. The second argument to scsi_register()
+			 * specifies the size of the extra memory we want to hold any device 
+			 * specific information.
+			 */
+			host_ptr = scsi_register( template, sizeof(struct aac_dev) );
+			/* 
+			 * These three parameters can be used to allow for wide SCSI 
+			 * and for host adapters that support multiple buses.
+			 */
+			host_ptr->max_id = 17;
+			host_ptr->max_lun = 8;
+			host_ptr->max_channel = 1;
+			host_ptr->irq = dev->irq;		/* Adapter IRQ number */
+			/* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
+			host_ptr->base = dev->resource[0].start;
+			scsi_set_pci_device(host_ptr, dev);
+			dprintk((KERN_DEBUG "Device base address = 0x%lx [0x%lx].\n", host_ptr->base, dev->resource[0].start));
+			dprintk((KERN_DEBUG "Device irq = 0x%x.\n", dev->irq));
+			/*
+			 * The unique_id field is a unique identifier that must
+			 * be assigned so that we have some way of identifying
+			 * each host adapter properly and uniquely. For hosts 
+			 * that do not support more than one card in the
+			 * system, this does not need to be set. It is
+			 * initialized to zero in scsi_register(). This is the 
+			 * value returned as aac->id.
+			 */
+			host_ptr->unique_id = aac_count - 1;
+			/*
+			 *	This function is called after the device list has
+			 *	been built to find the tagged queueing depth 
+			 *	supported for each device.
+			 */
+			host_ptr->select_queue_depths = aac_queuedepth;
+			aac = (struct aac_dev *)host_ptr->hostdata;
+			/* attach a pointer back to Scsi_Host */
+			aac->scsi_host_ptr = host_ptr;	
+			aac->pdev = dev;
+			aac->cardtype =  index;
+			aac->name = aac->scsi_host_ptr->hostt->name;
+			aac->id = aac->scsi_host_ptr->unique_id;
+			/* Initialize the ordinal number of the device to -1 */
+			fsa_dev_ptr = &(aac->fsa_dev);
+			for( container = 0; container < MAXIMUM_NUM_CONTAINERS; container++ )
+				fsa_dev_ptr->devno[container] = -1;
+
+			dprintk((KERN_DEBUG "Initializing Hardware...\n"));
+			if((*aac_drivers[index].init)(aac , host_ptr->unique_id) != 0)
+			{
+				/* device initialization failed */
+				printk(KERN_WARNING "aacraid: device initialization failed.\n");
+				scsi_unregister(host_ptr);
+				aac_count--;
+			} 
+			else
+			{
+				dprintk((KERN_DEBUG "%s:%d device initialization successful.\n", name, host_ptr->unique_id));
+				aac_get_containers(aac);
+				aac_devices[aac_count-1] = aac;
+			}
+		}
+	}
+
+	if( aac_count ){
+		if((aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops))<0)
+			printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n");
+	}
+
+	template->present = aac_count; /* # of cards of this type found */
+	return aac_count;
+}
+
+/**
+ *	aac_release	-	release SCSI host resources
+ *	@host_ptr: SCSI host to clean up
+ *
+ *	Release all resources previously acquired to support a specific Host 
+ *	Adapter and unregister the AAC Host Adapter.
+ *
+ *	BUGS: Does not wait for the thread it kills to die.
+ */
+
+static int aac_release(struct Scsi_Host *host_ptr)
+{
+	struct aac_dev *dev;
+	dprintk((KERN_DEBUG "aac_release.\n"));
+	dev = (struct aac_dev *)host_ptr->hostdata;
+	/*
+	 *	kill any threads we started
+	 */
+	kill_proc(dev->thread_pid, SIGKILL, 0);
+	wait_for_completion(&dev->aif_completion);
+	/*
+	 *	Call the comm layer to detach from this adapter
+	 */
+	aac_detach(dev);
+	/* Check free orderings... */
+	/* remove interrupt binding */
+	free_irq(host_ptr->irq, dev);
+	iounmap((void * )dev->regs.sa);
+	/* unregister adapter */
+	scsi_unregister(host_ptr);
+	/*
+	 *	FIXME: This assumes no hot plugging is going on...
+	 */
+	if( aac_cfg_major >= 0 )
+	{
+		unregister_chrdev(aac_cfg_major, "aac");
+		aac_cfg_major = -1;
+	}
+	return 0;
+}
+
+/**
+ *	aac_queuecommand	-	queue a SCSI command
+ *	@scsi_cmnd_ptr:	SCSI command to queue
+ *	@CompletionRoutine: Function to call on command completion
+ *
+ *	Queues a command for execution by the associated Host Adapter.
+ */ 
+
+static int aac_queuecommand(Scsi_Cmnd *scsi_cmnd_ptr, void (*CompletionRoutine)(Scsi_Cmnd *))
+{
+	int ret;
+
+	scsi_cmnd_ptr->scsi_done = CompletionRoutine;
+	/*
+	 *	aac_scsi_cmd() handles command processing, setting the 
+	 *	result code and calling completion routine. 
+	 */
+	if((ret = aac_scsi_cmd(scsi_cmnd_ptr)) != 0)
+		dprintk((KERN_DEBUG "aac_scsi_cmd failed.\n"));
+	return ret;
+} 
+
+
+/**
+ *	aac_done	-	Callback function for a non-queued command.
+ *	@scsi_cmnd_ptr:	SCSI command block to wait for
+ *
+ *	Sets single_command done to 1. This lets aac_command complete. 
+ *	This function is obsolete.
+ *
+ *	Bugs: Doesn't actually work properly with multiple controllers
+ */
+ 
+static void aac_done(Scsi_Cmnd * scsi_cmnd_ptr) 
+{
+	single_command_done = 1;
+}
+
+/**
+ *	aac_command	-	synchronous SCSI command execution
+ *	@scsi_cmnd_ptr:	SCSI command to issue
+ *
+ *	Accepts a single command for execution by the associated Host Adapter.
+ *	Waits until it completes an then returns an int where:
+ *		Byte 0 = SCSI status code
+ *		Byte 1 = SCSI 1 byte message
+ *		Byte 2 = host error return
+ *		Byte 3 = mid level error return
+ */
+ 
+static int aac_command(Scsi_Cmnd *scsi_cmnd_ptr )
+{
+	scsi_cmnd_ptr->scsi_done = aac_done;
+	dprintk((KERN_DEBUG "aac_command.\n"));
+
+	/*
+	 *	aac_scsi_cmd() handles command processing, setting the 
+	 *	result code and calling completion routine.
+	 */
+	single_command_done = 0;
+	aac_scsi_cmd(scsi_cmnd_ptr);
+	while(!single_command_done)
+		rmb();
+	return scsi_cmnd_ptr->result;
+} 
+
+/**
+ *	aac_abortcommand	-	Abort command if possible.
+ *	@scsi_cmnd_ptr:	SCSI command block to abort
+ *
+ *	Called when the midlayer wishes to abort a command. We don't support
+ *	this facility, and our firmware looks after life for us. We just
+ *	report the command as busy. 
+ */
+ 
+static int aac_abortcommand(Scsi_Cmnd *scsi_cmnd_ptr )
+{
+	return SCSI_ABORT_BUSY;
+}
+
+/**
+ *	aac_resetcommand	-	Reset command handling
+ *	@scsi_cmnd_ptr:	SCSI command block causing the reset
+ *	@reset_flags: Reset hints from the midlayer code
+ *
+ *	Issue a reset of a SCSI command. We are ourselves not truely a SCSI
+ *	controller and our firmware will do the work for us anyway. Thus this
+ *	is a no-op. We just return SCSI_RESET_PUNT
+ */
+ 
+static int aac_resetcommand(struct scsi_cmnd *scsi_cmnd_ptr, unsigned int reset_flags )
+{
+	return SCSI_RESET_PUNT;
+}
+
+/**
+ *	aac_driverinfo		-	Returns the host adapter name
+ *	@host_ptr:	Scsi host to report on
+ *
+ *	Returns a static string describing the device in question
+ */
+
+const char *aac_driverinfo(struct Scsi_Host *host_ptr)
+{
+	struct aac_dev *dev = (struct aac_dev *)host_ptr->hostdata;
+	return aac_drivers[dev->cardtype].name;
+}
+
+/**
+ *	aac_biosparm	-	return BIOS parameters for disk
+ *	@disk: SCSI disk object to process
+ *	@device: kdev_t of the disk in question
+ *	@geom: geometry block to fill in
+ *
+ *	Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.  
+ *	The default disk geometry is 64 heads, 32 sectors, and the appropriate 
+ *	number of cylinders so as not to exceed drive capacity.  In order for 
+ *	disks equal to or larger than 1 GB to be addressable by the BIOS
+ *	without exceeding the BIOS limitation of 1024 cylinders, Extended 
+ *	Translation should be enabled.   With Extended Translation enabled, 
+ *	drives between 1 GB inclusive and 2 GB exclusive are given a disk 
+ *	geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive 
+ *	are given a disk geometry of 255 heads and 63 sectors.  However, if 
+ *	the BIOS detects that the Extended Translation setting does not match 
+ *	the geometry in the partition table, then the translation inferred 
+ *	from the partition table will be used by the BIOS, and a warning may 
+ *	be displayed.
+ */
+ 
+static int aac_biosparm(Scsi_Disk *disk, kdev_t dev, int *geom)
+{
+	struct diskparm *param = (struct diskparm *)geom;
+	struct buffer_head * buf;
+
+	dprintk((KERN_DEBUG "aac_biosparm.\n"));
+
+	/*
+	 *	Assuming extended translation is enabled - #REVISIT#
+	 */
+	if( disk->capacity >= 2 * 1024 * 1024 ) /* 1 GB in 512 byte sectors */
+	{
+		if( disk->capacity >= 4 * 1024 * 1024 ) /* 2 GB in 512 byte sectors */
+		{
+			param->heads = 255;
+			param->sectors = 63;
+		}
+		else
+		{
+			param->heads = 128;
+			param->sectors = 32;
+		}
+	}
+	else
+	{
+		param->heads = 64;
+		param->sectors = 32;
+	}
+
+	param->cylinders = disk->capacity/(param->heads * param->sectors);
+
+	/*
+	 *	Read the first 1024 bytes from the disk device
+	 */
+
+	buf = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, block_size(dev));
+	if(buf == NULL)
+		return 0;
+	/* 
+	 *	If the boot sector partition table is valid, search for a partition 
+	 *	table entry whose end_head matches one of the standard geometry 
+	 *	translations ( 64/32, 128/32, 255/63 ).
+	 */
+	 
+	if(*(unsigned short *)(buf->b_data + 0x1fe) == cpu_to_le16(0xaa55))
+	{
+		struct partition *first = (struct partition * )(buf->b_data + 0x1be);
+		struct partition *entry = first;
+		int saved_cylinders = param->cylinders;
+		int num;
+		unsigned char end_head, end_sec;
+
+		for(num = 0; num < 4; num++)
+		{
+			end_head = entry->end_head;
+			end_sec = entry->end_sector & 0x3f;
+
+			if(end_head == 63)
+			{
+				param->heads = 64;
+				param->sectors = 32;
+				break;
+			}
+			else if(end_head == 127)
+			{
+				param->heads = 128;
+				param->sectors = 32;
+				break;
+			}
+			else if(end_head == 254) 
+			{
+				param->heads = 255;
+				param->sectors = 63;
+				break;
+			}
+			entry++;
+		}
+
+		if(num == 4)
+		{
+			end_head = first->end_head;
+			end_sec = first->end_sector & 0x3f;
+		}
+
+		param->cylinders = disk->capacity / (param->heads * param->sectors);
+
+		if(num < 4 && end_sec == param->sectors)
+		{
+			if(param->cylinders != saved_cylinders)
+				dprintk((KERN_DEBUG "Adopting geometry: heads=%d, sectors=%d from partition table %d.\n",
+					param->heads, param->sectors, num));
+		}
+		else if(end_head > 0 || end_sec > 0)
+		{
+			dprintk((KERN_DEBUG "Strange geometry: heads=%d, sectors=%d in partition table %d.\n",
+				end_head + 1, end_sec, num));
+			dprintk((KERN_DEBUG "Using geometry: heads=%d, sectors=%d.\n",
+					param->heads, param->sectors));
+		}
+	}
+	brelse(buf);
+	return 0;
+}
+
+/**
+ *	aac_queuedepth		-	compute queue depths
+ *	@host:	SCSI host in question
+ *	@dev:	SCSI device we are considering
+ *
+ *	Selects queue depths for each target device based on the host adapter's
+ *	total capacity and the queue depth supported by the target device.
+ *	A queue depth of one automatically disables tagged queueing.
+ */
+
+static void aac_queuedepth(struct Scsi_Host * host, Scsi_Device * dev )
+{
+	Scsi_Device * dptr;
+
+	dprintk((KERN_DEBUG "aac_queuedepth.\n"));
+	dprintk((KERN_DEBUG "Device #   Q Depth   Online\n"));
+	dprintk((KERN_DEBUG "---------------------------\n"));
+	for(dptr = dev; dptr != NULL; dptr = dptr->next)
+	{
+		if(dptr->host == host)
+		{
+			dptr->queue_depth = 10;		
+			dprintk((KERN_DEBUG "  %2d         %d        %d\n", 
+				dptr->id, dptr->queue_depth, dptr->online));
+		}
+	}
+}
+
+/*------------------------------------------------------------------------------
+	aac_ioctl()
+
+		Handle SCSI ioctls
+ *----------------------------------------------------------------------------*/
+static int aac_ioctl(Scsi_Device * scsi_dev_ptr, int cmd, void * arg)
+/*----------------------------------------------------------------------------*/
+{
+	struct aac_dev *dev;
+	dprintk((KERN_DEBUG "aac_ioctl.\n"));
+	dev = (struct aac_dev *)scsi_dev_ptr->host->hostdata;
+	return aac_do_ioctl(dev, cmd, arg);
+}
+
+/**
+ *	aac_cfg_open		-	open a configuration file
+ *	@inode: inode being opened
+ *	@file: file handle attached
+ *
+ *	Called when the configuration device is opened. Does the needed
+ *	set up on the handle and then returns
+ *
+ *	Bugs: This needs extending to check a given adapter is present
+ *	so we can support hot plugging, and to ref count adapters.
+ */
+
+static int aac_cfg_open(struct inode * inode, struct file * file )
+{
+	unsigned minor_number = MINOR(inode->i_rdev);
+	if(minor_number >= aac_count)
+		return -ENODEV;
+	return 0;
+}
+
+/**
+ *	aac_cfg_release		-	close down an AAC config device
+ *	@inode: inode of configuration file
+ *	@file: file handle of configuration file
+ *	
+ *	Called when the last close of the configuration file handle
+ *	is performed.
+ */
+ 
+static int aac_cfg_release(struct inode * inode, struct file * file )
+{
+	return 0;
+}
+
+/**
+ *	aac_cfg_ioctl		-	AAC configuration request
+ *	@inode: inode of device
+ *	@file: file handle
+ *	@cmd: ioctl command code
+ *	@arg: argument
+ *
+ *	Handles a configuration ioctl. Currently this involves wrapping it
+ *	up and feeding it into the nasty windowsalike glue layer.
+ *
+ *	Bugs: Needs locking against parallel ioctls lower down
+ *	Bugs: Needs to handle hot plugging
+ */
+ 
+static int aac_cfg_ioctl(struct inode * inode,  struct file * file, unsigned int cmd, unsigned long arg )
+{
+	struct aac_dev *dev = aac_devices[MINOR(inode->i_rdev)];
+	return aac_do_ioctl(dev, cmd, (void *)arg);
+}
+
+/*
+ *	To use the low level SCSI driver support using the linux kernel loadable 
+ *	module interface we should initialize the global variable driver_interface  
+ *	(datatype Scsi_Host_Template) and then include the file scsi_module.c.
+ */
+ 
+static Scsi_Host_Template driver_template = {
+	module:			THIS_MODULE,
+	name:           	"AAC",
+	proc_info:      	aac_procinfo,
+	detect:         	aac_detect,
+	release:        	aac_release,
+	info:           	aac_driverinfo,
+	ioctl:          	aac_ioctl,
+	command:        	aac_command,
+	queuecommand:   	aac_queuecommand,
+	abort:          	aac_abortcommand,
+	reset:          	aac_resetcommand,
+	bios_param:     	aac_biosparm,	
+	can_queue:      	AAC_NUM_IO_FIB,	
+	this_id:        	16,
+	sg_tablesize:   	16,
+	max_sectors:    	128,
+	cmd_per_lun:    	1,
+	eh_abort_handler:       aac_abortcommand,
+	use_clustering:		ENABLE_CLUSTERING,
+};
+
+#include "scsi_module.c"
+
+/**
+ *	aac_procinfo	-	Implement /proc/scsi/<drivername>/<n>
+ *	@proc_buffer: memory buffer for I/O
+ *	@start_ptr: pointer to first valid data
+ *	@offset: offset into file
+ *	@bytes_available: space left
+ *	@host_no: scsi host ident
+ *	@write: direction of I/O
+ *
+ *	Used to export driver statistics and other infos to the world outside 
+ *	the kernel using the proc file system. Also provides an interface to
+ *	feed the driver with information.
+ *
+ *		For reads
+ *			- if offset > 0 return 0
+ *			- if offset == 0 write data to proc_buffer and set the start_ptr to
+ *			beginning of proc_buffer, return the number of characters written.
+ *		For writes
+ *			- writes currently not supported, return 0
+ *
+ *	Bugs:	Only offset zero is handled
+ */
+
+static int aac_procinfo(char *proc_buffer, char **start_ptr,off_t offset,
+			int bytes_available, int host_no, int write)
+{
+	if(write || offset > 0)
+		return 0;
+	*start_ptr = proc_buffer;
+	return sprintf(proc_buffer, "%s  %d\n", "Raid Controller, scsi hba number", host_no);
+}
+
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
--- linux-2.4.17-pre6/drivers/scsi/aacraid/rx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/rx.c	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,413 @@
+/*
+ *	Adaptec AAC series RAID controller driver
+ *	(c) Copyright 2001 Red Hat Inc.	<alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ *
+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Module Name:
+ *  rx.c
+ *
+ * Abstract: Hardware miniport for Drawbridge specific hardware functions.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/blk.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <asm/semaphore.h>
+#include "scsi.h"
+#include "hosts.h"
+
+#include "aacraid.h"
+
+static void aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct aac_dev *dev = dev_id;
+	unsigned long bellbits;
+	u8 intstat, mask;
+
+	intstat = rx_readb(dev, MUnit.OISR);
+	/*
+	 *	Read mask and invert because drawbridge is reversed.
+	 *	This allows us to only service interrupts that have 
+	 *	been enabled.
+	 */
+	mask = ~(rx_readb(dev, MUnit.OIMR));
+	/* Check to see if this is our interrupt.  If it isn't just return */
+	if (intstat & mask) 
+	{
+		bellbits = rx_readl(dev, OutboundDoorbellReg);
+		if (bellbits & DoorBellPrintfReady)
+		{
+			aac_printf(dev, le32_to_cpu(rx_readl (dev, IndexRegs.Mailbox[5])));
+			rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
+			rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
+		}
+		else if (bellbits & DoorBellAdapterNormCmdReady)
+		{
+			aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
+			rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
+		}
+		else if (bellbits & DoorBellAdapterNormRespReady) 
+		{
+			aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
+			rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
+		}
+		else if (bellbits & DoorBellAdapterNormCmdNotFull)
+		{
+			rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+		}
+		else if (bellbits & DoorBellAdapterNormRespNotFull)
+		{
+			rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+		}
+	}
+}
+
+/**
+ *	aac_rx_enable_interrupt	-	Enable event reporting
+ *	@dev: Adapter
+ *	@event: Event to enable
+ *
+ *	Enable event reporting from the i960 for a given event.
+ */
+ 
+static void aac_rx_enable_interrupt(struct aac_dev * dev, u32 event)
+{
+	switch (event) {
+
+	case HostNormCmdQue:
+		dev->irq_mask &= ~(OUTBOUNDDOORBELL_1);
+		break;
+
+	case HostNormRespQue:
+		dev->irq_mask &= ~(OUTBOUNDDOORBELL_2);
+		break;
+
+	case AdapNormCmdNotFull:
+		dev->irq_mask &= ~(OUTBOUNDDOORBELL_3);
+		break;
+
+	case AdapNormRespNotFull:
+		dev->irq_mask &= ~(OUTBOUNDDOORBELL_4);
+		break;
+	}
+}
+
+/**
+ *	aac_rx_disable_interrupt	-	Disable event reporting
+ *	@dev: Adapter
+ *	@event: Event to enable
+ *
+ *	Disable event reporting from the i960 for a given event.
+ */
+
+static void aac_rx_disable_interrupt(struct aac_dev *dev, u32 event)
+{
+	switch (event) {
+
+	case HostNormCmdQue:
+		dev->irq_mask |= (OUTBOUNDDOORBELL_1);
+		break;
+
+	case HostNormRespQue:
+		dev->irq_mask |= (OUTBOUNDDOORBELL_2);
+		break;
+
+	case AdapNormCmdNotFull:
+		dev->irq_mask |= (OUTBOUNDDOORBELL_3);
+		break;
+
+	case AdapNormRespNotFull:
+		dev->irq_mask |= (OUTBOUNDDOORBELL_4);
+		break;
+	}
+}
+
+/**
+ *	rx_sync_cmd	-	send a command and wait
+ *	@dev: Adapter
+ *	@command: Command to execute
+ *	@p1: first parameter
+ *	@ret: adapter status
+ *
+ *	This routine will send a synchronous comamnd to the adapter and wait 
+ *	for its	completion.
+ */
+
+static int rx_sync_cmd(struct aac_dev *dev, unsigned long command, unsigned long p1, unsigned long *status)
+{
+	unsigned long start;
+	int ok;
+	/*
+	 *	Write the command into Mailbox 0
+	 */
+	rx_writel(dev, InboundMailbox0, cpu_to_le32(command));
+	/*
+	 *	Write the parameters into Mailboxes 1 - 4
+	 */
+	rx_writel(dev, InboundMailbox1, cpu_to_le32(p1));
+	rx_writel(dev, InboundMailbox2, 0);
+	rx_writel(dev, InboundMailbox3, 0);
+	rx_writel(dev, InboundMailbox4, 0);
+	/*
+	 *	Clear the synch command doorbell to start on a clean slate.
+	 */
+	rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
+	/*
+	 *	Disable doorbell interrupts
+	 */
+	rx_writeb(dev, MUnit.OIMR, rx_readb(dev, MUnit.OIMR) | 0x04);
+	/*
+	 *	Force the completion of the mask register write before issuing
+	 *	the interrupt.
+	 */
+	rx_readb (dev, MUnit.OIMR);
+	/*
+	 *	Signal that there is a new synch command
+	 */
+	rx_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0);
+
+	ok = 0;
+	start = jiffies;
+
+	/*
+	 *	Wait up to 30 seconds
+	 */
+	while (time_before(start+30*HZ, jiffies)) 
+	{
+		udelay(5);	/* Delay 5 microseconds to let Mon960 get info. */
+		/*
+		 *	Mon960 will set doorbell0 bit when it has completed the command.
+		 */
+		if (rx_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
+			/*
+			 *	Clear the doorbell.
+			 */
+			rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
+			ok = 1;
+			break;
+		}
+		/*
+		 *	Yield the processor in case we are slow 
+		 */
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+	if (ok != 1) {
+		/*
+		 *	Restore interrupt mask even though we timed out
+		 */
+		rx_writeb(dev, MUnit.OIMR, rx_readl(dev, MUnit.OIMR) & 0xfb);
+		return -ETIMEDOUT;
+	}
+	/*
+	 *	Pull the synch status from Mailbox 0.
+	 */
+	*status = le32_to_cpu(rx_readl(dev, IndexRegs.Mailbox[0]));
+	/*
+	 *	Clear the synch command doorbell.
+	 */
+	rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
+	/*
+	 *	Restore interrupt mask
+	 */
+	rx_writeb(dev, MUnit.OIMR, rx_readl(dev, MUnit.OIMR) & 0xfb);
+	return 0;
+
+}
+
+/**
+ *	aac_rx_interrupt_adapter	-	interrupt adapter
+ *	@dev: Adapter
+ *
+ *	Send an interrupt to the i960 and breakpoint it.
+ */
+
+static void aac_rx_interrupt_adapter(struct aac_dev *dev)
+{
+	unsigned long ret;
+	rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
+}
+
+/**
+ *	aac_rx_notify_adapter		-	send an event to the adapter
+ *	@dev: Adapter
+ *	@event: Event to send
+ *
+ *	Notify the i960 that something it probably cares about has
+ *	happened.
+ */
+
+static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event)
+{
+	switch (event) {
+
+	case AdapNormCmdQue:
+		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1);
+		break;
+	case HostNormRespNotFull:
+		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4);
+		break;
+	case AdapNormRespQue:
+		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2);
+		break;
+	case HostNormCmdNotFull:
+		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3);
+		break;
+	case HostShutdown:
+//		rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret);
+		break;
+	case FastIo:
+		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6);
+		break;
+	case AdapPrintfDone:
+		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5);
+		break;
+	default:
+		BUG();
+		break;
+	}
+}
+
+/**
+ *	aac_rx_start_adapter		-	activate adapter
+ *	@dev:	Adapter
+ *
+ *	Start up processing on an i960 based AAC adapter
+ */
+
+static void aac_rx_start_adapter(struct aac_dev *dev)
+{
+	unsigned long status;
+	struct aac_init *init;
+
+	init = dev->init;
+	init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ);
+	/*
+	 *	Tell the adapter we are back and up and running so it will scan
+	 *	its command queues and enable our interrupts
+	 */
+	dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
+	/*
+	 *	First clear out all interrupts.  Then enable the one's that we
+	 *	can handle.
+	 */
+	rx_writeb(dev, MUnit.OIMR, 0xff);
+	rx_writel(dev, MUnit.ODR, 0xffffffff);
+//	rx_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK);
+	rx_writeb(dev, MUnit.OIMR, 0xfb);
+
+	rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (unsigned long) dev->init_pa, &status);
+}
+
+/**
+ *	aac_rx_init	-	initialize an i960 based AAC card
+ *	@dev: device to configure
+ *	@devnum: adapter number
+ *
+ *	Allocate and set up resources for the i960 based AAC variants. The 
+ *	device_interface in the commregion will be allocated and linked 
+ *	to the comm region.
+ */
+
+int aac_rx_init(struct aac_dev *dev, unsigned long num)
+{
+	unsigned long start;
+	unsigned long status;
+	int instance;
+	const char * name;
+
+	dev->devnum = num;
+
+	instance = dev->id;
+	name     = dev->name;
+
+	/*
+	 *	Map in the registers from the adapter.
+	 */
+	if((dev->regs.rx = (struct rx_registers *)ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
+	{	
+		printk(KERN_WARNING "aacraid: unable to map i960.\n" );
+		return -1;
+	}
+	/*
+	 *	Check to see if the board failed any self tests.
+	 */
+	if (rx_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
+		printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
+		return -1;
+	}
+	/*
+	 *	Check to see if the board panic'd while booting.
+	 */
+	if (rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
+		printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance);
+		return -1;
+	}
+	start = jiffies;
+	/*
+	 *	Wait for the adapter to be up and running. Wait up to 30 seconds.
+	 */
+	while (!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) 
+	{
+		if(time_after(jiffies, start+30*HZ))
+		{
+			status = rx_readl(dev, IndexRegs.Mailbox[7]) >> 16;
+			printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %ld.\n", dev->name, instance, status);
+			return -1;
+		}
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+	if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) 
+	{
+		printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance);
+		return -1;
+	}
+	/*
+	 *	Fill in the function dispatch table.
+	 */
+	dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;
+	dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt;
+	dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt;
+	dev->a_ops.adapter_notify = aac_rx_notify_adapter;
+
+	if (aac_init_adapter(dev) == NULL)
+		return -1;
+	/*
+	 *	Start any kernel threads needed
+	 */
+	dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
+	/*
+	 *	Tell the adapter that all is configured, and it can start
+	 *	accepting requests
+	 */
+	aac_rx_start_adapter(dev);
+	return 0;
+}
diff -urN linux-2.4.17-pre6/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
--- linux-2.4.17-pre6/drivers/scsi/aacraid/sap1sup.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/aacraid/sap1sup.c	Sun Dec  9 12:40:05 2001
@@ -0,0 +1,394 @@
+/*
+ *	Adaptec AAC series RAID controller driver
+ *	(c) Copyright 2001 Red Hat Inc.	<alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ *
+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Module Name:
+ *  sap1sup.c
+ *
+ * Abstract: Drawbridge specific support functions
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/blk.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <asm/semaphore.h>
+#include "scsi.h"
+#include "hosts.h"
+
+#include "aacraid.h"
+
+static void aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct aac_dev *dev = dev_id;
+	unsigned short intstat, mask;
+
+	intstat = sa_readw(dev, DoorbellReg_p);
+	/*
+	 *	Read mask and invert because drawbridge is reversed.
+	 *	This allows us to only service interrupts that have been enabled.
+	 */
+	mask = ~(sa_readw(dev, SaDbCSR.PRISETIRQMASK));
+
+	/* Check to see if this is our interrupt.  If it isn't just return */
+
+	if (intstat & mask) {
+		if (intstat & PrintfReady) {
+			aac_printf(dev, le32_to_cpu(sa_readl(dev, Mailbox5)));
+			sa_writew(dev, DoorbellClrReg_p, PrintfReady); /* clear PrintfReady */
+			sa_writew(dev, DoorbellReg_s, PrintfDone);
+		} else if (intstat & DOORBELL_1) {	// dev -> Host Normal Command Ready
+			aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
+			sa_writew(dev, DoorbellClrReg_p, DOORBELL_1);
+		} else if (intstat & DOORBELL_2) {	// dev -> Host Normal Response Ready
+			aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
+			sa_writew(dev, DoorbellClrReg_p, DOORBELL_2);
+		} else if (intstat & DOORBELL_3) {	// dev -> Host Normal Command Not Full
+			sa_writew(dev, DoorbellClrReg_p, DOORBELL_3);
+		} else if (intstat & DOORBELL_4) {	// dev -> Host Normal Response Not Full
+			sa_writew(dev, DoorbellClrReg_p, DOORBELL_4);
+		}
+	}
+}
+
+/**
+ *	aac_sa_enable_interrupt	-	enable an interrupt event
+ *	@dev: Which adapter to enable.
+ *	@event: Which adapter event.
+ *
+ *	This routine will enable the corresponding adapter event to cause an interrupt on 
+ * 	the host.
+ */
+ 
+void aac_sa_enable_interrupt(struct aac_dev *dev, u32 event)
+{
+	switch (event) {
+
+	case HostNormCmdQue:
+		sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, DOORBELL_1);
+		break;
+
+	case HostNormRespQue:
+		sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, DOORBELL_2);
+		break;
+
+	case AdapNormCmdNotFull:
+		sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, DOORBELL_3);
+		break;
+
+	case AdapNormRespNotFull:
+		sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, DOORBELL_4);
+		break;
+	}
+}
+
+/**
+ *	aac_sa_disable_interrupt	-	disable an interrupt event
+ *	@dev: Which adapter to enable.
+ *	@event: Which adapter event.
+ *
+ *	This routine will enable the corresponding adapter event to cause an interrupt on 
+ * 	the host.
+ */
+
+void aac_sa_disable_interrupt (struct aac_dev *dev, u32 event)
+{
+	switch (event) {
+
+	case HostNormCmdQue:
+		sa_writew(dev, SaDbCSR.PRISETIRQMASK, DOORBELL_1);
+		break;
+
+	case HostNormRespQue:
+		sa_writew(dev, SaDbCSR.PRISETIRQMASK, DOORBELL_2);
+		break;
+
+	case AdapNormCmdNotFull:
+		sa_writew(dev, SaDbCSR.PRISETIRQMASK, DOORBELL_3);
+		break;
+
+	case AdapNormRespNotFull:
+		sa_writew(dev, SaDbCSR.PRISETIRQMASK, DOORBELL_4);
+		break;
+	}
+}
+
+/**
+ *	aac_sa_notify_adapter		-	handle adapter notification
+ *	@dev:	Adapter that notification is for
+ *	@event:	Event to notidy
+ *
+ *	Notify the adapter of an event
+ */
+ 
+void aac_sa_notify_adapter(struct aac_dev *dev, u32 event)
+{
+	switch (event) {
+
+	case AdapNormCmdQue:
+		sa_writew(dev, DoorbellReg_s,DOORBELL_1);
+		break;
+	case HostNormRespNotFull:
+		sa_writew(dev, DoorbellReg_s,DOORBELL_4);
+		break;
+	case AdapNormRespQue:
+		sa_writew(dev, DoorbellReg_s,DOORBELL_2);
+		break;
+	case HostNormCmdNotFull:
+		sa_writew(dev, DoorbellReg_s,DOORBELL_3);
+		break;
+	case HostShutdown:
+		//sa_sync_cmd(dev, HOST_CRASHING, 0, &ret);
+		break;
+	case FastIo:
+		sa_writew(dev, DoorbellReg_s,DOORBELL_6);
+		break;
+	case AdapPrintfDone:
+		sa_writew(dev, DoorbellReg_s,DOORBELL_5);
+		break;
+	default:
+		BUG();
+		break;
+	}
+}
+
+
+/**
+ *	sa_sync_cmd	-	send a command and wait
+ *	@dev: Adapter
+ *	@command: Command to execute
+ *	@p1: first parameter
+ *	@ret: adapter status
+ *
+ *	This routine will send a synchronous comamnd to the adapter and wait 
+ *	for its	completion.
+ */
+
+static int sa_sync_cmd(struct aac_dev *dev, unsigned long command, unsigned long p1, unsigned long *ret)
+{
+	unsigned long start;
+ 	int ok;
+	/*
+	 *	Write the Command into Mailbox 0
+	 */
+	sa_writel(dev, Mailbox0, cpu_to_le32(command));
+	/*
+	 *	Write the parameters into Mailboxes 1 - 4
+	 */
+	sa_writel(dev, Mailbox1, cpu_to_le32(p1));
+	sa_writel(dev, Mailbox2, 0);
+	sa_writel(dev, Mailbox3, 0);
+	sa_writel(dev, Mailbox4, 0);
+	/*
+	 *	Clear the synch command doorbell to start on a clean slate.
+	 */
+	sa_writew(dev, DoorbellClrReg_p, DOORBELL_0);
+	/*
+	 *	Signal that there is a new synch command
+	 */
+	sa_writew(dev, DoorbellReg_s, DOORBELL_0);
+
+	ok = 0;
+	start = jiffies;
+
+	while(time_before(jiffies, start+30*HZ))
+	{
+		/*
+		 *	Delay 5uS so that the monitor gets access
+		 */
+		udelay(5);
+		/*
+		 *	Mon110 will set doorbell0 bit when it has 
+		 *	completed the command.
+		 */
+		if(sa_readw(dev, DoorbellReg_p) & DOORBELL_0)  {
+			ok = 1;
+			break;
+		}
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+
+	if (ok != 1)
+		return -ETIMEDOUT;
+	/*
+	 *	Clear the synch command doorbell.
+	 */
+	sa_writew(dev, DoorbellClrReg_p, DOORBELL_0);
+	/*
+	 *	Pull the synch status from Mailbox 0.
+	 */
+	*ret = le32_to_cpu(sa_readl(dev, Mailbox0));
+	return 0;
+}
+
+/**
+ *	aac_sa_interrupt_adapter	-	interrupt an adapter
+ *	@dev: Which adapter to enable.
+ *
+ *	Breakpoint an adapter.
+ */
+ 
+static void aac_sa_interrupt_adapter (struct aac_dev *dev)
+{
+	unsigned long ret;
+	sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
+}
+
+/**
+ *	aac_sa_start_adapter		-	activate adapter
+ *	@dev:	Adapter
+ *
+ *	Start up processing on an ARM based AAC adapter
+ */
+
+static void aac_sa_start_adapter(struct aac_dev *dev)
+{
+	unsigned long ret;
+	struct aac_init *init;
+	/*
+	 * Fill in the remaining pieces of the init.
+	 */
+	init = dev->init;
+	init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ);
+
+	dprintk(("INIT\n"));
+	/*
+	 * Tell the adapter we are back and up and running so it will scan its command
+	 * queues and enable our interrupts
+	 */
+	dev->irq_mask =	(PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
+	/*
+	 *	First clear out all interrupts.  Then enable the one's that 
+	 *	we can handle.
+	 */
+	dprintk(("MASK\n"));
+	sa_writew(dev, SaDbCSR.PRISETIRQMASK, cpu_to_le16(0xffff));
+	sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
+	dprintk(("SYNCCMD\n"));
+	sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (unsigned long) dev->init_pa, &ret);
+}
+
+/**
+ *	aac_sa_init	-	initialize an ARM based AAC card
+ *	@dev: device to configure
+ *	@devnum: adapter number
+ *
+ *	Allocate and set up resources for the ARM based AAC variants. The 
+ *	device_interface in the commregion will be allocated and linked 
+ *	to the comm region.
+ */
+
+int aac_sa_init(struct aac_dev *dev, unsigned long devnum)
+{
+	unsigned long start;
+	unsigned long status;
+	int instance;
+	const char *name;
+
+	dev->devnum = devnum;
+
+	dprintk(("PREINST\n"));
+	instance = dev->id;
+	name     = dev->name;
+
+	/*
+	 *	Map in the registers from the adapter.
+	 */
+	dprintk(("PREMAP\n"));
+
+	if((dev->regs.sa = (struct sa_registers *)ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
+	{	
+		printk(KERN_WARNING "aacraid: unable to map ARM.\n" );
+		return -1;
+	}
+	/*
+	 *	Check to see if the board failed any self tests.
+	 */
+	if (sa_readl(dev, Mailbox7) & SELF_TEST_FAILED) {
+		printk(KERN_WARNING "%s%d: adapter self-test failed.\n", name, instance);
+		return -1;
+	}
+	/*
+	 *	Check to see if the board panic'd while booting.
+	 */
+	if (sa_readl(dev, Mailbox7) & KERNEL_PANIC) {
+		printk(KERN_WARNING "%s%d: adapter kernel panic'd.\n", name, instance);
+		return -1;
+	}
+	start = jiffies;
+	/*
+	 *	Wait for the adapter to be up and running. Wait up to 3 minutes.
+	 */
+	while (!(sa_readl(dev, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
+		if (time_after(start+180*HZ, jiffies)) {
+			status = sa_readl(dev, Mailbox7) >> 16;
+			printk(KERN_WARNING "%s%d: adapter kernel failed to start, init status = %d.\n", name, instance, le32_to_cpu(status));
+			return -1;
+		}
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+
+	dprintk(("ATIRQ\n"));
+	if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev ) < 0) {
+		printk(KERN_WARNING "%s%d: Interrupt unavailable.\n", name, instance);
+		return -1;
+	}
+
+	/*
+	 *	Fill in the function dispatch table.
+	 */
+
+	dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
+	dev->a_ops.adapter_enable_int = aac_sa_enable_interrupt;
+	dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
+	dev->a_ops.adapter_notify = aac_sa_notify_adapter;
+
+	dprintk(("FUNCDONE\n"));
+
+	if(aac_init_adapter(dev) == NULL)
+		return -1;
+
+	dprintk(("NEWADAPTDONE\n"));
+	/*
+	 *	Start any kernel threads needed
+	 */
+	dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
+	/*
+	 *	Tell the adapter that all is configure, and it can start 
+	 *	accepting requests
+	 */
+	dprintk(("STARTING\n"));
+	aac_sa_start_adapter(dev);
+	dprintk(("STARTED\n"));
+	return 0;
+}
+
diff -urN linux-2.4.17-pre6/drivers/scsi/dtc.c linux/drivers/scsi/dtc.c
--- linux-2.4.17-pre6/drivers/scsi/dtc.c	Sun Sep 30 12:26:07 2001
+++ linux/drivers/scsi/dtc.c	Sun Dec  9 12:40:05 2001
@@ -1,13 +1,11 @@
-
 #define AUTOSENSE
 #define PSEUDO_DMA
 #define DONT_USE_INTR
-#define UNSAFE		/* Leave interrupts enabled during pseudo-dma I/O */
+#define UNSAFE			/* Leave interrupts enabled during pseudo-dma I/O */
 #define xNDEBUG (NDEBUG_INTR+NDEBUG_RESELECTION+\
 		 NDEBUG_SELECTION+NDEBUG_ARBITRATION)
 #define DMA_WORKS_RIGHT
 
-
 /*
  * DTC 3180/3280 driver, by
  *	Ray Van Tassle	rayvt@comm.mot.com
@@ -65,6 +63,7 @@
  6 = yellow
  7 = white
 */
+
 #if 0
 #define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);}
 #else
@@ -102,336 +101,318 @@
  */
 
 /*
- */ 
+ */
 /* Offset from DTC_5380_OFFSET */
 #define DTC_CONTROL_REG		0x100	/* rw */
 #define D_CR_ACCESS		0x80	/* ro set=can access 3280 registers */
 #define CSR_DIR_READ		0x40	/* rw direction, 1 = read 0 = write */
 
-#define CSR_RESET              0x80    /* wo  Resets 53c400 */
-#define CSR_5380_REG           0x80    /* ro  5380 registers can be accessed */
-#define CSR_TRANS_DIR          0x40    /* rw  Data transfer direction */
-#define CSR_SCSI_BUFF_INTR     0x20    /* rw  Enable int on transfer ready */
-#define CSR_5380_INTR          0x10    /* rw  Enable 5380 interrupts */
-#define CSR_SHARED_INTR        0x08    /* rw  Interrupt sharing */
-#define CSR_HOST_BUF_NOT_RDY   0x04    /* ro  Host buffer not ready */
-#define CSR_SCSI_BUF_RDY       0x02    /* ro  SCSI buffer ready */
-#define CSR_GATED_5380_IRQ     0x01    /* ro  Last block xferred */
+#define CSR_RESET              0x80	/* wo  Resets 53c400 */
+#define CSR_5380_REG           0x80	/* ro  5380 registers can be accessed */
+#define CSR_TRANS_DIR          0x40	/* rw  Data transfer direction */
+#define CSR_SCSI_BUFF_INTR     0x20	/* rw  Enable int on transfer ready */
+#define CSR_5380_INTR          0x10	/* rw  Enable 5380 interrupts */
+#define CSR_SHARED_INTR        0x08	/* rw  Interrupt sharing */
+#define CSR_HOST_BUF_NOT_RDY   0x04	/* ro  Host buffer not ready */
+#define CSR_SCSI_BUF_RDY       0x02	/* ro  SCSI buffer ready */
+#define CSR_GATED_5380_IRQ     0x01	/* ro  Last block xferred */
 #define CSR_INT_BASE (CSR_SCSI_BUFF_INTR | CSR_5380_INTR)
 
 
-#define DTC_BLK_CNT		0x101   /* rw 
+#define DTC_BLK_CNT		0x101	/* rw 
 					 * # of 128-byte blocks to transfer */
 
 
-#define D_CR_ACCESS             0x80    /* ro set=can access 3280 registers */
+#define D_CR_ACCESS             0x80	/* ro set=can access 3280 registers */
 
 #define DTC_SWITCH_REG		0x3982	/* ro - DIP switches */
 #define DTC_RESUME_XFER		0x3982	/* wo - resume data xfer 
-					   * after disconnect/reconnect*/
+					   * after disconnect/reconnect */
 
 #define DTC_5380_OFFSET		0x3880	/* 8 registers here, see NCR5380.h */
 
 /*!!!! for dtc, it's a 128 byte buffer at 3900 !!! */
-#define DTC_DATA_BUF		0x3900  /* rw 128 bytes long */
+#define DTC_DATA_BUF		0x3900	/* rw 128 bytes long */
 
 static struct override {
-   unsigned int address;
-   int irq;
+	unsigned int address;
+	int irq;
 } overrides
 #ifdef OVERRIDE
 [] __initdata = OVERRIDE;
 #else
-[4] __initdata = {{0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}, {0, IRQ_AUTO}};
+[4] __initdata = { 
+	{0, IRQ_AUTO},
+	{0, IRQ_AUTO},
+	{0, IRQ_AUTO},
+	{0, IRQ_AUTO}
+};
 #endif
 
 #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
 
 static struct base {
-   unsigned long address;
-   int noauto;
-} bases[] __initdata = {{0xcc000, 0}, {0xc8000, 0}, {0xdc000, 0}, {0xd8000, 0}};
+	unsigned long address;
+	int noauto;
+} bases[] __initdata = {
+	{0xcc000, 0},
+	{0xc8000, 0},
+	{0xdc000, 0},
+	{0xd8000, 0}
+};
 
 #define NO_BASES (sizeof (bases) / sizeof (struct base))
 
 static const struct signature {
-   const char *string;
-   int offset;
-} signatures[] = { {"DATA TECHNOLOGY CORPORATION BIOS", 0x25}, };
+	const char *string;
+	int offset;
+} signatures[] = { 
+	{"DATA TECHNOLOGY CORPORATION BIOS", 0x25},
+};
 
 #define NO_SIGNATURES (sizeof (signatures) /  sizeof (struct signature))
 
-/*
- * Function : dtc_setup(char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- * 
- * Inputs : str - unused, ints - array of integer parameters with ints[0]
- *	equal to the number of ints.
+/**
+ *	dtc_setup	-	option setup for dtc3x80
  *
-*/
+ *	LILO command line initialization of the overrides array,
+ */
 
-void __init dtc_setup(char *str, int *ints){
-   static int commandline_current = 0;
-   int i;
-   if (ints[0] != 2)
-      printk("dtc_setup: usage dtc=address,irq\n");
-   else
-      if (commandline_current < NO_OVERRIDES) {
-      overrides[commandline_current].address = ints[1];
-      overrides[commandline_current].irq = ints[2];
-      for (i = 0; i < NO_BASES; ++i)
-	 if (bases[i].address == ints[1]) {
-	 bases[i].noauto = 1;
-	 break;
-      }
-      ++commandline_current;
-   }
+static int __init dtc_setup(char *str)
+{
+	static int commandline_current = 0;
+	int i;
+	int ints[10];
+
+	get_options(str, sizeof(ints) / sizeof(int), ints);
+	
+	if (ints[0] != 2)
+		printk(KERN_ERR "dtc_setup: usage dtc=address,irq\n");
+	else if (commandline_current < NO_OVERRIDES) {
+		overrides[commandline_current].address = ints[1];
+		overrides[commandline_current].irq = ints[2];
+		for (i = 0; i < NO_BASES; ++i)
+			if (bases[i].address == ints[1]) {
+				bases[i].noauto = 1;
+				break;
+			}
+		++commandline_current;
+	}
+	return 1;
 }
 
-/* 
- * Function : int dtc_detect(Scsi_Host_Template * tpnt)
+__setup("dtc=", dtc_setup);
+
+/**
+ *	dtc_detect	-	detect DTC 3x80 controllers
+ *	@tpnt: controller template
  *
- * Purpose : detects and initializes DTC 3180/3280 controllers
+ *	Detects and initializes DTC 3180/3280 controllers
  *	that were autoprobed, overridden on the LILO command line, 
  *	or specified at compile time.
- *
- * Inputs : tpnt - template for this SCSI adapter.
- * 
- * Returns : 1 if a host adapter was found, 0 if not.
- *
-*/
-
-int __init dtc_detect(Scsi_Host_Template * tpnt){
-   static int current_override = 0, current_base = 0;
-   struct Scsi_Host *instance;
-   unsigned int base;
-   int sig, count;
-
-   tpnt->proc_name = "dtc3x80";
-   tpnt->proc_info = &dtc_proc_info;
-
-   for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
-      base = 0;
-
-      if (overrides[current_override].address)
-	 base = overrides[current_override].address;
-      else
-	 for (; !base && (current_base < NO_BASES); ++current_base) {
-#if (DTCDEBUG & DTCDEBUG_INIT)
-	 printk("scsi-dtc : probing address %08x\n", bases[current_base].address);
-#endif
-	 for (sig = 0; sig < NO_SIGNATURES; ++sig)
-	    if (!bases[current_base].noauto && 
-		isa_check_signature(bases[current_base].address +
-				signatures[sig].offset,
-	      signatures[sig].string, strlen(signatures[sig].string))) {
-	    base = bases[current_base].address;
-#if (DTCDEBUG & DTCDEBUG_INIT)
-	    printk("scsi-dtc : detected board.\n");
-#endif
-	    break;
-	 }
-      }
-
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-      printk("scsi-dtc : base = %08x\n", base);
-#endif
-
-      if (!base)
-	 break;
+ */
 
-      instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
-      if(instance == NULL)
-      	break;
-      	
-      instance->base = base;
-
-      NCR5380_init(instance, 0);
-
-      NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */
-      if (overrides[current_override].irq != IRQ_AUTO)
-	 instance->irq = overrides[current_override].irq;
-      else
-	 instance->irq = NCR5380_probe_irq(instance, DTC_IRQS);
+int __init dtc_detect(Scsi_Host_Template * tpnt)
+{
+	static int current_override = 0, current_base = 0;
+	struct Scsi_Host *instance;
+	unsigned int base;
+	int sig, count;
+
+	tpnt->proc_name = "dtc3x80";
+	tpnt->proc_info = &dtc_proc_info;
+
+	for (count = 0; current_override < NO_OVERRIDES; ++current_override) 
+	{
+		base = 0;
+
+		if (overrides[current_override].address)
+			base = overrides[current_override].address;
+		else
+		{
+			for (; !base && (current_base < NO_BASES); ++current_base) {
+				for (sig = 0; sig < NO_SIGNATURES; ++sig)
+				{
+					if (!bases[current_base].noauto && isa_check_signature(bases[current_base].address + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
+						base = bases[current_base].address;
+						break;
+					}
+				}
+			}
+		}
+
+		if (!base)
+			break;
+
+		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
+		if (instance == NULL)
+			break;
+
+		instance->base = base;
+
+		NCR5380_init(instance, 0);
+
+		NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);	/* Enable int's */
+		if (overrides[current_override].irq != IRQ_AUTO)
+			instance->irq = overrides[current_override].irq;
+		else
+			instance->irq = NCR5380_probe_irq(instance, DTC_IRQS);
 
 #ifndef DONT_USE_INTR
-/* With interrupts enabled, it will sometimes hang when doing heavy
- * reads. So better not enable them until I finger it out. */
-      if (instance->irq != IRQ_NONE)
-	 if (request_irq(instance->irq, do_dtc_intr, SA_INTERRUPT, "dtc")) {
-	 printk("scsi%d : IRQ%d not free, interrupts disabled\n",
-	      instance->host_no, instance->irq);
-	 instance->irq = IRQ_NONE;
-      }
-
-      if (instance->irq == IRQ_NONE) {
-	 printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
-	 printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
-      }
+		/* With interrupts enabled, it will sometimes hang when doing heavy
+		 * reads. So better not enable them until I figure it out. */
+		if (instance->irq != IRQ_NONE)
+			if (request_irq(instance->irq, do_dtc_intr, SA_INTERRUPT, "dtc")) 
+			{
+				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
+				instance->irq = IRQ_NONE;
+			}
+
+		if (instance->irq == IRQ_NONE) {
+			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+			printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
+		}
 #else
-      if (instance->irq != IRQ_NONE)
-	 printk("scsi%d : interrupts not used. Might as well not jumper it.\n",
-		instance->host_no);
-      instance->irq = IRQ_NONE;
+		if (instance->irq != IRQ_NONE)
+			printk(KERN_INFO "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
+		instance->irq = IRQ_NONE;
 #endif
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
-      printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
-
-      printk("scsi%d : at 0x%05X", instance->host_no, (int)instance->base);
-      if (instance->irq == IRQ_NONE)
-	 printk (" interrupts disabled");
-      else
-	 printk (" irq %d", instance->irq);
-      printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
-	   CAN_QUEUE, CMD_PER_LUN, DTC_PUBLIC_RELEASE);
-      NCR5380_print_options(instance);
-      printk("\n");
-
-      ++current_override;
-      ++count;
-   }
-   return count;
+		printk(KERN_INFO "scsi%d : at 0x%05X", instance->host_no, (int) instance->base);
+		if (instance->irq == IRQ_NONE)
+			printk(" interrupts disabled");
+		else
+			printk(" irq %d", instance->irq);
+		printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, DTC_PUBLIC_RELEASE);
+		NCR5380_print_options(instance);
+		printk("\n");
+
+		++current_override;
+		++count;
+	}
+	return count;
 }
 
-/*
- * Function : int dtc_biosparam(Disk * disk, kdev_t dev, int *ip)
+/**
+ *	dtc_biosparam		-	compute disk geometry
+ *	@disk: disk to generate for
+ *	@dev: major/minor of device
+ *	@ip: returned geometry
  *
- * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
+ * 	Generates a BIOS / DOS compatible H-C-S mapping for 
  *	the specified device / size.
- * 
- * Inputs : size = size of device in sectors (512 bytes), dev = block device
- *	major / minor, ip[] = {heads, sectors, cylinders}  
- *
- * Returns : always 0 (success), initializes ip
- *	
-*/
-
-/* 
- * XXX Most SCSI boards use this mapping, I could be incorrect.  Some one
- * using hard disks on a trantor should verify that this mapping corresponds
- * to that used by the BIOS / ASPI driver by running the linux fdisk program
- * and matching the H_C_S coordinates to what DOS uses.
-*/
+ */
 
-int dtc_biosparam(Disk * disk, kdev_t dev, int * ip)
+int dtc_biosparam(Disk * disk, kdev_t dev, int *ip)
 {
-   int size = disk->capacity;
+	int size = disk->capacity;
 
-   ip[0] = 64;
-   ip[1] = 32;
-   ip[2] = size >> 11;
-   return 0;
+	ip[0] = 64;
+	ip[1] = 32;
+	ip[2] = size >> 11;
+	return 0;
 }
 
 
-/****************************************************************
- * Function : int NCR5380_pread (struct Scsi_Host *instance, 
- *	unsigned char *dst, int len)
- *
- * Purpose : Fast 5380 pseudo-dma read function, reads len bytes to 
- *	dst
- * 
- * Inputs : dst = destination, len = length in bytes
- *
- * Returns : 0 on success, non zero on a failure such as a watchdog 
- * 	timeout.
-*/
-
 static int dtc_maxi = 0;
 static int dtc_wmaxi = 0;
 
-static inline int NCR5380_pread (struct Scsi_Host *instance,
-     unsigned char *dst, int len)
-     {
-   unsigned char *d = dst;
-   int i;	/* For counting time spent in the poll-loop */
-   NCR5380_local_declare();
-   NCR5380_setup(instance);
-
-   i = 0;
-   NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-   NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
-   if (instance->irq == IRQ_NONE)
-      NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
-   else
-      NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ | CSR_INT_BASE);
-   NCR5380_write(DTC_BLK_CNT, len >> 7);        /* Block count */
-   rtrc(1);
-   while (len > 0) {
-      rtrc(2);
-      while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
-	 ++i;
-      rtrc(3);
-      isa_memcpy_fromio(d, base + DTC_DATA_BUF, 128);
-      d += 128;
-      len -= 128;
-      rtrc(7);	/*** with int's on, it sometimes hangs after here.
+/**
+ *	NCR5380_pread 		-	fast pseudo DMA read
+ *	@instance: controller
+ *	@dst: destination buffer
+ *	@len: expected/max size
+ *
+ *	Fast 5380 pseudo-dma read function, reads len bytes from the controller
+ *	mmio area into dst.
+ */
+
+static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+{
+	unsigned char *d = dst;
+	int i;			/* For counting time spent in the poll-loop */
+	NCR5380_local_declare();
+	NCR5380_setup(instance);
+
+	i = 0;
+	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+	NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
+	if (instance->irq == IRQ_NONE)
+		NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
+	else
+		NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ | CSR_INT_BASE);
+	NCR5380_write(DTC_BLK_CNT, len >> 7);	/* Block count */
+	rtrc(1);
+	while (len > 0) {
+		rtrc(2);
+		while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
+			++i;
+		rtrc(3);
+		isa_memcpy_fromio(d, base + DTC_DATA_BUF, 128);
+		d += 128;
+		len -= 128;
+		rtrc(7);
+		/*** with int's on, it sometimes hangs after here.
 		 * Looks like something makes HBNR go away. */
-   }
-   rtrc(4);
-   while ( !(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
-      ++i;
-   NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
-   rtrc(0);
-   NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-   if (i > dtc_maxi)
-      dtc_maxi = i;
-   return(0);
+	}
+	rtrc(4);
+	while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
+		++i;
+	NCR5380_write(MODE_REG, 0);	/* Clear the operating mode */
+	rtrc(0);
+	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+	if (i > dtc_maxi)
+		dtc_maxi = i;
+	return (0);
 }
 
-/****************************************************************
- * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 
- *	unsigned char *src, int len)
+/**
+ *	NCR5380_pwrite 		-	fast pseudo DMA write
+ *	@instance: controller
+ *	@dst: destination buffer
+ *	@len: expected/max size
  *
- * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
- *	src
- * 
- * Inputs : src = source, len = length in bytes
- *
- * Returns : 0 on success, non zero on a failure such as a watchdog 
- * 	timeout.
-*/
+ *	Fast 5380 pseudo-dma write function, writes len bytes to the
+ *	controller mmio area from src.
+ */
 
-static inline int NCR5380_pwrite (struct Scsi_Host *instance,
-     unsigned char *src, int len) {
-   int i;
-   NCR5380_local_declare();
-   NCR5380_setup(instance);
-
-   NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-   NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
-   /* set direction (write) */
-   if (instance->irq == IRQ_NONE)
-      NCR5380_write(DTC_CONTROL_REG, 0);
-   else
-      NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);
-   NCR5380_write(DTC_BLK_CNT, len >> 7);        /* Block count */
-   for (i = 0; len > 0; ++i) {
-      rtrc(5);
-      /* Poll until the host buffer can accept data. */
-      while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
-	 ++i;
-      rtrc(3);
-      isa_memcpy_toio(base + DTC_DATA_BUF, src, 128);
-      src += 128;
-      len -= 128;
-   }
-   rtrc(4);
-   while ( !(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
-      ++i;
-   rtrc(6);
-   /* Wait until the last byte has been sent to the disk */
-   while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
-      ++i;
-   rtrc(7);
-   /* Check for parity error here. fixme. */
-   NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
-   rtrc(0);
-   if (i > dtc_wmaxi)
-      dtc_wmaxi = i;
-   return (0);
+static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+{
+	int i;
+	NCR5380_local_declare();
+	NCR5380_setup(instance);
+
+	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
+	NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
+	/* set direction (write) */
+	if (instance->irq == IRQ_NONE)
+		NCR5380_write(DTC_CONTROL_REG, 0);
+	else
+		NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);
+	NCR5380_write(DTC_BLK_CNT, len >> 7);	/* Block count */
+	for (i = 0; len > 0; ++i) {
+		rtrc(5);
+		/* Poll until the host buffer can accept data. */
+		while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
+			++i;
+		rtrc(3);
+		isa_memcpy_toio(base + DTC_DATA_BUF, src, 128);
+		src += 128;
+		len -= 128;
+	}
+	rtrc(4);
+	while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
+		++i;
+	rtrc(6);
+	/* Wait until the last byte has been sent to the disk */
+	while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
+		++i;
+	rtrc(7);
+	/* Check for parity error here. fixme. */
+	NCR5380_write(MODE_REG, 0);	/* Clear the operating mode */
+	rtrc(0);
+	if (i > dtc_wmaxi)
+		dtc_wmaxi = i;
+	return (0);
 }
 
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.17-pre6/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- linux-2.4.17-pre6/drivers/scsi/fdomain.c	Sun Sep 30 12:26:07 2001
+++ linux/drivers/scsi/fdomain.c	Sun Dec  9 12:40:05 2001
@@ -983,7 +983,7 @@
       /* Register the IRQ with the kernel */
 
       retcode = request_irq( interrupt_level,
-			     do_fdomain_16x0_intr, pdev?SA_SHIRQ:0, "fdomain", NULL);
+			     do_fdomain_16x0_intr, pdev?SA_SHIRQ:0, "fdomain", shpnt);
 
       if (retcode < 0) {
 	 if (retcode == -EINVAL) {
@@ -2033,6 +2033,15 @@
    }
    
    return 0;
+}
+
+int fdomain_16x0_release(struct Scsi_Host *shpnt)
+{
+	if (shpnt->irq)
+		free_irq(shpnt->irq, shpnt);
+	if (shpnt->io_port && shpnt->n_io_port)
+		release_region(shpnt->io_port, shpnt->n_io_port);
+
 }
 
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.17-pre6/drivers/scsi/fdomain.h linux/drivers/scsi/fdomain.h
--- linux-2.4.17-pre6/drivers/scsi/fdomain.h	Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/fdomain.h	Sun Dec  9 12:40:05 2001
@@ -43,6 +43,7 @@
 		       abort:          fdomain_16x0_abort,               \
 		       reset:          fdomain_16x0_reset,               \
 		       bios_param:     fdomain_16x0_biosparam,           \
+		       release:        fdomain_16x0_release,		 \
 		       can_queue:      1, 				 \
 		       this_id:        6, 				 \
 		       sg_tablesize:   64, 				 \
diff -urN linux-2.4.17-pre6/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- linux-2.4.17-pre6/drivers/scsi/g_NCR5380.c	Sun Dec  9 12:39:27 2001
+++ linux/drivers/scsi/g_NCR5380.c	Sun Dec  9 12:40:05 2001
@@ -141,21 +141,21 @@
 #ifdef GENERIC_NCR5380_OVERRIDE
 [] __initdata = GENERIC_NCR5380_OVERRIDE;
 #else
-[1] __initdata = { {
-0,},};
+[1] __initdata = { { 0,},};
 #endif
 
 #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
 
-/*
- * Function : static internal_setup(int board, char *str, int *ints)
+/**
+ *	internal_setup		-	handle lilo command string override
+ *	@board:	BOARD_* identifier for the board
+ *	@str: unused
+ *	@ints: numeric parameters
  *
- * Purpose : LILO command line initialization of the overrides array,
- * 
- * Inputs : board - either BOARD_NCR5380 for a normal NCR5380 board, 
- * 	or BOARD_NCR53C400 for a NCR53C400 board. str - unused, ints - 
- *	array of integer parameters with ints[0] equal to the number of ints.
+ * 	Do LILO command line initialization of the overrides array. Display
+ *	errors when needed
  *
+ *	Locks: none
  */
 
 static void __init internal_setup(int board, char *str, int *ints)
@@ -164,19 +164,19 @@
 	switch (board) {
 	case BOARD_NCR5380:
 		if (ints[0] != 2 && ints[0] != 3) {
-			printk("generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
+			printk(KERN_ERR "generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
 			return;
 		}
 		break;
 	case BOARD_NCR53C400:
 		if (ints[0] != 2) {
-			printk("generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
+			printk(KERN_ERR "generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
 			return;
 		}
 		break;
 	case BOARD_NCR53C400A:
 		if (ints[0] != 2) {
-			printk("generic_NCR53C400A_setup : usage ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n");
+			printk(KERN_ERR "generic_NCR53C400A_setup : usage ncr53c400a=" STRVAL(NCR5380_map_name) ",irq\n");
 			return;
 		}
 		break;
@@ -200,84 +200,101 @@
 	}
 }
 
-/*
- * Function : generic_NCR5380_setup (char *str, int *ints)
+/**
+ * 	do_NCR53C80_setup		-	set up entry point
+ *	@str: unused
  *
- * Purpose : LILO command line initialization of the overrides array,
- * 
- * Inputs : str - unused, ints - array of integer parameters with ints[0] 
- * 	equal to the number of ints.
+ *	Setup function invoked at boot to parse the ncr5380= command
+ *	line.
  */
 
-void __init generic_NCR5380_setup(char *str, int *ints)
+static int __init do_NCR5380_setup(char *str)
 {
+	int ints[10];
+
+	get_options(str, sizeof(ints) / sizeof(int), ints);
 	internal_setup(BOARD_NCR5380, str, ints);
+	return 1;
 }
 
-/*
- * Function : generic_NCR53C400_setup (char *str, int *ints)
+/**
+ * 	do_NCR53C400_setup		-	set up entry point
+ *	@str: unused
+ *	@ints: integer parameters from kernel setup code 
  *
- * Purpose : LILO command line initialization of the overrides array,
- * 
- * Inputs : str - unused, ints - array of integer parameters with ints[0] 
- * 	equal to the number of ints.
+ *	Setup function invoked at boot to parse the ncr53c400= command
+ *	line.
  */
 
-void __init generic_NCR53C400_setup(char *str, int *ints)
+static int __init do_NCR53C400_setup(char *str)
 {
+	int ints[10];
+
+	get_options(str, sizeof(ints) / sizeof(int), ints);
 	internal_setup(BOARD_NCR53C400, str, ints);
+	return 1;
 }
 
-/*
- * Function : generic_NCR53C400A_setup (char *str, int *ints)
+/**
+ * 	do_NCR53C400A_setup	-	set up entry point
+ *	@str: unused
+ *	@ints: integer parameters from kernel setup code 
  *
- * Purpose : LILO command line initialization of the overrides array,
- * 
- * Inputs : str - unused, ints - array of integer parameters with ints[0] 
- * 	equal to the number of ints.
+ *	Setup function invoked at boot to parse the ncr53c400a= command
+ *	line.
  */
 
-void generic_NCR53C400A_setup(char *str, int *ints)
+static int __init do_NCR53C400A_setup(char *str)
 {
+	int ints[10];
+
+	get_options(str, sizeof(ints) / sizeof(int), ints);
 	internal_setup(BOARD_NCR53C400A, str, ints);
+	return 1;
 }
 
-/*
- * Function : generic_DTC3181E_setup (char *str, int *ints)
+/**
+ * 	do_DTC3181E_setup	-	set up entry point
+ *	@str: unused
+ *	@ints: integer parameters from kernel setup code 
  *
- * Purpose : LILO command line initialization of the overrides array,
- * 
- * Inputs : str - unused, ints - array of integer parameters with ints[0] 
- * 	equal to the number of ints.
+ *	Setup function invoked at boot to parse the dtc3181e= command
+ *	line.
  */
 
-void generic_DTC3181E_setup(char *str, int *ints)
+static int __init do_DTC3181E_setup(char *str)
 {
+	int ints[10];
+
+	get_options(str, sizeof(ints) / sizeof(int), ints);
 	internal_setup(BOARD_DTC3181E, str, ints);
+	return 1;
 }
 
-/* 
- * Function : int generic_NCR5380_detect(Scsi_Host_Template * tpnt)
- *
- * Purpose : initializes generic NCR5380 driver based on the 
- *	command line / compile time port and irq definitions.
+/**
+ * 	generic_NCR5380_detect	-	look for NCR5380 controllers
+ *	@tpnt: the scsi template
+ *
+ *	Scan for the present of NCR5380, NCR53C400, NCR53C400A, DTC3181E
+ *	and DTC436(ISAPnP) controllers. If overrides have been set we use
+ *	them.
  *
- * Inputs : tpnt - template for this SCSI adapter.
- * 
- * Returns : 1 if a host adapter was found, 0 if not.
+ *	The caller supplied NCR5380_init function is invoked from here, before
+ *	the interrupt line is taken.
  *
+ *	Locks: none
  */
 
 int __init generic_NCR5380_detect(Scsi_Host_Template * tpnt)
 {
 	static int current_override = 0;
 	int count, i;
-	u_int *ports;
-	u_int ncr_53c400a_ports[] = { 0x280, 0x290, 0x300, 0x310, 0x330,
-		0x340, 0x348, 0x350, 0
+	unsigned int *ports;
+	static unsigned int __initdata ncr_53c400a_ports[] = {
+		0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
 	};
-	u_int dtc_3181e_ports[] = { 0x220, 0x240, 0x280, 0x2a0, 0x2c0,
-		0x300, 0x320, 0x340, 0
+	static unsigned int __initdata dtc_3181e_ports[] = {
+		0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
 	};
 	int flags = 0;
 	struct Scsi_Host *instance;
@@ -415,16 +432,16 @@
 
 		if (instance->irq != IRQ_NONE)
 			if (request_irq(instance->irq, do_generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) {
-				printk("scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
+				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
 				instance->irq = IRQ_NONE;
 			}
 
 		if (instance->irq == IRQ_NONE) {
-			printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
-			printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
+			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+			printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
 		}
 
-		printk("scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int) instance->NCR5380_instance_name);
+		printk(KERN_INFO "scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int) instance->NCR5380_instance_name);
 		if (instance->irq == IRQ_NONE)
 			printk(" interrupts disabled");
 		else
@@ -439,16 +456,31 @@
 	return count;
 }
 
+/**
+ *	generic_NCR5380_info	-	reporting string
+ *	@host: NCR5380 to report on
+ *
+ *	Report driver information for the NCR5380
+ */
+ 	
 const char *generic_NCR5380_info(struct Scsi_Host *host)
 {
 	static const char string[] = "Generic NCR5380/53C400 Driver";
 	return string;
 }
 
+/**
+ *	generic_NCR5380_release_resources	-	free resources
+ *	@instance: host adapter to clean up 
+ *
+ *	Free the generic interface resources from this adapter.
+ *
+ *	Locks: none
+ */
+ 
 int generic_NCR5380_release_resources(struct Scsi_Host *instance)
 {
 	NCR5380_local_declare();
-
 	NCR5380_setup(instance);
 
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
@@ -464,24 +496,21 @@
 }
 
 #ifdef BIOSPARAM
-/*
- * Function : int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
+/**
+ *	generic_NCR5380_biosparam
+ *	@disk: disk to compute geometry for
+ *	@dev: device identifier for this disk
+ *	@ip: sizes to fill in
  *
- * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
- *	the specified device / size.
+ *	Generates a BIOS / DOS compatible H-C-S mapping for the specified 
+ *	device / size.
  * 
- * Inputs : size = size of device in sectors (512 bytes), dev = block device
- *	major / minor, ip[] = {heads, sectors, cylinders}  
+ * 	XXX Most SCSI boards use this mapping, I could be incorrect.  Someone
+ *	using hard disks on a trantor should verify that this mapping
+ *	corresponds to that used by the BIOS / ASPI driver by running the linux
+ *	fdisk program and matching the H_C_S coordinates to what DOS uses.
  *
- * Returns : always 0 (success), initializes ip
- *	
- */
-
-/* 
- * XXX Most SCSI boards use this mapping, I could be incorrect.  Some one
- * using hard disks on a trantor should verify that this mapping corresponds
- * to that used by the BIOS / ASPI driver by running the linux fdisk program
- * and matching the H_C_S coordinates to what DOS uses.
+ *	Locks: none
  */
 
 int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
@@ -495,59 +524,44 @@
 #endif
 
 #if NCR53C400_PSEUDO_DMA
+
+/**
+ *	NCR5380_pread		-	pseudo DMA read
+ *	@instance: adapter to read from
+ *	@dst: buffer to read into
+ *	@len: buffer length
+ *
+ *	Perform a psuedo DMA mode read from an NCR53C400 or equivalent
+ *	controller
+ */
+ 
 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
 {
 	int blocks = len / 128;
 	int start = 0;
 	int bl;
-#ifdef CONFIG_SCSI_G_NCR5380_PORT
-	int i;
-#endif
 
 	NCR5380_local_declare();
-
 	NCR5380_setup(instance);
 
-#if (NDEBUG & NDEBUG_C400_PREAD)
-	printk("53C400r: About to read %d blocks for %d bytes\n", blocks, len);
-#endif
-
 	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
 	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
 	while (1) {
-
-#if (NDEBUG & NDEBUG_C400_PREAD)
-		printk("53C400r: %d blocks left\n", blocks);
-#endif
-
 		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
-#if (NDEBUG & NDEBUG_C400_PREAD)
-			if (blocks)
-				printk("53C400r: blocks still == %d\n", blocks);
-			else
-				printk("53C400r: Exiting loop\n");
-#endif
 			break;
 		}
-#if 1
 		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
-			printk("53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
+			printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
 			return -1;
 		}
-#endif
-
-#if (NDEBUG & NDEBUG_C400_PREAD)
-		printk("53C400r: Waiting for buffer, bl=%d\n", bl);
-#endif
-
 		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
-#if (NDEBUG & NDEBUG_C400_PREAD)
-		printk("53C400r: Transferring 128 bytes\n");
-#endif
 
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-		for (i = 0; i < 128; i++)
-			dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
+		{
+			int i;
+			for (i = 0; i < 128; i++)
+				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
+		}
 #else
 		/* implies CONFIG_SCSI_G_NCR5380_MEM */
 		isa_memcpy_fromio(dst + start, NCR53C400_host_buffer + NCR5380_map_name, 128);
@@ -557,17 +571,17 @@
 	}
 
 	if (blocks) {
-#if (NDEBUG & NDEBUG_C400_PREAD)
-		printk("53C400r: EXTRA: Waiting for buffer\n");
-#endif
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
+		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+		{
+			// FIXME - no timeout
+		}
 
-#if (NDEBUG & NDEBUG_C400_PREAD)
-		printk("53C400r: Transferring EXTRA 128 bytes\n");
-#endif
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-		for (i = 0; i < 128; i++)
-			dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
+		{
+			int i;	
+			for (i = 0; i < 128; i++)
+				dst[start + i] = NCR5380_read(C400_HOST_BUFFER);
+		}
 #else
 		/* implies CONFIG_SCSI_G_NCR5380_MEM */
 		isa_memcpy_fromio(dst + start, NCR53C400_host_buffer + NCR5380_map_name, 128);
@@ -575,84 +589,64 @@
 		start += 128;
 		blocks--;
 	}
-#if (NDEBUG & NDEBUG_C400_PREAD)
-	else
-		printk("53C400r: No EXTRA required\n");
-#endif
-
-#if (NDEBUG & NDEBUG_C400_PREAD)
-	printk("53C400r: Final values: blocks=%d   start=%d\n", blocks, start);
-#endif
 
 	if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
 		printk("53C400r: no 53C80 gated irq after transfer");
-#if (NDEBUG & NDEBUG_C400_PREAD)
-	else
-		printk("53C400r: Got 53C80 interrupt and tried to clear it\n");
-#endif
-
-/* DON'T DO THIS - THEY NEVER ARRIVE!
-    printk("53C400r: Waiting for 53C80 registers\n");
-    while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
-	;
-*/
 
-	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
-		printk("53C400r: no end dma signal\n");
-#if (NDEBUG & NDEBUG_C400_PREAD)
-	else
-		printk("53C400r: end dma as expected\n");
+#if 0
+	/*
+	 *	DON'T DO THIS - THEY NEVER ARRIVE!
+	 */
+	printk("53C400r: Waiting for 53C80 registers\n");
+	while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
+		;
 #endif
-
+	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
+		printk(KERN_ERR "53C400r: no end dma signal\n");
+		
 	NCR5380_write(MODE_REG, MR_BASE);
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 	return 0;
 }
 
+/**
+ *	NCR5380_write		-	pseudo DMA write
+ *	@instance: adapter to read from
+ *	@dst: buffer to read into
+ *	@len: buffer length
+ *
+ *	Perform a psuedo DMA mode read from an NCR53C400 or equivalent
+ *	controller
+ */
+
 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
 {
 	int blocks = len / 128;
 	int start = 0;
-	int i;
 	int bl;
-	NCR5380_local_declare();
+	int i;
 
+	NCR5380_local_declare();
 	NCR5380_setup(instance);
 
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("53C400w: About to write %d blocks for %d bytes\n", blocks, len);
-#endif
-
 	NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
 	NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
 	while (1) {
 		if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
-			printk("53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
+			printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
 			return -1;
 		}
 
 		if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-			if (blocks)
-				printk("53C400w: exiting loop, blocks still == %d\n", blocks);
-			else
-				printk("53C400w: exiting loop\n");
-#endif
 			break;
 		}
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-		printk("53C400w: %d blocks left\n", blocks);
-
-		printk("53C400w: waiting for buffer, bl=%d\n", bl);
-#endif
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-		printk("53C400w: transferring 128 bytes\n");
-#endif
+		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+			; // FIXME - timeout
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-		for (i = 0; i < 128; i++)
-			NCR5380_write(C400_HOST_BUFFER, src[start + i]);
+		{
+			for (i = 0; i < 128; i++)
+				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
+		}
 #else
 		/* implies CONFIG_SCSI_G_NCR5380_MEM */
 		isa_memcpy_toio(NCR53C400_host_buffer + NCR5380_map_name, src + start, 128);
@@ -661,17 +655,14 @@
 		blocks--;
 	}
 	if (blocks) {
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-		printk("53C400w: EXTRA waiting for buffer\n");
-#endif
-		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY);
+		while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+			; // FIXME - no timeout
 
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-		printk("53C400w: transferring EXTRA 128 bytes\n");
-#endif
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-		for (i = 0; i < 128; i++)
-			NCR5380_write(C400_HOST_BUFFER, src[start + i]);
+		{
+			for (i = 0; i < 128; i++)
+				NCR5380_write(C400_HOST_BUFFER, src[start + i]);
+		}
 #else
 		/* implies CONFIG_SCSI_G_NCR5380_MEM */
 		isa_memcpy_toio(NCR53C400_host_buffer + NCR5380_map_name, src + start, 128);
@@ -679,14 +670,6 @@
 		start += 128;
 		blocks--;
 	}
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-	else
-		printk("53C400w: No EXTRA required\n");
-#endif
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("53C400w: Final values: blocks=%d   start=%d\n", blocks, start);
-#endif
 
 #if 0
 	printk("53C400w: waiting for registers to be available\n");
@@ -698,44 +681,34 @@
 	/* All documentation says to check for this. Maybe my hardware is too
 	 * fast. Waiting for it seems to work fine! KLL
 	 */
-	while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ));
+	while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
+		;	// FIXME - no timeout
 
 	/*
 	 * I know. i is certainly != 0 here but the loop is new. See previous
 	 * comment.
 	 */
 	if (i) {
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-		printk("53C400w: got 53C80 gated irq (last block)\n");
-#endif
 		if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
-			printk("53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-		else
-			printk("53C400w: Got END OF DMA\n");
-#endif
+			printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
 	} else
-		printk("53C400w: no 53C80 gated irq after transfer (last block)\n");
+		printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n");
 
 #if 0
 	if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
-		printk("53C400w: no end dma signal\n");
+		printk(KERN_ERR "53C400w: no end dma signal\n");
 	}
 #endif
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("53C400w: waiting for last byte...\n");
-#endif
-	while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
-	printk("53C400w:     got last byte.\n");
-	printk("53C400w: pwrite exiting with status 0, whoopee!\n");
-#endif
+	while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
+		; 	// TIMEOUT
 	return 0;
 }
 #endif				/* PSEUDO_DMA */
 
+/*
+ *	Include the NCR5380 core code that we build our driver around	
+ */
+ 
 #include "NCR5380.c"
 
 #define PRINTP(x) len += sprintf(buffer+len, x)
@@ -758,6 +731,15 @@
 	return len - start;
 }
 
+/**
+ *	sprintf_Scsi_Cmnd	-	print a scsi command
+ *	@buffer: buffr to print into
+ *	@len: buffer length
+ *	@cmd: SCSI command block
+ *	
+ *	Print out the target and command data in hex
+ */
+
 static int sprint_Scsi_Cmnd(char *buffer, int len, Scsi_Cmnd * cmd)
 {
 	int start = len;
@@ -767,6 +749,23 @@
 	return len - start;
 }
 
+/**
+ *	generic_NCR5380_proc_info	-	/proc for NCR5380 driver
+ *	@buffer: buffer to print into
+ *	@start: start position
+ *	@offset: offset into buffer
+ *	@len: length
+ *	@hostno: instance to affect
+ *	@inout: read/write
+ *
+ *	Provide the procfs information for the 5380 controller. We fill
+ *	this with useful debugging information including the commands
+ *	being executed, disconnected command queue and the statistical
+ *	data
+ *
+ *	Locks: global cli/lock for queue walk
+ */
+ 
 int generic_NCR5380_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
 {
 	int len = 0;
@@ -883,14 +882,14 @@
 #undef PRINTP
 #undef ANDP
 
-/* Eventually this will go into an include file, but this will be later */
+/*
+ *	Eventually this will go into an include file, but this will be later 
+ */
 static Scsi_Host_Template driver_template = GENERIC_NCR5380;
 
 #include <linux/module.h>
 #include "scsi_module.c"
 
-#ifdef MODULE
-
 MODULE_PARM(ncr_irq, "i");
 MODULE_PARM(ncr_dma, "i");
 MODULE_PARM(ncr_addr, "i");
@@ -899,17 +898,20 @@
 MODULE_PARM(ncr_53c400a, "i");
 MODULE_PARM(dtc_3181e, "i");
 MODULE_LICENSE("GPL");
-#else
 
-static int __init do_NCR5380_setup(char *str)
-{
-	int ints[10];
 
-	get_options(str, sizeof(ints) / sizeof(int), ints);
-	generic_NCR5380_setup(str, ints);
+static struct isapnp_device_id id_table[] __devinitdata = {
+	{
+	 ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+	 ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e),
+	 0},
+	{0}
+};
 
-	return 1;
-}
+MODULE_DEVICE_TABLE(isapnp, id_table);
+
+
+#ifndef MODULE
 
 static int __init do_NCR53C400_setup(char *str)
 {
@@ -945,17 +947,5 @@
 __setup("ncr53c400=", do_NCR53C400_setup);
 __setup("ncr53c400a=", do_NCR53C400A_setup);
 __setup("dtc3181e=", do_DTC3181E_setup);
-
-static struct isapnp_device_id id_table[] __devinitdata = {
-	{
-	 ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-	 ISAPNP_VENDOR('D', 'T', 'C'), ISAPNP_FUNCTION(0x436e),
-	 0},
-	{0}
-};
-
-MODULE_DEVICE_TABLE(isapnp, id_table);
-MODULE_LICENSE("GPL");
-
 
 #endif
diff -urN linux-2.4.17-pre6/drivers/scsi/g_NCR5380.h linux/drivers/scsi/g_NCR5380.h
--- linux-2.4.17-pre6/drivers/scsi/g_NCR5380.h	Sun Dec  9 12:39:27 2001
+++ linux/drivers/scsi/g_NCR5380.h	Sun Dec  9 12:40:05 2001
@@ -43,7 +43,6 @@
 #define NCR5380_BIOSPARAM NULL
 #endif
 
-#ifndef ASM
 int generic_NCR5380_abort(Scsi_Cmnd *);
 int generic_NCR5380_detect(Scsi_Host_Template *);
 int generic_NCR5380_release_resources(struct Scsi_Host *);
@@ -57,10 +56,6 @@
 
 int generic_NCR5380_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout);
 
-#ifndef NULL
-#define NULL 0
-#endif
-
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
 #endif
@@ -91,19 +86,15 @@
 #define STRVAL(x) __STRVAL(x)
 
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
-
 #define NCR5380_map_config port
-
 #define NCR5380_map_type int
-
 #define NCR5380_map_name port
-
 #define NCR5380_instance_name io_port
-
 #define NCR53C400_register_offset 0
-
 #define NCR53C400_address_adjust 8
-
+/*
+ *	FIXME: size should be runtime decided
+ */
 #ifdef NCR53C400
 #define NCR5380_region_size 16
 #else
@@ -117,24 +108,15 @@
 /* therefore CONFIG_SCSI_G_NCR5380_MEM */
 
 #define NCR5380_map_config memory
-
 #define NCR5380_map_type unsigned long
-
 #define NCR5380_map_name base
-
 #define NCR5380_instance_name base
-
 #define NCR53C400_register_offset 0x108
-
 #define NCR53C400_address_adjust 0
-
 #define NCR53C400_mem_base 0x3880
-
 #define NCR53C400_host_buffer 0x3900
-
 #define NCR5380_region_size 0x3a00
 
-
 #define NCR5380_read(reg) isa_readb(NCR5380_map_name + NCR53C400_mem_base + (reg))
 #define NCR5380_write(reg, value) isa_writeb(NCR5380_map_name + NCR53C400_mem_base + (reg), value)
 
@@ -164,5 +146,4 @@
 #define BOARD_DTC3181E	3
 
 #endif				/* else def HOSTS_C */
-#endif				/* ndef ASM */
 #endif				/* GENERIC_NCR5380_H */
diff -urN linux-2.4.17-pre6/drivers/scsi/pas16.c linux/drivers/scsi/pas16.c
--- linux-2.4.17-pre6/drivers/scsi/pas16.c	Sun Sep 30 12:26:07 2001
+++ linux/drivers/scsi/pas16.c	Sun Dec  9 12:40:05 2001
@@ -1,6 +1,6 @@
 #define AUTOSENSE
 #define PSEUDO_DMA
-#define FOO
+#define BOARD_REQUIRES_NO_UDELAY	/* PAS16 needs no I/O recovery delays */
 #define UNSAFE  /* Not unsafe for PAS16 -- use it */
 
 /*
diff -urN linux-2.4.17-pre6/drivers/scsi/t128.c linux/drivers/scsi/t128.c
--- linux-2.4.17-pre6/drivers/scsi/t128.c	Sun Sep 30 12:26:08 2001
+++ linux/drivers/scsi/t128.c	Sun Dec  9 12:40:05 2001
@@ -47,17 +47,12 @@
  * increase compared to polled I/O.
  *
  * PARITY - enable parity checking.  Not supported.
- * 
- * SCSI2 - enable support for SCSI-II tagged queueing.  Untested.
- *
  *
  * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.  You
  *          only really want to use this if you're having a problem with
  *          dropped characters during high speed communications, and even
  *          then, you're going to be better off twiddling with transfersize.
  *
- * USLEEP - enable support for devices that don't disconnect.  Untested.
- *
  * The card is detected and initialized in one of several ways : 
  * 1.  Autoprobe (default) - since the board is memory mapped, 
  *     a BIOS signature is scanned for to locate the registers.
@@ -101,10 +96,6 @@
  * 14 10-12
  * 15 9-11
  */
- 
-/*
- * $Log: t128.c,v $
- */
 
 #include <asm/system.h>
 #include <linux/signal.h>
@@ -123,276 +114,252 @@
 #include <linux/module.h>
 
 static struct override {
-    unsigned long address;
-    int irq;
-} overrides 
+	unsigned long address;
+	int irq;
+} overrides
 #ifdef T128_OVERRIDE
-    [] __initdata = T128_OVERRIDE;
+[] __initdata = T128_OVERRIDE;
 #else
-    [4] __initdata = {{0, IRQ_AUTO}, {0, IRQ_AUTO}, 
-        {0 ,IRQ_AUTO}, {0, IRQ_AUTO}};
+[4] __initdata = { 
+	{ 0, IRQ_AUTO},
+	{ 0, IRQ_AUTO},
+	{ 0, IRQ_AUTO},
+	{ 0, IRQ_AUTO}
+};
 #endif
 
 #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
 
 static struct base {
-    unsigned int address;
-    int noauto;
+	unsigned int address;
+	int noauto;
 } bases[] __initdata = {
-    { 0xcc000, 0}, { 0xc8000, 0}, { 0xdc000, 0}, { 0xd8000, 0}
+	{0xcc000, 0},
+	{0xc8000, 0},
+	{0xdc000, 0},
+	{0xd8000, 0}
 };
 
 #define NO_BASES (sizeof (bases) / sizeof (struct base))
 
 static const struct signature {
-    const char *string;
-    int offset;
+	const char *string;
+	int offset;
 } signatures[] __initdata = {
-{"TSROM: SCSI BIOS, Version 1.12", 0x36},
+	{"TSROM: SCSI BIOS, Version 1.12", 0x36},
 };
 
 #define NO_SIGNATURES (sizeof (signatures) /  sizeof (struct signature))
 
-/*
- * Function : t128_setup(char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- * 
- * Inputs : str - unused, ints - array of integer parameters with ints[0]
- *	equal to the number of ints.
+/**
+ *	t128_setup
+ *	@str: command line 
  *
+ *	LILO command line initialization of the overrides array,
  */
 
-void __init t128_setup(char *str, int *ints){
-    static int commandline_current = 0;
-    int i;
-    if (ints[0] != 2) 
-	printk("t128_setup : usage t128=address,irq\n");
-    else 
-	if (commandline_current < NO_OVERRIDES) {
-	    overrides[commandline_current].address = ints[1];
-	    overrides[commandline_current].irq = ints[2];
-	    for (i = 0; i < NO_BASES; ++i)
-		if (bases[i].address == ints[1]) {
-		    bases[i].noauto = 1;
-		    break;
-		}
-	    ++commandline_current;
+int __init t128_setup(char *str)
+{
+	static int commandline_current = 0;
+	int ints[10];
+	int i;
+	
+	get_options(str, sizeof(ints) / sizeof(int), ints);
+
+	if (ints[0] != 2)
+		printk(KERN_ERR "t128_setup : usage t128=address,irq\n");
+	else if (commandline_current < NO_OVERRIDES) {
+		overrides[commandline_current].address = ints[1];
+		overrides[commandline_current].irq = ints[2];
+		for (i = 0; i < NO_BASES; ++i)
+			if (bases[i].address == ints[1]) {
+				bases[i].noauto = 1;
+				break;
+			}
+		++commandline_current;
 	}
+	return 1;
 }
 
-/* 
- * Function : int t128_detect(Scsi_Host_Template * tpnt)
+__setup("t128=", t128_setup);
+
+/**
+ *	t128_detect	-	detect controllers
+ *	@tpnt: SCSI template
  *
- * Purpose : detects and initializes T128,T128F, or T228 controllers
+ *	Detects and initializes T128,T128F, or T228 controllers
  *	that were autoprobed, overridden on the LILO command line, 
  *	or specified at compile time.
- *
- * Inputs : tpnt - template for this SCSI adapter.
- * 
- * Returns : 1 if a host adapter was found, 0 if not.
- *
  */
 
-int __init t128_detect(Scsi_Host_Template * tpnt){
-    static int current_override = 0, current_base = 0;
-    struct Scsi_Host *instance;
-    unsigned long base;
-    int sig, count;
-
-    tpnt->proc_name = "t128";
-    tpnt->proc_info = &t128_proc_info;
-
-    for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
-	base = 0;
-
-	if (overrides[current_override].address)
-	    base = overrides[current_override].address;
-	else 
-	    for (; !base && (current_base < NO_BASES); ++current_base) {
-#if (TDEBUG & TDEBUG_INIT)
-    printk("scsi-t128 : probing address %08x\n", bases[current_base].address);
-#endif
-		for (sig = 0; sig < NO_SIGNATURES; ++sig) 
-		    if (!bases[current_base].noauto && 
-			isa_check_signature(bases[current_base].address +
-					signatures[sig].offset,
-					signatures[sig].string,
-					strlen(signatures[sig].string))) {
-			base = bases[current_base].address;
-#if (TDEBUG & TDEBUG_INIT)
-			printk("scsi-t128 : detected board.\n");
-#endif
+int __init t128_detect(Scsi_Host_Template * tpnt)
+{
+	static int current_override = 0, current_base = 0;
+	struct Scsi_Host *instance;
+	unsigned long base;
+	int sig, count;
+
+	tpnt->proc_name = "t128";
+	tpnt->proc_info = &t128_proc_info;
+
+	for (count = 0; current_override < NO_OVERRIDES; ++current_override) 
+	{
+		base = 0;
+
+		if (overrides[current_override].address)
+			base = overrides[current_override].address;
+		else
+			for (; !base && (current_base < NO_BASES); ++current_base) {
+				for (sig = 0; sig < NO_SIGNATURES; ++sig)
+					if (!bases[current_base].noauto &&
+					    isa_check_signature(bases[current_base].address + signatures[sig].offset,
+								signatures[sig].string,
+								strlen(signatures[sig].string)))
+					{
+						base = bases[current_base].address;
+						break;
+					}
+			}
+
+		if (!base)
 			break;
-		    }
-	    }
 
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-	printk("scsi-t128 : base = %08x\n", (unsigned int) base);
-#endif
+		instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
+		if (instance == NULL)
+			break;
 
-	if (!base)
-	    break;
+		instance->base = base;
 
-	instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
-	if(instance == NULL)
-		break;
-		
-	instance->base = base;
-
-	NCR5380_init(instance, 0);
-
-	if (overrides[current_override].irq != IRQ_AUTO)
-	    instance->irq = overrides[current_override].irq;
-	else 
-	    instance->irq = NCR5380_probe_irq(instance, T128_IRQS);
-
-	if (instance->irq != IRQ_NONE) 
-	    if (request_irq(instance->irq, do_t128_intr, SA_INTERRUPT, "t128", NULL)) {
-		printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
-		    instance->host_no, instance->irq);
-		instance->irq = IRQ_NONE;
-	    } 
-
-	if (instance->irq == IRQ_NONE) {
-	    printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
-	    printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
-	}
+		NCR5380_init(instance, 0);
 
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
-	printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+		if (overrides[current_override].irq != IRQ_AUTO)
+			instance->irq = overrides[current_override].irq;
+		else
+			instance->irq = NCR5380_probe_irq(instance, T128_IRQS);
+
+		if (instance->irq != IRQ_NONE)
+			if (request_irq(instance->irq, do_t128_intr, SA_INTERRUPT, "t128", NULL)) 
+			{
+				printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
+				instance->irq = IRQ_NONE;
+			}
+
+		if (instance->irq == IRQ_NONE) {
+			printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
+			printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
+		}
+
+		printk(KERN_INFO "scsi%d : at 0x%08lx", instance->host_no,instance->base);
+		if (instance->irq == IRQ_NONE)
+			printk(" interrupts disabled");
+		else
+			printk(" irq %d", instance->irq);
+		printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, T128_PUBLIC_RELEASE);
+		NCR5380_print_options(instance);
+		printk("\n");
 
-	printk("scsi%d : at 0x%08lx", instance->host_no, instance->base);
-	if (instance->irq == IRQ_NONE)
-	    printk (" interrupts disabled");
-	else 
-	    printk (" irq %d", instance->irq);
-	printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
-	    CAN_QUEUE, CMD_PER_LUN, T128_PUBLIC_RELEASE);
-	NCR5380_print_options(instance);
-	printk("\n");
-
-	++current_override;
-	++count;
-    }
-    return count;
+		++current_override;
+		++count;
+	}
+	return count;
 }
 
-/*
- * Function : int t128_biosparam(Disk * disk, kdev_t dev, int *ip)
+/**
+ *	t128_biosparam		-	disk geometry
+ *	@disk: device 
+ *	@dev: device major/minor
+ *	@ip: array to return results
  *
- * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
+ *	Generates a BIOS / DOS compatible H-C-S mapping for 
  *	the specified device / size.
  * 
- * Inputs : size = size of device in sectors (512 bytes), dev = block device
- *	major / minor, ip[] = {heads, sectors, cylinders}  
- *
- * Returns : always 0 (success), initializes ip
- *	
+ *	Most SCSI boards use this mapping, I could be incorrect.  Some one
+ *	using hard disks on a trantor should verify that this mapping
+ *	corresponds to that used by the BIOS / ASPI driver by running the
+ *	linux fdisk program and matching the H_C_S coordinates to those
+ *	that DOS uses.
  */
 
-/* 
- * XXX Most SCSI boards use this mapping, I could be incorrect.  Some one
- * using hard disks on a trantor should verify that this mapping corresponds
- * to that used by the BIOS / ASPI driver by running the linux fdisk program
- * and matching the H_C_S coordinates to what DOS uses.
- */
-
-int t128_biosparam(Disk * disk, kdev_t dev, int * ip)
+int t128_biosparam(Disk * disk, kdev_t dev, int *ip)
 {
-  int size = disk->capacity;
-  ip[0] = 64;
-  ip[1] = 32;
-  ip[2] = size >> 11;
-  return 0;
+	int size = disk->capacity;
+	ip[0] = 64;
+	ip[1] = 32;
+	ip[2] = size >> 11;
+	return 0;
 }
 
-/*
- * Function : int NCR5380_pread (struct Scsi_Host *instance, 
- *	unsigned char *dst, int len)
+/**
+ *	NCR5380_pread		-	pseudo DMA read
+ *	@instance: controller
+ *	@dst: buffer to write to
+ *	@len: expect/max length
  *
- * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to 
- *	dst
- * 
- * Inputs : dst = destination, len = length in bytes
- *
- * Returns : 0 on success, non zero on a failure such as a watchdog 
- * 	timeout.
+ *	Fast 5380 pseudo-dma read function, transfers len bytes to 
+ *	dst from the controller.
  */
 
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
-    int len) {
-    unsigned long reg = instance->base + T_DATA_REG_OFFSET;
-    unsigned char *d = dst;
-    register int i = len;
-
-
-#if 0
-    for (; i; --i) {
-	while (!(isa_readb(instance->base+T_STATUS_REG_OFFSET) & T_ST_RDY)) barrier();
-#else
-    while (!(isa_readb(instance->base+T_STATUS_REG_OFFSET) & T_ST_RDY)) barrier();
-    for (; i; --i) {
-#endif
-	*d++ = isa_readb(reg);
-    }
+static inline int NCR5380_pread(struct Scsi_Host *instance,
+				unsigned char *dst, int len)
+{
+	unsigned long reg = instance->base + T_DATA_REG_OFFSET;
+	unsigned char *d = dst;
+	int i = len;
+
+	while (!(isa_readb(instance->base + T_STATUS_REG_OFFSET) & T_ST_RDY))
+	       	barrier();
+	for (; i; --i) {
+		*d++ = isa_readb(reg);
+	}
 
-    if (isa_readb(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
-	unsigned char tmp;
-	unsigned long foo;
-	foo = instance->base + T_CONTROL_REG_OFFSET;
-	tmp = isa_readb(foo);
-	isa_writeb(tmp | T_CR_CT, foo);
-	isa_writeb(tmp, foo);
-	printk("scsi%d : watchdog timer fired in NCR5380_pread()\n",
-	    instance->host_no);
-	return -1;
-    } else
-	return 0;
+	if (isa_readb(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
+		unsigned char tmp;
+		unsigned long foo;
+		foo = instance->base + T_CONTROL_REG_OFFSET;
+		tmp = isa_readb(foo);
+		isa_writeb(tmp | T_CR_CT, foo);
+		isa_writeb(tmp, foo);
+		printk(KERN_ERR "scsi%d : watchdog timer fired in t128 NCR5380_pread.\n", instance->host_no);
+		return -1;
+	} else
+		return 0;
 }
 
-/*
- * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 
- *	unsigned char *src, int len)
+/**
+ *	NCR5380_pwrite		-	pseudo DMA write
+ *	@instance: controller
+ *	@dst: buffer to write to
+ *	@len: expect/max length
  *
- * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
- *	src
- * 
- * Inputs : src = source, len = length in bytes
- *
- * Returns : 0 on success, non zero on a failure such as a watchdog 
- * 	timeout.
+ *	Fast 5380 pseudo-dma write function, transfers len bytes from
+ *	dst to the controller.
  */
 
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
-    int len) {
-    unsigned long reg = instance->base + T_DATA_REG_OFFSET;
-    unsigned char *s = src;
-    register int i = len;
-
-#if 0
-    for (; i; --i) {
-	while (!(isa_readb(instance->base+T_STATUS_REG_OFFSET) & T_ST_RDY)) barrier();
-#else
-    while (!(isa_readb(instance->base+T_STATUS_REG_OFFSET) & T_ST_RDY)) barrier();
-    for (; i; --i) {
-#endif
-	isa_writeb(*s++, reg);
-    }
 
-    if (isa_readb(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
-	unsigned char tmp;
-	unsigned long foo;
-	foo = instance->base + T_CONTROL_REG_OFFSET;
-	tmp = isa_readb(foo);
-	isa_writeb(tmp | T_CR_CT, foo);
-	isa_writeb(tmp, foo);
-	printk("scsi%d : watchdog timer fired in NCR5380_pwrite()\n",
-	    instance->host_no);
-	return -1;
-    } else 
-	return 0;
+static inline int NCR5380_pwrite(struct Scsi_Host *instance,
+				 unsigned char *src, int len)
+{
+	unsigned long reg = instance->base + T_DATA_REG_OFFSET;
+	unsigned char *s = src;
+	int i = len;
+
+	while (!(isa_readb(instance->base + T_STATUS_REG_OFFSET) & T_ST_RDY))
+		barrier();
+	for (; i; --i) {
+		isa_writeb(*s++, reg);
+	}
+
+	if (isa_readb(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
+		unsigned char tmp;
+		unsigned long foo;
+		foo = instance->base + T_CONTROL_REG_OFFSET;
+		tmp = isa_readb(foo);
+		isa_writeb(tmp | T_CR_CT, foo);
+		isa_writeb(tmp, foo);
+		printk(KERN_ERR "scsi%d : watchdog timer fired in t128 NCR5380_pwrite()\n", instance->host_no);
+		return -1;
+	} else
+		return 0;
 }
 
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.17-pre6/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- linux-2.4.17-pre6/drivers/sound/ymfpci.c	Sun Dec  9 12:39:28 2001
+++ linux/drivers/sound/ymfpci.c	Sun Dec  9 12:40:05 2001
@@ -2203,12 +2203,15 @@
 {
 	u8 cmd;
 
+	/*
+	 * In the 744, 754 only 0x01 exists, 0x02 is undefined.
+	 * It does not seem to hurt to trip both regardless of revision.
+	 */
 	pci_read_config_byte(pci, PCIR_DSXGCTRL, &cmd);
-	if (cmd & 0x03) {
-		pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
-		pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd | 0x03);
-		pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
-	}
+	pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
+	pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd | 0x03);
+	pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
+
 	pci_write_config_word(pci, PCIR_DSXPWRCTRL1, 0);
 	pci_write_config_word(pci, PCIR_DSXPWRCTRL2, 0);
 }
diff -urN linux-2.4.17-pre6/drivers/usb/CDCEther.c linux/drivers/usb/CDCEther.c
--- linux-2.4.17-pre6/drivers/usb/CDCEther.c	Fri Oct  5 12:06:08 2001
+++ linux/drivers/usb/CDCEther.c	Sun Dec  9 12:40:05 2001
@@ -337,13 +337,9 @@
 	ether_dev_t *ether_dev = (ether_dev_t *)net->priv;
 	int	res;
 
-	// We are finally getting used!
-	MOD_INC_USE_COUNT;
-
 	// Turn on the USB and let the packets flow!!!
 	if ( (res = enable_net_traffic( ether_dev )) ) {
 		err( __FUNCTION__ "can't enable_net_traffic() - %d", res );
-		MOD_DEC_USE_COUNT;
 		return -EIO;
 	}
 
@@ -391,9 +387,6 @@
 	usb_unlink_urb( &ether_dev->tx_urb );
 	usb_unlink_urb( &ether_dev->intr_urb );
 	
-	// We are not being used now.
-	MOD_DEC_USE_COUNT;
-
 	// That's it.  I'm done.
 	return 0;
 }
@@ -480,6 +473,7 @@
                      i++, mclist = mclist->next) {
 			memcpy(&mclist->dmi_addr, &buff[i * 6], 6);
 		}
+#if 0
 		usb_control_msg(ether_dev->usb,
 				usb_sndctrlpipe(ether_dev->usb, 0),
 				SET_ETHERNET_MULTICAST_FILTER, /* request */
@@ -489,11 +483,13 @@
 				buff,
 				(6* net->mc_count), /* size */
 				HZ); /* timeout */
+#endif
 		kfree(buff);
 	}
- 
+
+#if 0 
 	CDC_SetEthernetPacketFilter(ether_dev);
-	
+#endif	
         // Tell the kernel to start giving frames to us again.
 	netif_wake_queue(net);
 }
@@ -1210,6 +1206,7 @@
 	// Now that we have an ethernet device, let's set it up
 	// (And I don't mean "set [it] up the bomb".)
 	net->priv = ether_dev;
+	SET_MODULE_OWNER(net);
 	net->open = CDCEther_open;
 	net->stop = CDCEther_close;
 	net->watchdog_timeo = CDC_ETHER_TX_TIMEOUT;
diff -urN linux-2.4.17-pre6/drivers/usb/audio.c linux/drivers/usb/audio.c
--- linux-2.4.17-pre6/drivers/usb/audio.c	Fri Oct  5 12:04:50 2001
+++ linux/drivers/usb/audio.c	Sun Dec  9 12:40:05 2001
@@ -3362,28 +3362,48 @@
 	struct usb_device *dev = state->s->usbdev;
 	unsigned char data[1];
 #endif
+	unsigned char nr_logical_channels, i;
 
 	usb_audio_recurseunit(state, ftr[4]);
+
+	if (ftr[5] == 0 ) {
+		printk(KERN_ERR "usbaudio: wrong controls size in feature unit %u\n",ftr[3]);
+		return;
+	}
+
 	if (state->nrchannels == 0) {
 		printk(KERN_ERR "usbaudio: feature unit %u source has no channels\n", ftr[3]);
 		return;
 	}
 	if (state->nrchannels > 2)
 		printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]);
-	if (state->nrchannels == 1 && ftr[0] == 7+ftr[5]) {
-		printk(KERN_DEBUG "usbaudio: workaround for Philips camera microphone descriptor enabled\n");
-		mchftr = ftr[6];
-		chftr = 0;
-	} else {
-		if (ftr[0] < 7+ftr[5]*(1+state->nrchannels)) {
-			printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]);
-			return;
+
+		nr_logical_channels=(ftr[0]-7)/ftr[5]-1;
+
+		if (nr_logical_channels != state->nrchannels) {
+			printk(KERN_WARNING "usbaudio: warning: found %d of %d logical channels.\n", state->nrchannels,nr_logical_channels);
+
+		if (state->nrchannels == 1 && nr_logical_channels==0) {
+			printk(KERN_INFO "usbaudio: assuming the channel found is the master channel (got a Philips camera?). Should be fine.\n");
+		} else if (state->nrchannels == 1 && nr_logical_channels==2) {
+			printk(KERN_INFO "usbaudio: assuming that a stereo channel connected directly to a mixer is missing in search (got Labtec headset?). Should be fine.\n");
+			state->nrchannels=nr_logical_channels;
+		} else {
+			printk(KERN_WARNING "usbaudio: no idea what's going on..., contact linux-usb-devel@lists.sourceforge.net\n");
 		}
-		mchftr = ftr[6];
+	}
+
+	/* There is always a master channel */
+	mchftr = ftr[6];
+	/* Binary AND over logical channels if they exist */
+	if (nr_logical_channels) {
 		chftr = ftr[6+ftr[5]];
-		if (state->nrchannels > 1)
-			chftr &= ftr[6+2*ftr[5]];
+		for (i = 2; i <= nr_logical_channels; i++)
+			chftr &= ftr[6+i*ftr[5]];
+	} else {
+		chftr = 0;
 	}
+
 	/* volume control */
 	if (chftr & 2) {
 		ch = getmixchannel(state, getvolchannel(state));
diff -urN linux-2.4.17-pre6/drivers/usb/pegasus.c linux/drivers/usb/pegasus.c
--- linux-2.4.17-pre6/drivers/usb/pegasus.c	Fri Sep 14 14:04:07 2001
+++ linux/drivers/usb/pegasus.c	Sun Dec  9 12:40:05 2001
@@ -53,7 +53,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.4.21 (2001/08/27)"
+#define DRIVER_VERSION "v0.4.22 (2001/12/07)"
 #define DRIVER_AUTHOR "Petko Manolov <pmanolov@lnxw.com>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -713,10 +713,8 @@
 	pegasus_t *pegasus = (pegasus_t *)net->priv;
 	int	res;
 
-	MOD_INC_USE_COUNT;
 	if ( (res = enable_net_traffic(net, pegasus->usb)) ) {
 		err("can't enable_net_traffic() - %d", res);
-		MOD_DEC_USE_COUNT;
 		return -EIO;
 	}
 	FILL_BULK_URB( &pegasus->rx_urb, pegasus->usb,
@@ -755,7 +753,6 @@
 #ifdef	PEGASUS_USE_INTR
 	usb_unlink_urb( &pegasus->intr_urb );
 #endif
-	MOD_DEC_USE_COUNT;
 
 	return 0;
 }
@@ -867,6 +864,7 @@
 	
 	pegasus->usb = dev;
 	pegasus->net = net;
+	SET_MODULE_OWNER(net);
 	net->priv = pegasus;
 	net->open = pegasus_open;
 	net->stop = pegasus_close;
diff -urN linux-2.4.17-pre6/drivers/usb/pegasus.h linux/drivers/usb/pegasus.h
--- linux-2.4.17-pre6/drivers/usb/pegasus.h	Wed Oct 17 14:34:06 2001
+++ linux/drivers/usb/pegasus.h	Sun Dec  9 12:40:05 2001
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg)
+ *  Copyright (c) 1999,2000 Petko Manolov - Petkan (pmanolov@lnxw.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
@@ -138,6 +138,7 @@
 #define	VENDOR_DLINK		0x2001
 #define	VENDOR_ELSA		0x05cc
 #define	VENDOR_IODATA		0x04bb
+#define	VENDOR_KINGSTON		0x0951
 #define	VENDOR_LANEED		0x056e
 #define	VENDOR_LINKSYS		0x066b
 #define	VENDOR_MELCO		0x0411
@@ -210,6 +211,8 @@
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
+		DEFAULT_GPIO_RESET)
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
diff -urN linux-2.4.17-pre6/drivers/usb/serial/mct_u232.c linux/drivers/usb/serial/mct_u232.c
--- linux-2.4.17-pre6/drivers/usb/serial/mct_u232.c	Sun Dec  9 12:39:28 2001
+++ linux/drivers/usb/serial/mct_u232.c	Sun Dec  9 12:40:05 2001
@@ -27,6 +27,9 @@
  * 10-Nov-2001 Wolfgang Grandegger
  *   - Fixed an endianess problem with the baudrate selection for PowerPC.
  *
+ * 06-Dec-2001 Martin Hamilton <martinh@gnu.org>
+ *	Added support for the Belkin F5U109 DB9 adaptor
+ *
  * 30-May-2001 Greg Kroah-Hartman
  *	switched from using spinlock to a semaphore, which fixes lots of problems.
  *
@@ -133,11 +136,13 @@
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
+	{ USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
 	{ }		/* Terminating entry */
 };
 
 static __devinitdata struct usb_device_id mct_u232_table [] = {
         { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
+	{ USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
         { }                        /* Terminating entry */
 };
 
@@ -243,7 +248,8 @@
 #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
 
 static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) {
-	if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID) {
+	if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID
+	  || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) {
 		switch (value) {
 			case    300: return 0x01;
 			case    600: return 0x02; /* this one not tested */
diff -urN linux-2.4.17-pre6/drivers/usb/serial/mct_u232.h linux/drivers/usb/serial/mct_u232.h
--- linux-2.4.17-pre6/drivers/usb/serial/mct_u232.h	Thu Feb  8 16:30:40 2001
+++ linux/drivers/usb/serial/mct_u232.h	Sun Dec  9 12:40:05 2001
@@ -30,9 +30,12 @@
 #define MCT_U232_SITECOM_PID		0x0230	/* Sitecom Product Id */
 
 /* DU-H3SP USB BAY hub */
-
 #define MCT_U232_DU_H3SP_PID		0x0200	/* D-Link DU-H3SP USB BAY */
 
+/* Belkin badge the MCT U232-P9 as the F5U109 */
+#define MCT_U232_BELKIN_F5U109_VID	0x050d	/* Vendor Id */
+#define MCT_U232_BELKIN_F5U109_PID	0x0109	/* Product Id */
+
 /*
  * Vendor Request Interface
  */
@@ -363,6 +366,25 @@
  * 	  bmAttributes        =   03 (Interrupt)
  * 	  wMaxPacketSize      = 0002
  * 	  bInterval           =   02
+ *
+ *
+ * Hardware details (added by Martin Hamilton, 2001/12/06)
+ * -----------------------------------------------------------------
+ *
+ * This info was gleaned from opening a Belkin F5U109 DB9 USB serial
+ * adaptor, which turns out to simply be a re-badged U232-P9.  We
+ * know this because there is a sticky label on the circuit board
+ * which says "U232-P9" ;-)
+ * 
+ * The circuit board inside the adaptor contains a Philips PDIUSBD12
+ * USB endpoint chip and a Phillips P87C52UBAA microcontroller with
+ * embedded UART.  Exhaustive documentation for these is available at:
+ *
+ *   http://www.semiconductors.philips.com/pip/p87c52ubaa
+ *   http://www.semiconductors.philips.com/pip/pdiusbd12
+ *
+ * Thanks to Julian Highfield for the pointer to the Philips database.
+ * 
  */
 
 #endif /* __LINUX_USB_SERIAL_MCT_U232_H */
diff -urN linux-2.4.17-pre6/include/linux/isdn/tpam.h linux/include/linux/isdn/tpam.h
--- linux-2.4.17-pre6/include/linux/isdn/tpam.h	Mon Jul  2 14:07:55 2001
+++ linux/include/linux/isdn/tpam.h	Sun Dec  9 12:40:06 2001
@@ -1,4 +1,4 @@
-/* $Id: tpam.h,v 1.1.2.1 2001/06/08 08:23:46 kai Exp $
+/* $Id: tpam.h,v 1.1.2.1 2001/11/20 14:19:38 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver)
  *
diff -urN linux-2.4.17-pre6/include/linux/isdn.h linux/include/linux/isdn.h
--- linux-2.4.17-pre6/include/linux/isdn.h	Sun Sep 30 12:26:42 2001
+++ linux/include/linux/isdn.h	Sun Dec  9 12:40:06 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn.h,v 1.111.6.9 2001/09/23 22:25:05 kai Exp $
+/* $Id: isdn.h,v 1.1.4.1 2001/11/20 14:19:38 kai Exp $
  *
  * Main header for the Linux ISDN subsystem (linklevel).
  *
diff -urN linux-2.4.17-pre6/include/linux/isdn_divertif.h linux/include/linux/isdn_divertif.h
--- linux-2.4.17-pre6/include/linux/isdn_divertif.h	Sun Sep 30 12:26:42 2001
+++ linux/include/linux/isdn_divertif.h	Sun Dec  9 12:40:06 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_divertif.h,v 1.4.6.1 2001/09/23 22:25:05 kai Exp $
+/* $Id: isdn_divertif.h,v 1.1.4.1 2001/11/20 14:19:38 kai Exp $
  *
  * Header for the diversion supplementary interface for i4l.
  *
diff -urN linux-2.4.17-pre6/include/linux/isdn_lzscomp.h linux/include/linux/isdn_lzscomp.h
--- linux-2.4.17-pre6/include/linux/isdn_lzscomp.h	Sun Sep 30 12:26:42 2001
+++ linux/include/linux/isdn_lzscomp.h	Sun Dec  9 12:40:06 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_lzscomp.h,v 1.1.10.1 2001/09/23 22:25:05 kai Exp $
+/* $Id: isdn_lzscomp.h,v 1.1.4.1 2001/11/20 14:19:38 kai Exp $
  *
  * Header for isdn_lzscomp.c
  * Concentrated here to not mess up half a dozen kernel headers with code
diff -urN linux-2.4.17-pre6/include/linux/isdnif.h linux/include/linux/isdnif.h
--- linux-2.4.17-pre6/include/linux/isdnif.h	Sun Sep 30 12:26:42 2001
+++ linux/include/linux/isdnif.h	Sun Dec  9 12:40:06 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnif.h,v 1.37.6.6 2001/09/23 22:25:05 kai Exp $
+/* $Id: isdnif.h,v 1.1.4.1 2001/11/20 14:19:38 kai Exp $
  *
  * Linux ISDN subsystem
  * Definition of the interface between the subsystem and its low-level drivers.
diff -urN linux-2.4.17-pre6/ipc/shm.c linux/ipc/shm.c
--- linux-2.4.17-pre6/ipc/shm.c	Wed Oct 17 14:16:39 2001
+++ linux/ipc/shm.c	Sun Dec  9 12:40:06 2001
@@ -569,6 +569,7 @@
 {
 	struct shmid_kernel *shp;
 	unsigned long addr;
+	unsigned long size;
 	struct file * file;
 	int    err;
 	unsigned long flags;
@@ -588,8 +589,12 @@
 				return -EINVAL;
 		}
 		flags = MAP_SHARED | MAP_FIXED;
-	} else
+	} else {
+		if ((shmflg & SHM_REMAP))
+			return -EINVAL;
+
 		flags = MAP_SHARED;
+	}
 
 	if (shmflg & SHM_RDONLY) {
 		prot = PROT_READ;
@@ -603,7 +608,7 @@
 
 	/*
 	 * We cannot rely on the fs check since SYSV IPC does have an
-	 * aditional creator id...
+	 * additional creator id...
 	 */
 	shp = shm_lock(shmid);
 	if(shp == NULL)
@@ -618,11 +623,27 @@
 		return -EACCES;
 	}
 	file = shp->shm_file;
+	size = file->f_dentry->d_inode->i_size;
 	shp->shm_nattch++;
 	shm_unlock(shmid);
 
 	down_write(&current->mm->mmap_sem);
-	user_addr = (void *) do_mmap (file, addr, file->f_dentry->d_inode->i_size, prot, flags, 0);
+	if (addr && !(shmflg & SHM_REMAP)) {
+		user_addr = ERR_PTR(-EINVAL);
+		if (find_vma_intersection(current->mm, addr, addr + size))
+			goto invalid;
+		/*
+		 * If shm segment goes below stack, make sure there is some
+		 * space left for the stack to grow (at least 4 pages).
+		 */
+		if (addr < current->mm->start_stack &&
+		    addr > current->mm->start_stack - size - PAGE_SIZE * 5)
+			goto invalid;
+	}
+		
+	user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0);
+
+invalid:
 	up_write(&current->mm->mmap_sem);
 
 	down (&shm_ids.sem);
