Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/MAINTAINERS                           |   14 
 25-akpm/drivers/message/fusion/isense.c       |    8 
 25-akpm/drivers/message/fusion/linux_compat.h |  189 --
 25-akpm/drivers/message/fusion/mptbase.c      |   18 
 25-akpm/drivers/message/fusion/mptbase.h      |   10 
 25-akpm/drivers/message/fusion/mptctl.c       |   68 
 25-akpm/drivers/message/fusion/mptlan.c       |   19 
 25-akpm/drivers/message/fusion/mptscsih.c     |   73 
 25-akpm/drivers/message/fusion/mptscsih.h     |   71 
 25-akpm/drivers/message/i2o/i2o_block.c       |    8 
 25-akpm/drivers/message/i2o/i2o_config.c      |    2 
 25-akpm/drivers/message/i2o/i2o_core.c        |  159 +
 25-akpm/drivers/message/i2o/i2o_scsi.c        |   97 -
 25-akpm/drivers/scsi/3w-9xxx.c                | 2153 ++++++++++++++++++++++++++
 25-akpm/drivers/scsi/3w-9xxx.h                |  704 ++++++++
 25-akpm/drivers/scsi/3w-xxxx.c                |    2 
 25-akpm/drivers/scsi/53c700.c                 |  131 -
 25-akpm/drivers/scsi/53c700.h                 |   23 
 25-akpm/drivers/scsi/53c7xx.c                 |    2 
 25-akpm/drivers/scsi/BusLogic.c               |    2 
 25-akpm/drivers/scsi/Kconfig                  |   17 
 25-akpm/drivers/scsi/Makefile                 |    1 
 25-akpm/drivers/scsi/NCR53C9x.c               |    2 
 25-akpm/drivers/scsi/NCR53c406a.c             |    2 
 25-akpm/drivers/scsi/NCR_D700.c               |    6 
 25-akpm/drivers/scsi/NCR_Q720.c               |    2 
 25-akpm/drivers/scsi/a2091.c                  |    2 
 25-akpm/drivers/scsi/a3000.c                  |    2 
 25-akpm/drivers/scsi/advansys.c               |  774 ++-------
 25-akpm/drivers/scsi/aha1542.c                |    2 
 25-akpm/drivers/scsi/aha1740.c                |    2 
 25-akpm/drivers/scsi/aic7xxx/aic79xx_osm.h    |    2 
 25-akpm/drivers/scsi/aic7xxx/aic7xxx_osm.h    |    2 
 25-akpm/drivers/scsi/aic7xxx/aiclib.c         |    2 
 25-akpm/drivers/scsi/aic7xxx_old.c            |    2 
 25-akpm/drivers/scsi/amiga7xx.c               |    2 
 25-akpm/drivers/scsi/atari_scsi.c             |    2 
 25-akpm/drivers/scsi/atp870u.c                |    2 
 25-akpm/drivers/scsi/blz1230.c                |    2 
 25-akpm/drivers/scsi/blz2060.c                |    2 
 25-akpm/drivers/scsi/bvme6000.c               |    2 
 25-akpm/drivers/scsi/constants.c              |   24 
 25-akpm/drivers/scsi/cpqfcTScontrol.c         |    2 
 25-akpm/drivers/scsi/cpqfcTSinit.c            |    4 
 25-akpm/drivers/scsi/cpqfcTSworker.c          |    2 
 25-akpm/drivers/scsi/cyberstorm.c             |    2 
 25-akpm/drivers/scsi/cyberstormII.c           |    2 
 25-akpm/drivers/scsi/dc390.h                  |   15 
 25-akpm/drivers/scsi/dc395x.c                 |    2 
 25-akpm/drivers/scsi/dec_esp.c                |    2 
 25-akpm/drivers/scsi/dmx3191d.c               |    2 
 25-akpm/drivers/scsi/dpt_i2o.c                |   57 
 25-akpm/drivers/scsi/dpti.h                   |   24 
 25-akpm/drivers/scsi/dtc.c                    |    2 
 25-akpm/drivers/scsi/eata.c                   |    2 
 25-akpm/drivers/scsi/eata_pio.c               |  106 -
 25-akpm/drivers/scsi/esp.c                    |    2 
 25-akpm/drivers/scsi/fastlane.c               |    2 
 25-akpm/drivers/scsi/fcal.c                   |    2 
 25-akpm/drivers/scsi/fd_mcs.c                 |    2 
 25-akpm/drivers/scsi/fdomain.c                |    2 
 25-akpm/drivers/scsi/g_NCR5380.c              |    2 
 25-akpm/drivers/scsi/gvp11.c                  |    2 
 25-akpm/drivers/scsi/i60uscsi.c               |    2 
 25-akpm/drivers/scsi/ibmmca.c                 |    2 
 25-akpm/drivers/scsi/ide-scsi.c               |    2 
 25-akpm/drivers/scsi/imm.h                    |    2 
 25-akpm/drivers/scsi/in2000.c                 |    2 
 25-akpm/drivers/scsi/ini9100u.c               |    2 
 25-akpm/drivers/scsi/ipr.c                    |   13 
 25-akpm/drivers/scsi/ipr.h                    |    4 
 25-akpm/drivers/scsi/ips.c                    |    2 
 25-akpm/drivers/scsi/jazz_esp.c               |    2 
 25-akpm/drivers/scsi/lasi700.c                |    5 
 25-akpm/drivers/scsi/mac_esp.c                |    2 
 25-akpm/drivers/scsi/mac_scsi.c               |    2 
 25-akpm/drivers/scsi/mca_53c9x.c              |    2 
 25-akpm/drivers/scsi/megaraid.c               |   31 
 25-akpm/drivers/scsi/mvme147.c                |    2 
 25-akpm/drivers/scsi/mvme16x.c                |    2 
 25-akpm/drivers/scsi/ncr53c8xx.c              |    2 
 25-akpm/drivers/scsi/nsp32.c                  |    2 
 25-akpm/drivers/scsi/oktagon_esp.c            |    2 
 25-akpm/drivers/scsi/osst.c                   |    2 
 25-akpm/drivers/scsi/pas16.c                  |    2 
 25-akpm/drivers/scsi/pc980155.c               |    2 
 25-akpm/drivers/scsi/pci2000.c                |    2 
 25-akpm/drivers/scsi/pci2220i.c               |    2 
 25-akpm/drivers/scsi/pcmcia/aha152x_stub.c    |    2 
 25-akpm/drivers/scsi/pcmcia/fdomain_stub.c    |    2 
 25-akpm/drivers/scsi/pcmcia/qlogic_stub.c     |    2 
 25-akpm/drivers/scsi/pluto.c                  |    2 
 25-akpm/drivers/scsi/ppa.h                    |    2 
 25-akpm/drivers/scsi/psi240i.c                |    2 
 25-akpm/drivers/scsi/qla1280.c                |    6 
 25-akpm/drivers/scsi/qla2xxx/qla_os.h         |    2 
 25-akpm/drivers/scsi/qlogicfas.c              |    2 
 25-akpm/drivers/scsi/qlogicfas408.c           |    2 
 25-akpm/drivers/scsi/qlogicfc.c               |    2 
 25-akpm/drivers/scsi/qlogicisp.c              |    2 
 25-akpm/drivers/scsi/qlogicpti.c              |    2 
 25-akpm/drivers/scsi/scsi.h                   |   57 
 25-akpm/drivers/scsi/scsi_debug.c             |    2 
 25-akpm/drivers/scsi/scsi_devinfo.c           |   11 
 25-akpm/drivers/scsi/scsi_error.c             |    8 
 25-akpm/drivers/scsi/scsi_ioctl.c             |    2 
 25-akpm/drivers/scsi/scsi_lib.c               |    1 
 25-akpm/drivers/scsi/scsi_module.c            |    2 
 25-akpm/drivers/scsi/scsi_pc98.c              |    2 
 25-akpm/drivers/scsi/scsi_syms.c              |   12 
 25-akpm/drivers/scsi/scsicam.c                |    2 
 25-akpm/drivers/scsi/scsiiom.c                |  102 -
 25-akpm/drivers/scsi/sd.c                     |   10 
 25-akpm/drivers/scsi/seagate.c                |    2 
 25-akpm/drivers/scsi/sg.c                     |   40 
 25-akpm/drivers/scsi/sgiwd93.c                |    2 
 25-akpm/drivers/scsi/sim710.c                 |    5 
 25-akpm/drivers/scsi/sr.c                     |    2 
 25-akpm/drivers/scsi/sr_ioctl.c               |    5 
 25-akpm/drivers/scsi/sr_vendor.c              |    2 
 25-akpm/drivers/scsi/st.c                     |    2 
 25-akpm/drivers/scsi/sun3_scsi.c              |    2 
 25-akpm/drivers/scsi/sun3_scsi_vme.c          |    2 
 25-akpm/drivers/scsi/sun3x_esp.c              |    2 
 25-akpm/drivers/scsi/sym53c416.c              |   85 -
 25-akpm/drivers/scsi/t128.c                   |    2 
 25-akpm/drivers/scsi/tmscsim.c                |  279 ++-
 25-akpm/drivers/scsi/tmscsim.h                |   13 
 25-akpm/drivers/scsi/u14-34f.c                |    2 
 25-akpm/drivers/scsi/ultrastor.c              |    2 
 25-akpm/drivers/scsi/wd33c93.c                |    2 
 25-akpm/drivers/scsi/wd7000.c                 |    2 
 25-akpm/drivers/scsi/zalon.c                  |    2 
 25-akpm/drivers/usb/storage/scsiglue.c        |    3 
 25-akpm/include/linux/i2o.h                   |   14 
 25-akpm/include/linux/pci_ids.h               |    2 
 25-akpm/include/scsi/scsi_dbg.h               |   18 
 25-akpm/include/scsi/scsi_eh.h                |    4 
 25-akpm/include/scsi/scsi_host.h              |    9 
 drivers/scsi/scsi_transport_spi.c             |    0 
 140 files changed, 4018 insertions(+), 1670 deletions(-)

diff -puN drivers/message/fusion/isense.c~bk-scsi drivers/message/fusion/isense.c
--- 25/drivers/message/fusion/isense.c~bk-scsi	2004-06-14 00:10:34.436073224 -0700
+++ 25-akpm/drivers/message/fusion/isense.c	2004-06-14 00:10:34.686035224 -0700
@@ -56,14 +56,6 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <asm/io.h>
-#if defined (__sparc__)
-#include <linux/timer.h>
-#endif
-
-/* Hmmm, avoid undefined spinlock_t on lk-2.2.14-5.0 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-#include <asm/spinlock.h>
-#endif
 
 #define MODULEAUTHOR "Steven J. Ralston"
 #define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR
diff -puN drivers/message/fusion/linux_compat.h~bk-scsi drivers/message/fusion/linux_compat.h
--- 25/drivers/message/fusion/linux_compat.h~bk-scsi	2004-06-14 00:10:34.437073072 -0700
+++ 25-akpm/drivers/message/fusion/linux_compat.h	2004-06-14 00:10:34.688034920 -0700
@@ -2,196 +2,7 @@
 
 #ifndef FUSION_LINUX_COMPAT_H
 #define FUSION_LINUX_COMPAT_H
-/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include <linux/version.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#ifndef rwlock_init
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-#endif
-
-#define SET_NICE(current,x) do {(current)->nice = (x);} while (0)
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-#	if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
-		typedef unsigned int dma_addr_t;
-#	endif
-#else
-#	if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)
-		typedef unsigned int dma_addr_t;
-#	endif
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
-/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/* This block snipped from lk-2.2.18/include/linux/init.h { */
-/*
- * Used for initialization calls..
- */
-typedef int (*initcall_t)(void);
-typedef void (*exitcall_t)(void);
-
-#define __init_call	__attribute__ ((unused,__section__ (".initcall.init")))
-#define __exit_call	__attribute__ ((unused,__section__ (".exitcall.exit")))
-
-extern initcall_t __initcall_start, __initcall_end;
-
-#define __initcall(fn)								\
-	static initcall_t __initcall_##fn __init_call = fn
-#define __exitcall(fn)								\
-	static exitcall_t __exitcall_##fn __exit_call = fn
-
-#ifdef MODULE
-/* These macros create a dummy inline: gcc 2.9x does not count alias
- as usage, hence the `unused function' warning when __init functions
- are declared static. We use the dummy __*_module_inline functions
- both to kill the warning and check the type of the init/cleanup
- function. */
-typedef int (*__init_module_func_t)(void);
-typedef void (*__cleanup_module_func_t)(void);
-#define module_init(x) \
-	int init_module(void) __attribute__((alias(#x))); \
-	static inline __init_module_func_t __init_module_inline(void) \
-	{ return x; }
-#define module_exit(x) \
-	void cleanup_module(void) __attribute__((alias(#x))); \
-	static inline __cleanup_module_func_t __cleanup_module_inline(void) \
-	{ return x; }
-
-#else
-#define module_init(x)	__initcall(x);
-#define module_exit(x)	__exitcall(x);
-#endif
-/* } block snipped from lk-2.2.18/include/linux/init.h */
-
-/* This block snipped from lk-2.2.18/include/linux/sched.h { */
-/*
- * Used prior to schedule_timeout calls..
- */
-#define __set_current_state(state_value)	do { current->state = state_value; } while (0)
-#ifdef CONFIG_SMP
-#define set_current_state(state_value)		do { __set_current_state(state_value); mb(); } while (0)
-#else
-#define set_current_state(state_value)		__set_current_state(state_value)
-#endif
-/* } block snipped from lk-2.2.18/include/linux/sched.h */
-
-/* procfs compat stuff... */
-#define proc_mkdir(x,y)			create_proc_entry(x, S_IFDIR, y)
-
-/* MUTEX compat stuff... */
-#define DECLARE_MUTEX(name)		struct semaphore name=MUTEX
-#define DECLARE_MUTEX_LOCKED(name)	struct semaphore name=MUTEX_LOCKED
-#define init_MUTEX(x)			*(x)=MUTEX
-#define init_MUTEX_LOCKED(x)		*(x)=MUTEX_LOCKED
-
-/* Wait queues. */
-#define DECLARE_WAIT_QUEUE_HEAD(name)	\
-	struct wait_queue * (name) = NULL
-#define DECLARE_WAITQUEUE(name, task)	\
-	struct wait_queue (name) = { (task), NULL }
-
-#if defined(__sparc__) && defined(__sparc_v9__)
-/* The sparc64 ioremap implementation is wrong in 2.2.x,
- * but fixing it would break all of the drivers which
- * workaround it.  Fixed in 2.3.x onward. -DaveM
- */
-#define ARCH_IOREMAP(base)	((unsigned long) (base))
-#else
-#define ARCH_IOREMAP(base)	ioremap(base)
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#else		/* LINUX_VERSION_CODE must be >= KERNEL_VERSION(2,2,18) */
-
-/* No ioremap bugs in >2.3.x kernels. */
-#define ARCH_IOREMAP(base)	ioremap(base)
-
-/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#endif		/* LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) */
-
-
-/*
- * Inclined to use:
- *   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
- * here, but MODULE_LICENSE defined in 2.4.9-6 and 2.4.9-13
- * breaks the rule:-(
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-
-/* PCI/driver subsystem { */
-#define PCI_BASEADDR_FLAGS(idx)         resource[idx].flags
-#define PCI_BASEADDR_START(idx)         resource[idx].start
-#define PCI_BASEADDR_SIZE(dev,idx)      (dev)->resource[idx].end - (dev)->resource[idx].start + 1
-
-/* Compatability for the 2.3.x PCI DMA API. */
-#ifndef PCI_DMA_BIDIRECTIONAL
-/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#define PCI_DMA_BIDIRECTIONAL	0
-#define PCI_DMA_TODEVICE	1
-#define PCI_DMA_FROMDEVICE	2
-#define PCI_DMA_NONE		3
-
-#ifdef __KERNEL__
-#include <asm/page.h>
-/* Pure 2^n version of get_order */
-static __inline__ int __get_order(unsigned long size)
-{
-	int order;
-
-	size = (size-1) >> (PAGE_SHIFT-1);
-	order = -1;
-	do {
-		size >>= 1;
-		order++;
-	} while (size);
-	return order;
-}
-#endif
-
-#define pci_alloc_consistent(hwdev, size, dma_handle) \
-({	void *__ret = (void *)__get_free_pages(GFP_ATOMIC, __get_order(size)); \
-	if (__ret != NULL) { \
-		memset(__ret, 0, size); \
-		*(dma_handle) = virt_to_bus(__ret); \
-	} \
-	__ret; \
-})
-
-#define pci_free_consistent(hwdev, size, vaddr, dma_handle) \
-	free_pages((unsigned long)vaddr, __get_order(size))
-
-#define pci_map_single(hwdev, ptr, size, direction) \
-	virt_to_bus(ptr);
-
-#define pci_unmap_single(hwdev, dma_addr, size, direction) \
-	do { /* Nothing to do */ } while (0)
-
-#define pci_map_sg(hwdev, sg, nents, direction)	(nents)
-#define pci_unmap_sg(hwdev, sg, nents, direction) \
-	do { /* Nothing to do */ } while(0)
-
-#define sg_dma_address(sg)	(virt_to_bus((sg)->address))
-#define sg_dma_len(sg)		((sg)->length)
-
-/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#endif /* PCI_DMA_BIDIRECTIONAL */
-
-
-#define mpt_work_struct work_struct
-#define MPT_INIT_WORK(_task, _func, _data) INIT_WORK(_task, _func, _data)
-#define mpt_sync_irq(_irq) synchronize_irq(_irq)
 
 /*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif /* _LINUX_COMPAT_H */
-
diff -puN drivers/message/fusion/mptbase.c~bk-scsi drivers/message/fusion/mptbase.c
--- 25/drivers/message/fusion/mptbase.c~bk-scsi	2004-06-14 00:10:34.440072616 -0700
+++ 25-akpm/drivers/message/fusion/mptbase.c	2004-06-14 00:10:34.692034312 -0700
@@ -1311,14 +1311,14 @@ mptbase_probe(struct pci_dev *pdev, cons
 	mem_phys = msize = 0;
 	port = psize = 0;
 	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
-		if (pdev->PCI_BASEADDR_FLAGS(ii) & PCI_BASE_ADDRESS_SPACE_IO) {
+		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
 			/* Get I/O space! */
-			port = pdev->PCI_BASEADDR_START(ii);
-			psize = PCI_BASEADDR_SIZE(pdev,ii);
+			port = pci_resource_start(pdev, ii);
+			psize = pci_resource_len(pdev,ii);
 		} else {
 			/* Get memmap */
-			mem_phys = pdev->PCI_BASEADDR_START(ii);
-			msize = PCI_BASEADDR_SIZE(pdev,ii);
+			mem_phys = pci_resource_start(pdev, ii);
+			msize = pci_resource_len(pdev,ii);
 			break;
 		}
 	}
@@ -1524,7 +1524,7 @@ mptbase_remove(struct pci_dev *pdev)
 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
 
 	ioc->active = 0;
-	mpt_sync_irq(pdev->irq);
+	synchronize_irq(pdev->irq);
 
 	/* Clear any lingering interrupt */
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
@@ -3799,7 +3799,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
 
 		/*  Prime reply FIFO...  */
 		dprintk((KERN_INFO MYNAM ": %s.reply_alloc  @ %p[%p], sz=%d bytes\n",
-			 	ioc->name, mem, (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
+			ioc->name, ioc->reply_alloc, 
+			(void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
 
 		b = (unsigned long) ioc->reply_alloc;
 		b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
@@ -3812,7 +3813,8 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
 	
 		/*  Request FIFO - WE manage this!  */
 		dprintk((KERN_INFO MYNAM ": %s.req_alloc    @ %p[%p], sz=%d bytes\n",
-			 	ioc->name, mem, (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
+			ioc->name, ioc->req_alloc,
+			(void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
 
 		b = (unsigned long) ioc->req_alloc;
 		b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
diff -puN drivers/message/fusion/mptbase.h~bk-scsi drivers/message/fusion/mptbase.h
--- 25/drivers/message/fusion/mptbase.h~bk-scsi	2004-06-14 00:10:34.442072312 -0700
+++ 25-akpm/drivers/message/fusion/mptbase.h	2004-06-14 00:10:34.694034008 -0700
@@ -55,7 +55,11 @@
 #define MPTBASE_H_INCLUDED
 /*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#include "linux_compat.h"	/* linux-2.2.x (vs. -2.4.x) tweaks */
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
 #include "scsi3.h"		/* SCSI defines */
 
 #include "lsi/mpi_type.h"
@@ -81,8 +85,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2004 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.01.06"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.01.06"
+#define MPT_LINUX_VERSION_COMMON	"3.01.07"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.01.07"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
diff -puN drivers/message/fusion/mptctl.c~bk-scsi drivers/message/fusion/mptctl.c
--- 25/drivers/message/fusion/mptctl.c~bk-scsi	2004-06-14 00:10:34.444072008 -0700
+++ 25-akpm/drivers/message/fusion/mptctl.c	2004-06-14 00:10:34.697033552 -0700
@@ -102,9 +102,6 @@
 #define my_VERSION	MPT_LINUX_VERSION_COMMON
 #define MYNAM		"mptctl"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62)
-EXPORT_NO_SYMBOLS;
-#endif
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
@@ -547,38 +544,6 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int r
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *  struct file_operations functionality.
- *  Members:
- *	llseek, write, read, ioctl, open, release
- */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
-static loff_t
-mptctl_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-#define no_llseek mptctl_llseek
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static ssize_t
-mptctl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
-	printk(KERN_ERR MYNAM ": ioctl WRITE not yet supported\n");
-	return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static ssize_t
-mptctl_read(struct file *file, char *buf, size_t count, loff_t *ptr)
-{
-	printk(KERN_ERR MYNAM ": ioctl READ not yet supported\n");
-	return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
  *  MPT ioctl handler
  *  cmd - specify the particular IOCTL command to be issued
  *  arg - data specific to the command. Must not be null.
@@ -700,21 +665,6 @@ static int mptctl_do_reset(unsigned long
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int mptctl_open(struct inode *inode, struct file *file)
-{
-	/*
-	 * Should support multiple management users
-	 */
-	return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int mptctl_release(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * MPT FW download function.  Cast the arg into the mpt_fw_xfer structure.
  * This structure contains: iocnum, firmware length (bytes),
@@ -1278,10 +1228,8 @@ mptctl_getiocinfo (unsigned long arg, un
 	karg->pciId = pdev->device;
 	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
 	karg->hwRev = revision;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	karg->subSystemDevice = pdev->subsystem_device;
 	karg->subSystemVendor = pdev->subsystem_vendor;
-#endif
 
 	if (cim_rev == 1) {
 		/* Get the PCI bus, device, and function numbers for the IOC
@@ -2455,10 +2403,8 @@ mptctl_hp_hostinfo(unsigned long arg, un
 
 	karg.vendor = pdev->vendor;
 	karg.device = pdev->device;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	karg.subsystem_id = pdev->subsystem_device;
 	karg.subsystem_vendor = pdev->subsystem_vendor;
-#endif
 	karg.devfn = pdev->devfn;
 	karg.bus = pdev->bus->number;
 
@@ -2540,7 +2486,7 @@ mptctl_hp_hostinfo(unsigned long arg, un
 		break;
 	}
 
-	karg.base_io_addr = pdev->PCI_BASEADDR_START(0);
+	karg.base_io_addr = pci_resource_start(pdev, 0);
 
 	if ((int)ioc->chip_type <= (int) FC929)
 		karg.bus_phys_width = HP_BUS_WIDTH_UNK;
@@ -2739,20 +2685,10 @@ mptctl_hp_targetinfo(unsigned long arg)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
-#define	owner_THIS_MODULE  .owner = THIS_MODULE,
-#else
-#define	owner_THIS_MODULE
-#endif
-
 static struct file_operations mptctl_fops = {
-	owner_THIS_MODULE
+	.owner =	THIS_MODULE,
 	.llseek =	no_llseek,
-	.read =		mptctl_read,
-	.write =	mptctl_write,
 	.ioctl =	mptctl_ioctl,
-	.open =		mptctl_open,
-	.release =	mptctl_release,
 };
 
 static struct miscdevice mptctl_miscdev = {
diff -puN drivers/message/fusion/mptlan.c~bk-scsi drivers/message/fusion/mptlan.c
--- 25/drivers/message/fusion/mptlan.c~bk-scsi	2004-06-14 00:10:34.445071856 -0700
+++ 25-akpm/drivers/message/fusion/mptlan.c	2004-06-14 00:10:34.699033248 -0700
@@ -133,7 +133,7 @@ struct mpt_lan_priv {
 	u32 total_received;
 	struct net_device_stats stats;	/* Per device statistics */
 
-	struct mpt_work_struct post_buckets_task;
+	struct work_struct post_buckets_task;
 	unsigned long post_buckets_active;
 };
 
@@ -880,18 +880,9 @@ mpt_lan_wake_post_buckets_task(struct ne
 	
 	if (test_and_set_bit(0, &priv->post_buckets_active) == 0) {
 		if (priority) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
 			schedule_work(&priv->post_buckets_task);
-#else
-			queue_task(&priv->post_buckets_task, &tq_immediate);
-			mark_bh(IMMEDIATE_BH);
-#endif
 		} else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
 			schedule_delayed_work(&priv->post_buckets_task, 1);
-#else
-			queue_task(&priv->post_buckets_task, &tq_timer);
-#endif
 			dioprintk((KERN_INFO MYNAM ": post_buckets queued on "
 				   "timer.\n"));
 		}
@@ -1391,8 +1382,8 @@ mpt_register_lan_device (MPT_ADAPTER *mp
 	priv->mpt_dev = mpt_dev;
 	priv->pnum = pnum;
 
-	memset(&priv->post_buckets_task, 0, sizeof(struct mpt_work_struct));
-	MPT_INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev);
+	memset(&priv->post_buckets_task, 0, sizeof(struct work_struct));
+	INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev);
 	priv->post_buckets_active = 0;
 
 	dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n",
@@ -1566,10 +1557,6 @@ static void __exit mpt_lan_exit(void)
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,59)
-MODULE_PARM(tx_max_out_p, "i");
-MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME!
-#endif
 
 module_init(mpt_lan_init);
 module_exit(mpt_lan_exit);
diff -puN drivers/message/fusion/mptscsih.c~bk-scsi drivers/message/fusion/mptscsih.c
--- 25/drivers/message/fusion/mptscsih.c~bk-scsi	2004-06-14 00:10:34.448071400 -0700
+++ 25-akpm/drivers/message/fusion/mptscsih.c	2004-06-14 00:10:34.704032488 -0700
@@ -74,6 +74,8 @@
 #include <linux/delay.h>	/* for mdelay */
 #include <linux/interrupt.h>	/* needed for in_interrupt() proto */
 #include <linux/reboot.h>	/* notifier code */
+#include <linux/sched.h>
+#include <linux/workqueue.h>
 #include "../../scsi/scsi.h"
 #include <scsi/scsi_host.h>
 
@@ -185,7 +187,7 @@ static void	mptscsih_schedule_reset(void
 static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
 static int	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
 
-static struct mpt_work_struct   mptscsih_rstTask;
+static struct work_struct   mptscsih_rstTask;
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 static int	mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
@@ -231,7 +233,7 @@ static int	ScsiScanDvCtx = -1; /* Used o
 static spinlock_t dvtaskQ_lock = SPIN_LOCK_UNLOCKED;
 static int dvtaskQ_active = 0;
 static int dvtaskQ_release = 0;
-static struct mpt_work_struct	mptscsih_dvTask;
+static struct work_struct	mptscsih_dvTask;
 #endif
 
 /*
@@ -249,31 +251,7 @@ static struct mptscsih_driver_setup
 static Scsi_Cmnd *foo_to[8];
 #endif
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/* see mptscsih.h */
-
-static struct scsi_host_template driver_template = {
-	.proc_name			= "mptscsih",
-	.proc_info			= x_scsi_proc_info,
-	.name				= "MPT SCSI Host",
-	.info				= x_scsi_info,
-	.queuecommand			= x_scsi_queuecommand,
-	.slave_alloc			= x_scsi_slave_alloc,
-	.slave_configure		= x_scsi_slave_configure,
-	.slave_destroy			= x_scsi_slave_destroy,
-	.eh_abort_handler		= x_scsi_abort,
-	.eh_device_reset_handler	= x_scsi_dev_reset,
-	.eh_bus_reset_handler		= x_scsi_bus_reset,
-	.eh_host_reset_handler		= x_scsi_host_reset,
-	.bios_param			= x_scsi_bios_param,
-	.can_queue			= MPT_SCSI_CAN_QUEUE,
-	.this_id			= -1,
-	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
-	.max_sectors			= MPT_SCSI_MAX_SECTORS,
-	.cmd_per_lun			= MPT_SCSI_CMD_PER_LUN,
-	.use_clustering			= ENABLE_CLUSTERING,
-};
+static struct scsi_host_template driver_template;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -1459,7 +1437,6 @@ mptscsih_probe(struct pci_dev *pdev, con
 	}
 		
 	sh->max_lun = MPT_LAST_LUN + 1;
-	sh->max_sectors = MPT_SCSI_MAX_SECTORS;
 	sh->max_channel = 0;
 	sh->this_id = ioc->pfacts[0].PortSCSIID;
 		
@@ -1800,8 +1777,8 @@ mptscsih_remove(struct pci_dev *pdev)
 		}
 
 		dprintk((MYIOC_s_INFO_FMT
-		  "Free'd ScsiLookup (%d), chain (%d) and Target (%d+%d) memory\n",
-		  hd->ioc->name, sz1, szchain, sz3, sztarget));
+		  "Free'd ScsiLookup (%d) Target (%d+%d) memory\n",
+		  hd->ioc->name, sz1, sz3, sztarget));
 		dprintk(("Free'd done and free Q (%d) memory\n", szQ));
 
 		/* NULL the Scsi_Host pointer
@@ -1879,9 +1856,9 @@ mptscsih_resume(struct pci_dev *pdev)
 	if (!dvtaskQ_active) {
 		dvtaskQ_active = 1;
 		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-		MPT_INIT_WORK(&mptscsih_dvTask,
+		INIT_WORK(&mptscsih_dvTask,
 		  mptscsih_domainValidation, (void *) hd);
-		SCHEDULE_TASK(&mptscsih_dvTask);
+		schedule_work(&mptscsih_dvTask);
 	} else {
 		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
 	}
@@ -1902,7 +1879,6 @@ static struct mpt_pci_driver mptscsih_dr
 #endif
 };
 
-
 /*  SCSI host fops start here...  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
@@ -2434,9 +2410,9 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*d
 					if (!dvtaskQ_active) {
 						dvtaskQ_active = 1;
 						spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-						MPT_INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
+						INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
 
-						SCHEDULE_TASK(&mptscsih_dvTask);
+						schedule_work(&mptscsih_dvTask);
 					} else {
 						spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
 					}
@@ -3905,6 +3881,29 @@ mptscsih_event_process(MPT_ADAPTER *ioc,
 	return 1;		/* currently means nothing really */
 }
 
+static struct scsi_host_template driver_template = {
+	.proc_name			= "mptscsih",
+	.proc_info			= mptscsih_proc_info,
+	.name				= "MPT SCSI Host",
+	.info				= mptscsih_info,
+	.queuecommand			= mptscsih_qcmd,
+	.slave_alloc			= mptscsih_slave_alloc,
+	.slave_configure		= mptscsih_slave_configure,
+	.slave_destroy			= mptscsih_slave_destroy,
+	.eh_abort_handler		= mptscsih_abort,
+	.eh_device_reset_handler	= mptscsih_dev_reset,
+	.eh_bus_reset_handler		= mptscsih_bus_reset,
+	.eh_host_reset_handler		= mptscsih_host_reset,
+	.bios_param			= mptscsih_bios_param,
+	.can_queue			= MPT_SCSI_CAN_QUEUE,
+	.this_id			= -1,
+	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
+	.max_sectors			= 8192,
+	.cmd_per_lun			= 7,
+	.use_clustering			= ENABLE_CLUSTERING,
+};
+
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Private data...
@@ -4950,8 +4949,8 @@ static void mptscsih_taskmgmt_timeout(un
 	/* Call the reset handler. Already had a TM request
 	 * timeout - so issue a diagnostic reset
 	 */
-	MPT_INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
-	SCHEDULE_TASK(&mptscsih_rstTask);
+	INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
+	schedule_work(&mptscsih_rstTask);
 	return;
 }
 
diff -puN drivers/message/fusion/mptscsih.h~bk-scsi drivers/message/fusion/mptscsih.h
--- 25/drivers/message/fusion/mptscsih.h~bk-scsi	2004-06-14 00:10:34.449071248 -0700
+++ 25-akpm/drivers/message/fusion/mptscsih.h	2004-06-14 00:10:34.706032184 -0700
@@ -108,75 +108,4 @@ struct mptscsih_driver_setup
         MPTSCSIH_SAF_TE,                        \
 }
 
-
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	Various bits and pieces broke within the lk-2.4.0-testN series:-(
- *	So here are various HACKS to work around them.
- */
-
-/*
- *	tq_scheduler disappeared @ lk-2.4.0-test12
- *	(right when <linux/sched.h> newly defined TQ_ACTIVE)
- *	tq_struct reworked in 2.5.41. Include workqueue.h.
- */
-#	include <linux/sched.h>
-#	include <linux/workqueue.h>
-#define SCHEDULE_TASK(x)		\
-	if (schedule_work(x) == 0) {	\
-		/*MOD_DEC_USE_COUNT*/;	\
-	}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#define x_scsi_info		mptscsih_info
-#define x_scsi_queuecommand	mptscsih_qcmd
-#define x_scsi_abort		mptscsih_abort
-#define x_scsi_bus_reset	mptscsih_bus_reset
-#define x_scsi_dev_reset	mptscsih_dev_reset
-#define x_scsi_host_reset	mptscsih_host_reset
-#define x_scsi_bios_param	mptscsih_bios_param
-
-#define x_scsi_slave_alloc	mptscsih_slave_alloc
-#define x_scsi_slave_configure	mptscsih_slave_configure
-#define x_scsi_slave_destroy	mptscsih_slave_destroy
-#define x_scsi_proc_info	mptscsih_proc_info
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	MPT SCSI Host / Initiator decls...
- */
-extern	const char	*x_scsi_info(struct Scsi_Host *);
-extern	int		 x_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern	int		 x_scsi_abort(Scsi_Cmnd *);
-extern	int		 x_scsi_bus_reset(Scsi_Cmnd *);
-extern	int		 x_scsi_dev_reset(Scsi_Cmnd *);
-extern	int		 x_scsi_host_reset(Scsi_Cmnd *);
-extern int		 x_scsi_bios_param(struct scsi_device * sdev, struct block_device *bdev,
-				sector_t capacity, int geom[]);
-extern	int		 x_scsi_slave_alloc(Scsi_Device *);
-extern	int		 x_scsi_slave_configure(Scsi_Device *);
-extern	void		 x_scsi_slave_destroy(Scsi_Device *);
-extern	int		 x_scsi_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/*  include/scsi/scsi.h may not be quite complete...  */
-#ifndef RESERVE_10
-#define RESERVE_10		0x56
-#endif
-#ifndef RELEASE_10
-#define RELEASE_10		0x57
-#endif
-#ifndef PERSISTENT_RESERVE_IN
-#define PERSISTENT_RESERVE_IN	0x5e
-#endif
-#ifndef PERSISTENT_RESERVE_OUT
-#define PERSISTENT_RESERVE_OUT	0x5f
 #endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#endif
-
diff -puN drivers/message/i2o/i2o_block.c~bk-scsi drivers/message/i2o/i2o_block.c
--- 25/drivers/message/i2o/i2o_block.c~bk-scsi	2004-06-14 00:10:34.451070944 -0700
+++ 25-akpm/drivers/message/i2o/i2o_block.c	2004-06-14 00:10:34.708031880 -0700
@@ -280,8 +280,8 @@ static int i2ob_send(u32 m, struct i2ob_
 {
 	struct i2o_controller *c = dev->controller;
 	int tid = dev->tid;
-	unsigned long msg;
-	unsigned long mptr;
+	void *msg;
+	void *mptr;
 	u64 offset;
 	struct request *req = ireq->req;
 	int count = req->nr_sectors<<9;
@@ -291,7 +291,7 @@ static int i2ob_send(u32 m, struct i2ob_
 
 	// printk(KERN_INFO "i2ob_send called\n");
 	/* Map the message to a virtual address */
-	msg = c->mem_offset + m;
+	msg = c->msg_virt + m;
 	
 	sgnum = i2ob_build_sglist(dev, ireq);
 	
@@ -479,7 +479,7 @@ static void i2o_block_reply(struct i2o_h
 		/* Now flush the message by making it a NOP */
 		m[0]&=0x00FFFFFF;
 		m[0]|=(I2O_CMD_UTIL_NOP)<<24;
-		i2o_post_message(c, ((unsigned long)m) - c->mem_offset);
+		i2o_post_message(c, (unsigned long) m - (unsigned long) c->msg_virt);
 
 		return;
 	}
diff -puN drivers/message/i2o/i2o_config.c~bk-scsi drivers/message/i2o/i2o_config.c
--- 25/drivers/message/i2o/i2o_config.c~bk-scsi	2004-06-14 00:10:34.452070792 -0700
+++ 25-akpm/drivers/message/i2o/i2o_config.c	2004-06-14 00:10:34.709031728 -0700
@@ -97,7 +97,7 @@ static void i2o_cfg_reply(struct i2o_han
 	u32 *msg = (u32 *)m;
 
 	if (msg[0] & MSG_FAIL) {
-		u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
+		u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]);
 
 		printk(KERN_ERR "i2o_config: IOP failed to process the msg.\n");
 
diff -puN drivers/message/i2o/i2o_core.c~bk-scsi drivers/message/i2o/i2o_core.c
--- 25/drivers/message/i2o/i2o_core.c~bk-scsi	2004-06-14 00:10:34.454070488 -0700
+++ 25-akpm/drivers/message/i2o/i2o_core.c	2004-06-14 00:10:34.713031120 -0700
@@ -354,7 +354,7 @@ static void i2o_core_reply(struct i2o_ha
 
 	if (msg[0] & MSG_FAIL) // Fail bit is set
 	{
-		u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
+		u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]);
 
 		i2o_report_status(KERN_INFO, "i2o_core", msg);
 		i2o_dump_message(preserved_msg);
@@ -1794,7 +1794,7 @@ static int i2o_reset_controller(struct i
 	m=i2o_wait_message(c, "AdapterReset");
 	if(m==0xFFFFFFFF)	
 		return -ETIMEDOUT;
-	msg=(u32 *)(c->mem_offset+m);
+	msg=(u32 *)(c->msg_virt+m);
 	
 	status = pci_alloc_consistent(c->pdev, 4, &status_phys);
 	if(status == NULL) {
@@ -1923,7 +1923,7 @@ int i2o_status_get(struct i2o_controller
 	m=i2o_wait_message(c, "StatusGet");
 	if(m==0xFFFFFFFF)
 		return -ETIMEDOUT;	
-	msg=(u32 *)(c->mem_offset+m);
+	msg=(u32 *)(c->msg_virt+m);
 
 	msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0;
 	msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID;
@@ -2344,7 +2344,7 @@ int i2o_init_outbound_q(struct i2o_contr
 	m=i2o_wait_message(c, "OutboundInit");
 	if(m==0xFFFFFFFF)
 		return -ETIMEDOUT;
-	msg=(u32 *)(c->mem_offset+m);
+	msg=(u32 *)(c->msg_virt+m);
 
 	status = pci_alloc_consistent(c->pdev, 4, &status_phys);
 	if (status==NULL) {
@@ -2618,7 +2618,7 @@ static int i2o_build_sys_table(void)
 		sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
 		sys_tbl->iops[count].iop_capabilities = 
 				iop->status_block->iop_capabilities;
-		sys_tbl->iops[count].inbound_low = iop->post_port;
+		sys_tbl->iops[count].inbound_low = (u32)iop->post_port;
 		sys_tbl->iops[count].inbound_high = 0;	// FIXME: 64-bit support
 
 		count++;
@@ -2666,7 +2666,7 @@ int i2o_post_this(struct i2o_controller 
 		       c->name);
 		return -ETIMEDOUT;
 	}
-	msg = (u32 *)(c->mem_offset + m);
+	msg = (u32 *)(c->msg_virt + m);
  	memcpy_toio(msg, data, len);
 	i2o_post_message(c,m);
 	return 0;
@@ -3592,7 +3592,9 @@ static void i2o_pci_dispose(struct i2o_c
 	I2O_IRQ_WRITE32(c,0xFFFFFFFF);
 	if(c->irq > 0)
 		free_irq(c->irq, c);
-	iounmap(((u8 *)c->post_port)-0x40);
+	iounmap(c->base_virt);
+	if(c->raptor)
+		iounmap(c->msg_virt);
 
 #ifdef CONFIG_MTRR
 	if(c->mtrr_reg0 > 0)
@@ -3633,9 +3635,12 @@ int __init i2o_pci_install(struct pci_de
 {
 	struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
 						GFP_KERNEL);
-	unsigned long mem;
-	u32 memptr = 0;
-	u32 size;
+	void *bar0_virt;
+	void *bar1_virt;
+	unsigned long bar0_phys = 0;
+	unsigned long bar1_phys = 0;
+	unsigned long bar0_size = 0;
+	unsigned long bar1_size = 0;
 	
 	int i;
 
@@ -3646,37 +3651,9 @@ int __init i2o_pci_install(struct pci_de
 	}
 	memset(c, 0, sizeof(*c));
 
-	for(i=0; i<6; i++)
-	{
-		/* Skip I/O spaces */
-		if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
-		{
-			memptr = pci_resource_start(dev, i);
-			break;
-		}
-	}
-	
-	if(i==6)
-	{
-		printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
-		kfree(c);
-		return -EINVAL;
-	}
-	
-	size = dev->resource[i].end-dev->resource[i].start+1;	
-	/* Map the I2O controller */
-	
-	printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
-	mem = (unsigned long)ioremap(memptr, size);
-	if(mem==0)
-	{
-		printk(KERN_ERR "i2o: Unable to map controller.\n");
-		kfree(c);
-		return -EINVAL;
-	}
-
 	c->irq = -1;
 	c->dpt = 0;
+	c->raptor = 0;
 	c->short_req = 0;
 	c->pdev = dev;
 
@@ -3684,13 +3661,6 @@ int __init i2o_pci_install(struct pci_de
 	c->context_list_lock = SPIN_LOCK_UNLOCKED;
 #endif
 
-	c->irq_mask = mem+0x34;
-	c->post_port = mem+0x40;
-	c->reply_port = mem+0x44;
-
-	c->mem_phys = memptr;
-	c->mem_offset = mem;
-	
 	/*
 	 *	Cards that fall apart if you hit them with large I/O
 	 *	loads...
@@ -3701,6 +3671,7 @@ int __init i2o_pci_install(struct pci_de
 		c->short_req = 1;
 		printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
 	}
+
 	if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
 	{
 		c->promise = 1;
@@ -3712,15 +3683,85 @@ int __init i2o_pci_install(struct pci_de
 	 *	them
 	 */
 	 
-	if(dev->vendor == PCI_VENDOR_ID_DPT)
+	if(dev->vendor == PCI_VENDOR_ID_DPT) {
 		c->dpt=1;
+		if(dev->device == 0xA511)
+			c->raptor=1;
+	}
+
+	for(i=0; i<6; i++)
+	{
+		/* Skip I/O spaces */
+		if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
+		{
+			if(!bar0_phys)
+			{
+				bar0_phys = pci_resource_start(dev, i);
+				bar0_size = pci_resource_len(dev, i);
+				if(!c->raptor)
+					break;
+			}
+			else
+			{
+				bar1_phys = pci_resource_start(dev, i);
+				bar1_size = pci_resource_len(dev, i);
+				break;
+			}
+		}
+	}
+
+	if(i==6)
+	{
+		printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
+		kfree(c);
+		return -EINVAL;
+	}
+
+
+	/* Map the I2O controller */
+	if(!c->raptor)
+		printk(KERN_INFO "i2o: PCI I2O controller at %08lX size=%ld\n", bar0_phys, bar0_size);
+	else
+		printk(KERN_INFO "i2o: PCI I2O controller\n    BAR0 at 0x%08lX size=%ld\n    BAR1 at 0x%08lX size=%ld\n", bar0_phys, bar0_size, bar1_phys, bar1_size);
+
+	bar0_virt = ioremap(bar0_phys, bar0_size);
+	if(bar0_virt==0)
+	{
+		printk(KERN_ERR "i2o: Unable to map controller.\n");
+		kfree(c);
+		return -EINVAL;
+	}
+
+	if(c->raptor)
+	{
+		bar1_virt = ioremap(bar1_phys, bar1_size);
+		if(bar1_virt==0)
+		{
+			printk(KERN_ERR "i2o: Unable to map controller.\n");
+			kfree(c);
+			iounmap(bar0_virt);
+			return -EINVAL;
+		}
+	} else {
+		bar1_virt = bar0_virt;
+		bar1_phys = bar0_phys;
+		bar1_size = bar0_size;
+	}
+
+	c->irq_mask = bar0_virt+0x34;
+	c->post_port = bar0_virt+0x40;
+	c->reply_port = bar0_virt+0x44;
+
+	c->base_phys = bar0_phys;
+	c->base_virt = bar0_virt;
+	c->msg_phys = bar1_phys;
+	c->msg_virt = bar1_virt;
 	
 	/* 
 	 * Enable Write Combining MTRR for IOP's memory region
 	 */
 #ifdef CONFIG_MTRR
-	c->mtrr_reg0 =
-		mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
+	c->mtrr_reg0 = mtrr_add(c->base_phys, bar0_size, MTRR_TYPE_WRCOMB, 1);
 	/*
 	 * If it is an INTEL i960 I/O processor then set the first 64K to
 	 * Uncacheable since the region contains the Messaging unit which
@@ -3730,14 +3771,16 @@ int __init i2o_pci_install(struct pci_de
 	if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
 	{
 		printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n"); 
-		c->mtrr_reg1 =	mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
+		c->mtrr_reg1 =	mtrr_add(c->base_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
 		if(c->mtrr_reg1< 0)
 		{
 			printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
-			mtrr_del(c->mtrr_reg0, c->mem_phys, size);
+			mtrr_del(c->mtrr_reg0, c->msg_phys, bar1_size);
 			c->mtrr_reg0 = -1;
 		}
 	}
+	if(c->raptor)
+		c->mtrr_reg1 = mtrr_add(c->msg_phys, bar1_size, MTRR_TYPE_WRCOMB, 1);
 
 #endif
 
@@ -3749,7 +3792,9 @@ int __init i2o_pci_install(struct pci_de
 	{
 		printk(KERN_ERR "i2o: Unable to install controller.\n");
 		kfree(c);
-		iounmap((void *)mem);
+		iounmap(bar0_virt);
+		if(c->raptor)
+			iounmap(bar1_virt);
 		return i;
 	}
 
@@ -3764,7 +3809,9 @@ int __init i2o_pci_install(struct pci_de
 				c->name, dev->irq);
 			c->irq = -1;
 			i2o_delete_controller(c);
-			iounmap((void *)mem);
+			iounmap(bar0_virt);
+			if(c->raptor)
+				iounmap(bar1_virt);
 			return -EBUSY;
 		}
 	}
@@ -3797,10 +3844,12 @@ int __init i2o_pci_scan(void)
 
 	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
 	{
-		if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
+		if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O &&
+		   (dev->vendor!=PCI_VENDOR_ID_DPT || dev->device!=0xA511))
 			continue;
 
-		if((dev->class&0xFF)>1)
+		if((dev->class>>8)==PCI_CLASS_INTELLIGENT_I2O &&
+		   (dev->class&0xFF)>1)
 		{
 			printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n");
 			continue;
diff -puN drivers/message/i2o/i2o_scsi.c~bk-scsi drivers/message/i2o/i2o_scsi.c
--- 25/drivers/message/i2o/i2o_scsi.c~bk-scsi	2004-06-14 00:10:34.456070184 -0700
+++ 25-akpm/drivers/message/i2o/i2o_scsi.c	2004-06-14 00:10:34.715030816 -0700
@@ -59,9 +59,11 @@
 #include <asm/atomic.h>
 #include <linux/blkdev.h>
 #include <linux/i2o.h>
-#include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
 
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
 
 
 #define VERSION_STRING        "Version 0.1.2"
@@ -186,7 +188,7 @@ static void flush_pending(void)
 
 static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)
 {
-	Scsi_Cmnd *current_command;
+	struct scsi_cmnd *current_command;
 	spinlock_t *lock;
 	u32 *m = (u32 *)msg;
 	u8 as,ds,st;
@@ -230,7 +232,7 @@ static void i2o_scsi_reply(struct i2o_ha
 		{
 			spin_unlock_irqrestore(&retry_lock, flags);
 			/* Create a scsi error for this */
-			current_command = (Scsi_Cmnd *)i2o_context_list_get(m[3], c);
+			current_command = (struct scsi_cmnd *)i2o_context_list_get(m[3], c);
 			if(!current_command)
 				return;
 
@@ -277,7 +279,7 @@ static void i2o_scsi_reply(struct i2o_ha
 		return;
 	}
 
-	current_command = (Scsi_Cmnd *)i2o_context_list_get(m[3], c);
+	current_command = (struct scsi_cmnd *)i2o_context_list_get(m[3], c);
 	
 	/*
 	 *	Is this a control request coming back - eg an abort ?
@@ -330,10 +332,17 @@ static void i2o_scsi_reply(struct i2o_ha
 		 */		
 		current_command->result = DID_OK << 16 | ds;
 
-	if (current_command->use_sg)
-		pci_unmap_sg(c->pdev, (struct scatterlist *)current_command->buffer, current_command->use_sg, scsi_to_pci_dma_dir(current_command->sc_data_direction));
-	else if (current_command->request_bufflen)
-		pci_unmap_single(c->pdev, (dma_addr_t)((long)current_command->SCp.ptr), current_command->request_bufflen, scsi_to_pci_dma_dir(current_command->sc_data_direction));
+	if (current_command->use_sg) {
+		pci_unmap_sg(c->pdev,
+			(struct scatterlist *)current_command->buffer,
+			current_command->use_sg,
+			current_command->sc_data_direction);
+	} else if (current_command->request_bufflen) {
+		pci_unmap_single(c->pdev,
+			(dma_addr_t)((long)current_command->SCp.ptr),
+			current_command->request_bufflen,
+			current_command->sc_data_direction);
+	}
 
 	lock = current_command->device->host->host_lock;
 	spin_lock_irqsave(lock, flags);
@@ -461,7 +470,7 @@ static void i2o_scsi_init(struct i2o_con
  *	scsi controller and then let the enumeration fake up the rest
  */
  
-static int i2o_scsi_detect(Scsi_Host_Template * tpnt)
+static int i2o_scsi_detect(struct scsi_host_template * tpnt)
 {
 	struct Scsi_Host *shpnt = NULL;
 	int i;
@@ -592,12 +601,13 @@ static const char *i2o_scsi_info(struct 
  *	Locks: takes the controller lock on error path only
  */
  
-static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
+				 void (*done) (struct scsi_cmnd *))
 {
 	int i;
 	int tid;
 	struct i2o_controller *c;
-	Scsi_Cmnd *current_command;
+	struct scsi_cmnd *current_command;
 	struct Scsi_Host *host;
 	struct i2o_scsi_host *hostdata;
 	u32 *msg, *mptr;
@@ -659,7 +669,7 @@ static int i2o_scsi_queuecommand(Scsi_Cm
 	if(m==0xFFFFFFFF)
 		return 1;
 
-	msg = (u32 *)(c->mem_offset + m);
+	msg = (u32 *)(c->msg_virt + m);
 	
 	/*
 	 *	Put together a scsi execscb message
@@ -668,19 +678,14 @@ static int i2o_scsi_queuecommand(Scsi_Cm
 	len = SCpnt->request_bufflen;
 	direction = 0x00000000;			// SGL IN  (osm<--iop)
 	
-	if(SCpnt->sc_data_direction == SCSI_DATA_NONE)
+	if (SCpnt->sc_data_direction == DMA_NONE) {
 		scsidir = 0x00000000;			// DATA NO XFER
-	else if(SCpnt->sc_data_direction == SCSI_DATA_WRITE)
-	{
-		direction=0x04000000;	// SGL OUT  (osm-->iop)
-		scsidir  =0x80000000;	// DATA OUT (iop-->dev)
-	}
-	else if(SCpnt->sc_data_direction == SCSI_DATA_READ)
-	{
-		scsidir  =0x40000000;	// DATA IN  (iop<--dev)
-	}
-	else
-	{
+	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
+		direction = 0x04000000;	// SGL OUT  (osm-->iop)
+		scsidir = 0x80000000;	// DATA OUT (iop-->dev)
+	} else if(SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
+		scsidir = 0x40000000;	// DATA IN  (iop<--dev)
+	} else {
 		/* Unknown - kill the command */
 		SCpnt->result = DID_NO_CONNECT << 16;
 		
@@ -768,7 +773,7 @@ static int i2o_scsi_queuecommand(Scsi_Cm
 		len = 0;
 
 		sg_count = pci_map_sg(c->pdev, sg, SCpnt->use_sg,
-				      scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+				SCpnt->sc_data_direction);
 
 		/* FIXME: handle fail */
 		if(!sg_count)
@@ -840,7 +845,7 @@ static int i2o_scsi_queuecommand(Scsi_Cm
 			dma_addr = pci_map_single(c->pdev,
 					       SCpnt->request_buffer,
 					       SCpnt->request_bufflen,
-					       scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+					       SCpnt->sc_data_direction);
 			if(dma_addr == 0)
 				BUG();	/* How to handle ?? */
 			SCpnt->SCp.ptr = (char *)(unsigned long) dma_addr;
@@ -883,7 +888,7 @@ static int i2o_scsi_queuecommand(Scsi_Cm
  *	Locks: no locks are held or needed
  */
  
-int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_abort(struct scsi_cmnd * SCpnt)
 {
 	struct i2o_controller *c;
 	struct Scsi_Host *host;
@@ -929,14 +934,14 @@ int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
  *	Locks: called with no lock held, requires no locks.
  */
  
-static int i2o_scsi_bus_reset(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_bus_reset(struct scsi_cmnd * SCpnt)
 {
 	int tid;
 	struct i2o_controller *c;
 	struct Scsi_Host *host;
 	struct i2o_scsi_host *hostdata;
 	u32 m;
-	unsigned long msg;
+	void *msg;
 	unsigned long timeout;
 
 	
@@ -974,7 +979,7 @@ static int i2o_scsi_bus_reset(Scsi_Cmnd 
 	while(time_before(jiffies, timeout));
 	
 	
-	msg = c->mem_offset + m;
+	msg = c->msg_virt + m;
 	i2o_raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
 	i2o_raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, msg+4);
 	i2o_raw_writel(scsi_context|0x80000000, msg+8);
@@ -992,32 +997,6 @@ static int i2o_scsi_bus_reset(Scsi_Cmnd 
 }
 
 /**
- *	i2o_scsi_host_reset	-	host reset callback
- *	@SCpnt: command causing the reset
- *
- *	An I2O controller can be many things at once. While we can
- *	reset a controller the potential mess from doing so is vast, and
- *	it's better to simply hold on and pray
- */
- 
-static int i2o_scsi_host_reset(Scsi_Cmnd * SCpnt)
-{
-	return FAILED;
-}
-
-/**
- *	i2o_scsi_device_reset	-	device reset callback
- *	@SCpnt: command causing the reset
- *
- *	I2O does not (AFAIK) support doing a device reset
- */
- 
-static int i2o_scsi_device_reset(Scsi_Cmnd * SCpnt)
-{
-	return FAILED;
-}
-
-/**
  *	i2o_scsi_bios_param	-	Invent disk geometry
  *	@sdev: scsi device 
  *	@dev: block layer device
@@ -1048,7 +1027,7 @@ MODULE_AUTHOR("Red Hat Software");
 MODULE_LICENSE("GPL");
 
 
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
 	.proc_name		= "i2o_scsi",
 	.name			= "I2O SCSI Layer",
 	.detect			= i2o_scsi_detect,
@@ -1057,8 +1036,6 @@ static Scsi_Host_Template driver_templat
 	.queuecommand		= i2o_scsi_queuecommand,
 	.eh_abort_handler	= i2o_scsi_abort,
 	.eh_bus_reset_handler	= i2o_scsi_bus_reset,
-	.eh_device_reset_handler= i2o_scsi_device_reset,
-	.eh_host_reset_handler	= i2o_scsi_host_reset,
 	.bios_param		= i2o_scsi_bios_param,
 	.can_queue		= I2O_SCSI_CAN_QUEUE,
 	.this_id		= 15,
diff -puN /dev/null drivers/scsi/3w-9xxx.c
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/drivers/scsi/3w-9xxx.c	2004-06-14 00:10:34.727028992 -0700
@@ -0,0 +1,2153 @@
+/*
+   3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux.
+
+   Written By: Adam Radford <linuxraid@amcc.com>
+
+   Copyright (C) 2004 Applied Micro Circuits Corporation.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   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.
+
+   NO WARRANTY
+   THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+   LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+   solely responsible for determining the appropriateness of using and
+   distributing the Program and assumes all risks associated with its
+   exercise of rights under this Agreement, including but not limited to
+   the risks and costs of program errors, damage to or loss of data,
+   programs or equipment, and unavailability or interruption of operations.
+
+   DISCLAIMER OF LIABILITY
+   NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+   USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+   HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+   Bugs/Comments/Suggestions should be mailed to:
+   linuxraid@amcc.com
+
+   For more information, goto:
+   http://www.amcc.com
+
+   Note: This version of the driver does not contain a bundled firmware
+         image.
+
+   History
+   -------
+   2.26.02.000 - Driver cleanup for kernel submission.
+   2.26.02.001 - Replace schedule_timeout() calls with msleep().
+*/
+
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/moduleparam.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/time.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_cmnd.h>
+#include "3w-9xxx.h"
+
+/* Globals */
+static const char *twa_driver_version="2.26.02.001";
+static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
+static unsigned int twa_device_extension_count;
+static int twa_major = -1;
+extern struct timezone sys_tz;
+
+/* Module parameters */
+MODULE_AUTHOR ("AMCC");
+MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver");
+MODULE_LICENSE("GPL");
+
+/* Function prototypes */
+static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header);
+static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
+static char *twa_aen_severity_lookup(unsigned char severity_code);
+static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id);
+static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int twa_chrdev_open(struct inode *inode, struct file *file);
+static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host);
+static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id);
+static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id);
+static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
+ 			      u32 set_features, unsigned short current_fw_srl, 
+			      unsigned short current_fw_arch_id, 
+			      unsigned short current_fw_branch, 
+			      unsigned short current_fw_build, 
+			      unsigned short *fw_on_ctlr_srl, 
+			      unsigned short *fw_on_ctlr_arch_id, 
+			      unsigned short *fw_on_ctlr_branch, 
+			      unsigned short *fw_on_ctlr_build, 
+			      u32 *init_connect_result);
+static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
+static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
+static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
+static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal);
+static int twa_reset_device_extension(TW_Device_Extension *tw_dev);
+static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset);
+static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Apache *sglistarg);
+static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
+static char *twa_string_lookup(twa_message_type *table, unsigned int aen_code);
+static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id);
+
+/* Functions */
+
+/* Show some statistics about the card */
+static ssize_t twa_show_stats(struct class_device *class_dev, char *buf)
+{
+	struct Scsi_Host *host = class_to_shost(class_dev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+	unsigned long flags = 0;
+	ssize_t len;
+
+	spin_lock_irqsave(tw_dev->host->host_lock, flags);
+	len = snprintf(buf, PAGE_SIZE, "Driver version: %s\n"
+		       "Current commands posted:   %4d\n"
+		       "Max commands posted:       %4d\n"
+		       "Current pending commands:  %4d\n"
+		       "Max pending commands:      %4d\n"
+		       "Last sgl length:           %4d\n"
+		       "Max sgl length:            %4d\n"
+		       "Last sector count:         %4d\n"
+		       "Max sector count:          %4d\n"
+		       "SCSI Host Resets:          %4d\n"
+		       "SCSI Aborts/Timeouts:      %4d\n"
+		       "AEN's:                     %4d\n", 
+		       twa_driver_version,
+		       tw_dev->posted_request_count,
+		       tw_dev->max_posted_request_count,
+		       tw_dev->pending_request_count,
+		       tw_dev->max_pending_request_count,
+		       tw_dev->sgl_entries,
+		       tw_dev->max_sgl_entries,
+		       tw_dev->sector_count,
+		       tw_dev->max_sector_count,
+		       tw_dev->num_resets,
+		       tw_dev->num_aborts,
+		       tw_dev->aen_count);
+	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+	return len;
+} /* End twa_show_stats() */
+
+/* This function will set a devices queue depth */
+static ssize_t twa_store_queue_depth(struct device *dev, const char *buf, size_t count)
+{
+	int queue_depth;
+	struct scsi_device *sdev = to_scsi_device(dev);
+
+	queue_depth = simple_strtoul(buf, NULL, 0);
+	if (queue_depth > TW_Q_LENGTH-2)
+		return -EINVAL;
+	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
+
+	return count;
+} /* End twa_store_queue_depth() */
+
+/* Create sysfs 'queue_depth' entry */
+static struct device_attribute twa_queue_depth_attr = {
+	.attr = {
+		.name =		"queue_depth",
+		.mode =		S_IRUSR | S_IWUSR,
+	},
+	.store = twa_store_queue_depth
+};
+
+/* Device attributes initializer */
+static struct device_attribute *twa_dev_attrs[] = {
+	&twa_queue_depth_attr,
+	NULL,
+};
+
+/* Create sysfs 'stats' entry */
+static struct class_device_attribute twa_host_stats_attr = {
+	.attr = {
+		.name = 	"stats",
+		.mode =		S_IRUGO,
+	},
+	.show = twa_show_stats
+};
+
+/* Host attributes initializer */
+static struct class_device_attribute *twa_host_attrs[] = {
+	&twa_host_stats_attr,
+	NULL,
+};
+
+/* File operations struct for character device */
+static struct file_operations twa_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= twa_chrdev_ioctl,
+	.open		= twa_chrdev_open,
+	.release	= NULL
+};
+
+/* This function will complete an aen request from the isr */
+static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Command_Apache_Header *header;
+	unsigned short aen;
+	int retval = 1;
+
+	header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
+	tw_dev->posted_request_count--;
+	aen = header->status_block.error;
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	command_packet = &full_command_packet->command.oldcommand;
+
+	/* First check for internal completion of set param for time sync */
+	if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
+		/* Keep reading the queue in case there are more aen's */
+		if (twa_aen_read_queue(tw_dev, request_id))
+			goto out2;
+	        else {
+			retval = 0;
+			goto out;
+		}
+	}
+
+	switch (aen) {
+	case TW_AEN_QUEUE_EMPTY:
+		/* Quit reading the queue if this is the last one */
+		break;
+	case TW_AEN_SYNC_TIME_WITH_HOST:
+		twa_aen_sync_time(tw_dev, request_id);
+		retval = 0;
+		goto out;
+	default:
+		twa_aen_queue_event(tw_dev, header);
+
+		/* If there are more aen's, keep reading the queue */
+		if (twa_aen_read_queue(tw_dev, request_id))
+			goto out2;
+		else {
+			retval = 0;
+			goto out;
+		}
+	}
+	retval = 0;
+out2:
+	tw_dev->state[request_id] = TW_S_COMPLETED;
+	twa_free_request_id(tw_dev, request_id);
+	clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
+out:
+	return retval;
+} /* End twa_aen_complete() */
+
+/* This function will drain aen queue */
+static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
+{
+	int request_id = 0;
+	char cdb[TW_MAX_CDB_LEN];
+	TW_SG_Apache sglist[1];
+	int finished = 0, count = 0;
+	TW_Command_Full *full_command_packet;
+	TW_Command_Apache_Header *header;
+	unsigned short aen;
+	int first_reset = 0, queue = 0, retval = 1;
+
+	if (no_check_reset)
+		first_reset = 0;
+	else
+		first_reset = 1;
+
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+
+	/* Initialize cdb */
+	memset(&cdb, 0, TW_MAX_CDB_LEN);
+	cdb[0] = REQUEST_SENSE; /* opcode */
+	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
+
+	/* Initialize sglist */
+	memset(&sglist, 0, sizeof(TW_SG_Apache));
+	sglist[0].length = TW_SECTOR_SIZE;
+	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
+
+	if (sglist[0].address & TW_ALIGNMENT_9000_SGL) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Found unaligned address during AEN drain");
+		goto out;
+	}
+
+	/* Mark internal command */
+	tw_dev->srb[request_id] = NULL;
+
+	do {
+		/* Send command to the board */
+		if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Error posting request sense");
+			goto out;
+		}
+
+		/* Now poll for completion */
+		if (twa_poll_response(tw_dev, request_id, 30)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "No valid response while draining AEN queue");
+			tw_dev->posted_request_count--;
+			goto out;
+		}
+
+		tw_dev->posted_request_count--;
+		header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
+		aen = header->status_block.error;
+		queue = 0;
+		count++;
+
+		switch (aen) {
+		case TW_AEN_QUEUE_EMPTY:
+			if (first_reset != 1)
+				goto out;
+			else
+				finished = 1;
+			break;
+		case TW_AEN_SOFT_RESET:
+			if (first_reset == 0)
+				first_reset = 1;
+			else
+				queue = 1;
+			break;
+		case TW_AEN_SYNC_TIME_WITH_HOST:
+			break;
+		default:
+			queue = 1;
+		}
+
+		/* Now queue an event info */
+		if (queue)
+			twa_aen_queue_event(tw_dev, header);
+	} while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
+
+	if (count == TW_MAX_AEN_DRAIN)
+		goto out;
+
+	retval = 0;
+out:
+	tw_dev->state[request_id] = TW_S_INITIAL;
+	return retval;
+} /* End twa_aen_drain_queue() */
+
+/* This function will queue an event */
+static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
+{
+	u32 local_time;
+	struct timeval time;
+	TW_Event *event;
+	unsigned short aen;
+	char host[16];
+
+	tw_dev->aen_count++;
+
+	/* Fill out event info */
+	event = tw_dev->event_queue[tw_dev->error_index];
+
+	/* Check for clobber */
+	host[0] = '\0';
+	if (tw_dev->host) {
+		sprintf(host, " scsi%d:", tw_dev->host->host_no);
+		if (event->retrieved == TW_AEN_NOT_RETRIEVED)
+			tw_dev->aen_clobber = 1;
+	}
+
+	aen = header->status_block.error;
+	memset(event, 0, sizeof(TW_Event));
+
+	event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
+	do_gettimeofday(&time);
+	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
+	event->time_stamp_sec = local_time;
+	event->aen_code = aen;
+	event->retrieved = TW_AEN_NOT_RETRIEVED;
+	event->sequence_id = tw_dev->error_sequence_id;
+	tw_dev->error_sequence_id++;
+
+	header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
+	event->parameter_len = strlen(header->err_specific_desc);
+	memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len);
+	if (event->severity != TW_AEN_SEVERITY_DEBUG)
+		printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
+		       host,
+		       twa_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
+		       TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen,
+		       twa_string_lookup(twa_aen_table, aen),
+		       header->err_specific_desc);
+	else
+		tw_dev->aen_count--;
+
+	if ((tw_dev->error_index + 1) == TW_Q_LENGTH)
+		tw_dev->event_queue_wrapped = 1;
+	tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
+} /* End twa_aen_queue_event() */
+
+/* This function will read the aen queue from the isr */
+static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
+{
+	char cdb[TW_MAX_CDB_LEN];
+	TW_SG_Apache sglist[1];
+	TW_Command_Full *full_command_packet;
+	int retval = 1;
+
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+
+	/* Initialize cdb */
+	memset(&cdb, 0, TW_MAX_CDB_LEN);
+	cdb[0] = REQUEST_SENSE; /* opcode */
+	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
+
+	/* Initialize sglist */
+	memset(&sglist, 0, sizeof(TW_SG_Apache));
+	sglist[0].length = TW_SECTOR_SIZE;
+	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
+
+	/* Mark internal command */
+	tw_dev->srb[request_id] = NULL;
+
+	/* Now post the command packet */
+	if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "Post failed while reading AEN queue");
+		goto out;
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twa_aen_read_queue() */
+
+/* This function will look up an AEN severity string */
+static char *twa_aen_severity_lookup(unsigned char severity_code)
+{
+	char *retval = NULL;
+
+	if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
+	    (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
+		goto out;
+
+	retval = twa_aen_severity_table[severity_code];
+out:
+	return retval;
+} /* End twa_aen_severity_lookup() */
+
+/* This function will sync firmware time with the host time */
+static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
+{
+	u32 schedulertime;
+	struct timeval utc;
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Param_Apache *param;
+	u32 local_time;
+
+	/* Fill out the command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+	command_packet = &full_command_packet->command.oldcommand;
+	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
+	command_packet->request_id = request_id;
+	command_packet->byte8_offset.param.sgl[0].address = tw_dev->generic_buffer_phys[request_id];
+	command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
+	command_packet->size = TW_COMMAND_SIZE;
+	command_packet->byte6_offset.parameter_count = 1;
+
+	/* Setup the param */
+	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
+	memset(param, 0, TW_SECTOR_SIZE);
+	param->table_id = TW_TIMEKEEP_TABLE | 0x8000; /* Controller time keep table */
+	param->parameter_id = 0x3; /* SchedulerTime */
+	param->parameter_size_bytes = 4;
+
+	/* Convert system time in UTC to local time seconds since last 
+           Sunday 12:00AM */
+	do_gettimeofday(&utc);
+	local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
+	schedulertime = local_time - (3 * 86400);
+	schedulertime = schedulertime % 604800;
+
+	memcpy(param->data, &schedulertime, sizeof(u32));
+
+	/* Mark internal command */
+	tw_dev->srb[request_id] = NULL;
+
+	/* Now post the command */
+	twa_post_command_packet(tw_dev, request_id, 1);
+} /* End twa_aen_sync_time() */
+
+/* This function will allocate memory and check if it is correctly aligned */
+static int twa_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
+{
+	int i;
+	dma_addr_t dma_handle;
+	unsigned long *cpu_addr;
+	int retval = 1;
+
+	cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
+	if (!cpu_addr) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
+		goto out;
+	}
+
+	if ((unsigned long)cpu_addr % (TW_ALIGNMENT_9000)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x6, "Failed to allocate correctly aligned memory");
+		pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
+		goto out;
+	}
+
+	memset(cpu_addr, 0, size*TW_Q_LENGTH);
+
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		switch(which) {
+		case 0:
+			tw_dev->command_packet_phys[i] = dma_handle+(i*size);
+			tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
+			break;
+		case 1:
+			tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
+			tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
+			break;
+		}
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twa_allocate_memory() */
+
+/* This function will check the status register for unexpected bits */
+static int twa_check_bits(u32 status_reg_value)
+{
+	int retval = 1;
+
+	if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS)
+		goto out;
+	if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0)
+		goto out;
+
+	retval = 0;
+out:
+	return retval;
+} /* End twa_check_bits() */
+
+/* This function will check the srl and decide if we are compatible  */
+static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed)
+{
+	int retval = 1;
+	unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
+	unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
+	u32 init_connect_result = 0;
+
+	if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
+			       TW_EXTENDED_INIT_CONNECT, TW_CURRENT_FW_SRL,
+			       TW_9000_ARCH_ID, TW_CURRENT_FW_BRANCH,
+			       TW_CURRENT_FW_BUILD, &fw_on_ctlr_srl,
+			       &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
+			       &fw_on_ctlr_build, &init_connect_result)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "Initconnection failed while checking SRL");
+		goto out;
+	}
+
+	tw_dev->working_srl = TW_CURRENT_FW_SRL;
+	tw_dev->working_branch = TW_CURRENT_FW_BRANCH;
+	tw_dev->working_build = TW_CURRENT_FW_BUILD;
+
+	/* Try base mode compatibility */
+	if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
+		if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
+				       TW_EXTENDED_INIT_CONNECT,
+				       TW_BASE_FW_SRL, TW_9000_ARCH_ID,
+				       TW_BASE_FW_BRANCH, TW_BASE_FW_BUILD,
+				       &fw_on_ctlr_srl, &fw_on_ctlr_arch_id,
+				       &fw_on_ctlr_branch, &fw_on_ctlr_build,
+				       &init_connect_result)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Initconnection (base mode) failed while checking SRL");
+			goto out;
+		}
+		if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
+			if (TW_CURRENT_FW_SRL > fw_on_ctlr_srl) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x32, "Firmware and driver incompatibility: please upgrade firmware");
+			} else {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x33, "Firmware and driver incompatibility: please upgrade driver");
+			}
+			goto out;
+		}
+		tw_dev->working_srl = TW_BASE_FW_SRL;
+		tw_dev->working_branch = TW_BASE_FW_BRANCH;
+		tw_dev->working_build = TW_BASE_FW_BUILD;
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twa_check_srl() */
+
+/* This function handles ioctl for the character device */
+static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	long timeout;
+	unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
+	dma_addr_t dma_handle;
+	int request_id = 0;
+	unsigned int sequence_id = 0;
+	unsigned char event_index, start_index;
+	TW_Ioctl_Driver_Command driver_command;
+	TW_Ioctl_Buf_Apache *tw_ioctl;
+	TW_Lock *tw_lock;
+	TW_Command_Full *full_command_packet;
+	TW_Compatibility_Info *tw_compat_info;
+	TW_Event *event;
+	struct timeval current_time;
+	u32 current_time_ms;
+	TW_Device_Extension *tw_dev = twa_device_extension_list[iminor(inode)];
+	int retval = TW_IOCTL_ERROR_OS_EFAULT;
+
+	/* Only let one of these through at a time */
+	if (down_interruptible(&tw_dev->ioctl_sem)) {
+		retval = TW_IOCTL_ERROR_OS_EINTR;
+		goto out;
+	}
+
+	/* First copy down the driver command */
+	if (copy_from_user(&driver_command, (void *)arg, sizeof(TW_Ioctl_Driver_Command)))
+		goto out2;
+
+	/* Check data buffer size */
+	if (driver_command.buffer_length > TW_MAX_SECTORS * 512) {
+		retval = TW_IOCTL_ERROR_OS_EINVAL;
+		goto out2;
+	}
+
+	/* Hardware can only do multiple of 512 byte transfers */
+	data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
+
+	/* Now allocate ioctl buf memory */
+	cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, &dma_handle);
+	if (!cpu_addr) {
+		retval = TW_IOCTL_ERROR_OS_ENOMEM;
+		goto out2;
+	}
+
+	tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
+
+	/* Now copy down the entire ioctl */
+	if (copy_from_user(tw_ioctl, (void *)arg, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
+		goto out3;
+
+	/* See which ioctl we are doing */
+	switch (cmd) {
+	case TW_IOCTL_FIRMWARE_PASS_THROUGH:
+		spin_lock_irqsave(tw_dev->host->host_lock, flags);
+		twa_get_request_id(tw_dev, &request_id);
+
+		/* Flag internal command */
+		tw_dev->srb[request_id] = 0;
+
+		/* Flag chrdev ioctl */
+		tw_dev->chrdev_request_id = request_id;
+
+		full_command_packet = &tw_ioctl->firmware_command;
+
+		/* Load request id and sglist for both command types */
+		twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
+
+		memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
+
+		/* Now post the command packet to the controller */
+		twa_post_command_packet(tw_dev, request_id, 1);
+		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+
+		timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
+
+		/* Now wait for command to complete */
+		timeout = wait_event_interruptible_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
+
+		/* Check if we timed out, got a signal, or didn't get
+                   an interrupt */
+		if ((timeout <= 0) && (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE)) {
+			/* Now we need to reset the board */
+			if (timeout == TW_IOCTL_ERROR_OS_ERESTARTSYS) {
+				retval = timeout;
+			} else {
+				printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
+				       tw_dev->host->host_no, TW_DRIVER, 0xc,
+				       cmd);
+				retval = TW_IOCTL_ERROR_OS_EIO;
+			}
+			spin_lock_irqsave(tw_dev->host->host_lock, flags);
+			tw_dev->state[request_id] = TW_S_COMPLETED;
+			twa_free_request_id(tw_dev, request_id);
+			tw_dev->posted_request_count--;
+			twa_reset_device_extension(tw_dev);
+			spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+			goto out3;
+		}
+
+		/* Now copy in the command packet response */
+		memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
+		
+		/* Now complete the io */
+		spin_lock_irqsave(tw_dev->host->host_lock, flags);
+		tw_dev->posted_request_count--;
+		tw_dev->state[request_id] = TW_S_COMPLETED;
+		twa_free_request_id(tw_dev, request_id);
+		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
+		break;
+	case TW_IOCTL_GET_COMPATIBILITY_INFO:
+		tw_ioctl->driver_command.status = 0;
+		/* Copy compatiblity struct into ioctl data buffer */
+		tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
+		strncpy(tw_compat_info->driver_version, twa_driver_version, strlen(twa_driver_version));
+		tw_compat_info->working_srl = tw_dev->working_srl;
+		tw_compat_info->working_branch = tw_dev->working_branch;
+		tw_compat_info->working_build = tw_dev->working_build;
+		break;
+	case TW_IOCTL_GET_LAST_EVENT:
+		if (tw_dev->event_queue_wrapped) {
+			if (tw_dev->aen_clobber) {
+				tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
+				tw_dev->aen_clobber = 0;
+			} else
+				tw_ioctl->driver_command.status = 0;
+		} else {
+			if (!tw_dev->error_index) {
+				tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+				break;
+			}
+			tw_ioctl->driver_command.status = 0;
+		}
+		event_index = (tw_dev->error_index - 1 + TW_Q_LENGTH) % TW_Q_LENGTH;
+		memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
+		tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
+		break;
+	case TW_IOCTL_GET_FIRST_EVENT:
+		if (tw_dev->event_queue_wrapped) {
+			if (tw_dev->aen_clobber) {
+				tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
+				tw_dev->aen_clobber = 0;
+			} else 
+				tw_ioctl->driver_command.status = 0;
+			event_index = tw_dev->error_index;
+		} else {
+			if (!tw_dev->error_index) {
+				tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+				break;
+			}
+			tw_ioctl->driver_command.status = 0;
+			event_index = 0;
+		}
+		memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
+		tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
+		break;
+	case TW_IOCTL_GET_NEXT_EVENT:
+		event = (TW_Event *)tw_ioctl->data_buffer;
+		sequence_id = event->sequence_id;
+		tw_ioctl->driver_command.status = 0;
+
+		if (tw_dev->event_queue_wrapped) {
+			if (tw_dev->aen_clobber) {
+				tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
+				tw_dev->aen_clobber = 0;
+			}
+			start_index = tw_dev->error_index;
+		} else {
+			if (!tw_dev->error_index) {
+				tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+				break;
+			}
+			start_index = 0;
+		}
+		event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id + 1) % TW_Q_LENGTH;
+
+		if (!(tw_dev->event_queue[event_index]->sequence_id > sequence_id)) {
+			if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
+				tw_dev->aen_clobber = 1;
+			tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+			break;
+		}
+		memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
+		tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
+		break;
+	case TW_IOCTL_GET_PREVIOUS_EVENT:
+		event = (TW_Event *)tw_ioctl->data_buffer;
+		sequence_id = event->sequence_id;
+		tw_ioctl->driver_command.status = 0;
+
+		if (tw_dev->event_queue_wrapped) {
+			if (tw_dev->aen_clobber) {
+				tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
+				tw_dev->aen_clobber = 0;
+			}
+			start_index = tw_dev->error_index;
+		} else {
+			if (!tw_dev->error_index) {
+				tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+				break;
+			}
+			start_index = 0;
+		}
+		event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id - 1) % TW_Q_LENGTH;
+
+		if (!(tw_dev->event_queue[event_index]->sequence_id < sequence_id)) {
+			if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
+				tw_dev->aen_clobber = 1;
+			tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
+			break;
+		}
+		memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
+		tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
+		break;
+	case TW_IOCTL_GET_LOCK:
+		tw_lock = (TW_Lock *)tw_ioctl->data_buffer;
+		do_gettimeofday(&current_time);
+		current_time_ms = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000);
+
+		if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || (current_time_ms >= tw_dev->ioctl_msec)) {
+			tw_dev->ioctl_sem_lock = 1;
+			tw_dev->ioctl_msec = current_time_ms + tw_lock->timeout_msec;
+			tw_ioctl->driver_command.status = 0;
+			tw_lock->time_remaining_msec = tw_lock->timeout_msec;
+		} else {
+			tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED;
+			tw_lock->time_remaining_msec = tw_dev->ioctl_msec - current_time_ms;
+		}
+		break;
+	case TW_IOCTL_RELEASE_LOCK:
+		if (tw_dev->ioctl_sem_lock == 1) {
+			tw_dev->ioctl_sem_lock = 0;
+			tw_ioctl->driver_command.status = 0;
+		} else {
+			tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NOT_LOCKED;
+		}
+		break;
+	default:
+		retval = TW_IOCTL_ERROR_OS_ENOTTY;
+		goto out3;
+	}
+
+	/* Now copy the entire response to userspace */
+	if (copy_to_user((void *)arg, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
+		retval = 0;
+out3:
+	/* Now free ioctl buf memory */
+	pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
+out2:
+	up(&tw_dev->ioctl_sem);
+out:
+	return retval;
+} /* End twa_chrdev_ioctl() */
+
+/* This function handles open for the character device */
+static int twa_chrdev_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor_number;
+	int retval = TW_IOCTL_ERROR_OS_ENODEV;
+
+	minor_number = iminor(inode);
+	if (minor_number >= twa_device_extension_count)
+		goto out;
+	retval = 0;
+out:
+	return retval;
+} /* End twa_chrdev_open() */
+
+/* This function will print readable messages from status register errors */
+static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
+{
+	int retval = 1;
+
+	/* Check for various error conditions and handle them appropriately */
+	if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "PCI Parity Error: clearing");
+		writel(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
+	}
+
+	if (status_reg_value & TW_STATUS_PCI_ABORT) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "PCI Abort: clearing");
+		writel(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
+		pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
+	}
+
+	if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
+		writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
+	}
+
+	if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "SBUF Write Error: clearing");
+		writel(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
+	}
+
+	if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
+		if (tw_dev->reset_print == 0) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing");
+			tw_dev->reset_print = 1;
+		}
+		goto out;
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twa_decode_bits() */
+
+/* This function will empty the response queue */
+static int twa_empty_response_queue(TW_Device_Extension *tw_dev)
+{
+	u32 status_reg_value, response_que_value;
+	int count = 0, retval = 1;
+
+	status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+
+	while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) {
+		response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
+		status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+		count++;
+	}
+	if (count == TW_MAX_RESPONSE_DRAIN)
+		goto out;
+
+	retval = 0;
+out:
+	return retval;
+} /* End twa_empty_response_queue() */
+
+/* This function passes sense keys from firmware to scsi layer */
+static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host)
+{
+	TW_Command_Full *full_command_packet;
+	unsigned short error;
+	int retval = 1;
+
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	/* Don't print error for Logical unit not supported during rollcall */
+	error = full_command_packet->header.status_block.error;
+	if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) {
+		if (print_host)
+			printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
+			       tw_dev->host->host_no,
+			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
+			       full_command_packet->header.status_block.error,
+			       twa_string_lookup(twa_error_table,
+						 full_command_packet->header.status_block.error),
+			       full_command_packet->header.err_specific_desc);
+		else
+			printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s:%s.\n",
+			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
+			       full_command_packet->header.status_block.error,
+			       twa_string_lookup(twa_error_table,
+						 full_command_packet->header.status_block.error),
+			       full_command_packet->header.err_specific_desc);
+	}
+
+	if (copy_sense) {
+		memcpy(tw_dev->srb[request_id]->sense_buffer, full_command_packet->header.sense_data, TW_SENSE_DATA_LENGTH);
+		tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
+		retval = TW_ISR_DONT_RESULT;
+		goto out;
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twa_fill_sense() */
+
+/* This function will free up device extension resources */
+static void twa_free_device_extension(TW_Device_Extension *tw_dev)
+{
+	if (tw_dev->command_packet_virt[0])
+		pci_free_consistent(tw_dev->tw_pci_dev,
+				    sizeof(TW_Command_Full)*TW_Q_LENGTH,
+				    tw_dev->command_packet_virt[0],
+				    tw_dev->command_packet_phys[0]);
+
+	if (tw_dev->generic_buffer_virt[0])
+		pci_free_consistent(tw_dev->tw_pci_dev,
+				    TW_SECTOR_SIZE*TW_Q_LENGTH,
+				    tw_dev->generic_buffer_virt[0],
+				    tw_dev->generic_buffer_phys[0]);
+
+	if (tw_dev->event_queue[0])
+		kfree(tw_dev->event_queue[0]);
+} /* End twa_free_device_extension() */
+
+/* This function will free a request id */
+static void twa_free_request_id(TW_Device_Extension *tw_dev, int request_id)
+{
+	tw_dev->free_queue[tw_dev->free_tail] = request_id;
+	tw_dev->state[request_id] = TW_S_FINISHED;
+	tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
+} /* End twa_free_request_id() */
+
+/* This function will get parameter table entires from the firmware */
+static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Param_Apache *param;
+	unsigned long param_value;
+	void *retval = NULL;
+
+	/* Setup the command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+	command_packet = &full_command_packet->command.oldcommand;
+
+	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
+	command_packet->size              = TW_COMMAND_SIZE;
+	command_packet->request_id        = request_id;
+	command_packet->byte6_offset.block_count = 1;
+
+	/* Now setup the param */
+	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
+	memset(param, 0, TW_SECTOR_SIZE);
+	param->table_id = table_id | 0x8000;
+	param->parameter_id = parameter_id;
+	param->parameter_size_bytes = parameter_size_bytes;
+	param_value = tw_dev->generic_buffer_phys[request_id];
+
+	command_packet->byte8_offset.param.sgl[0].address = param_value;
+	command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
+
+	/* Post the command packet to the board */
+	twa_post_command_packet(tw_dev, request_id, 1);
+
+	/* Poll for completion */
+	if (twa_poll_response(tw_dev, request_id, 30))
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "No valid response during get param")
+	else
+		retval = (void *)&(param->data[0]);
+
+	tw_dev->posted_request_count--;
+	tw_dev->state[request_id] = TW_S_INITIAL;
+
+	return retval;
+} /* End twa_get_param() */
+
+/* This function will assign an available request id */
+static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
+{
+	*request_id = tw_dev->free_queue[tw_dev->free_head];
+	tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
+	tw_dev->state[*request_id] = TW_S_STARTED;
+} /* End twa_get_request_id() */
+
+/* This function will send an initconnection command to controller */
+static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
+ 			      u32 set_features, unsigned short current_fw_srl, 
+			      unsigned short current_fw_arch_id, 
+			      unsigned short current_fw_branch, 
+			      unsigned short current_fw_build, 
+			      unsigned short *fw_on_ctlr_srl, 
+			      unsigned short *fw_on_ctlr_arch_id, 
+			      unsigned short *fw_on_ctlr_branch, 
+			      unsigned short *fw_on_ctlr_build, 
+			      u32 *init_connect_result)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Initconnect *tw_initconnect;
+	int request_id = 0, retval = 1;
+
+	/* Initialize InitConnection command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	memset(full_command_packet, 0, sizeof(TW_Command_Full));
+	full_command_packet->header.header_desc.size_header = 128;
+	
+	tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
+	tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
+	tw_initconnect->request_id = request_id;
+	tw_initconnect->message_credits = message_credits;
+	tw_initconnect->features = set_features;
+#if BITS_PER_LONG > 32
+	/* Turn on 64-bit sgl support */
+	tw_initconnect->features |= 1;
+#endif
+
+	if (set_features & TW_EXTENDED_INIT_CONNECT) {
+		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
+		tw_initconnect->fw_srl = current_fw_srl;
+		tw_initconnect->fw_arch_id = current_fw_arch_id;
+		tw_initconnect->fw_branch = current_fw_branch;
+		tw_initconnect->fw_build = current_fw_build;
+	} else 
+		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
+
+	/* Send command packet to the board */
+	twa_post_command_packet(tw_dev, request_id, 1);
+
+	/* Poll for completion */
+	if (twa_poll_response(tw_dev, request_id, 30)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection");
+	} else {
+		if (set_features & TW_EXTENDED_INIT_CONNECT) {
+			*fw_on_ctlr_srl = tw_initconnect->fw_srl;
+			*fw_on_ctlr_arch_id = tw_initconnect->fw_arch_id;
+			*fw_on_ctlr_branch = tw_initconnect->fw_branch;
+			*fw_on_ctlr_build = tw_initconnect->fw_build;
+			*init_connect_result = tw_initconnect->result;
+		}
+		retval = 0;
+	}
+
+	tw_dev->posted_request_count--;
+	tw_dev->state[request_id] = TW_S_INITIAL;
+
+	return retval;
+} /* End twa_initconnection() */
+
+/* This function will initialize the fields of a device extension */
+static int twa_initialize_device_extension(TW_Device_Extension *tw_dev)
+{
+	int i, retval = 1;
+
+	/* Initialize command packet buffers */
+	if (twa_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Command packet memory allocation failed");
+		goto out;
+	}
+
+	/* Initialize generic buffer */
+	if (twa_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x17, "Generic memory allocation failed");
+		goto out;
+	}
+
+	/* Allocate event info space */
+	tw_dev->event_queue[0] = kmalloc(sizeof(TW_Event) * TW_Q_LENGTH, GFP_KERNEL);
+	if (!tw_dev->event_queue[0]) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed");
+		goto out;
+	}
+
+	memset(tw_dev->event_queue[0], 0, sizeof(TW_Event) * TW_Q_LENGTH);
+
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
+		tw_dev->free_queue[i] = i;
+		tw_dev->state[i] = TW_S_INITIAL;
+	}
+
+	tw_dev->pending_head = TW_Q_START;
+	tw_dev->pending_tail = TW_Q_START;
+	tw_dev->free_head = TW_Q_START;
+	tw_dev->free_tail = TW_Q_START;
+	tw_dev->error_sequence_id = 1;
+	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+
+	init_MUTEX(&tw_dev->ioctl_sem);
+	init_waitqueue_head(&tw_dev->ioctl_wqueue);
+
+	retval = 0;
+out:
+	return retval;
+} /* End twa_initialize_device_extension() */
+
+/* This function is the interrupt service routine */
+static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	int request_id, error = 0;
+	u32 status_reg_value;
+	TW_Response_Queue response_que;
+	TW_Command_Full *full_command_packet;
+	TW_Command *command_packet;
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
+	int handled = 0;
+
+	/* Get the per adapter lock */
+	spin_lock(tw_dev->host->host_lock);
+
+	/* See if the interrupt matches this instance */
+	if (tw_dev->tw_pci_dev->irq == (unsigned int)irq) {
+
+		handled = 1;
+
+		/* Read the registers */
+		status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+
+		/* Check if this is our interrupt, otherwise bail */
+		if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
+			goto twa_interrupt_bail;
+
+		/* Check controller for errors */
+		if (twa_check_bits(status_reg_value)) {
+			if (twa_decode_bits(tw_dev, status_reg_value)) {
+				TW_CLEAR_ALL_INTERRUPTS(tw_dev);
+				goto twa_interrupt_bail;
+			}
+		}
+
+		/* Handle host interrupt */
+		if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
+			TW_CLEAR_HOST_INTERRUPT(tw_dev);
+
+		/* Handle attention interrupt */
+		if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
+			TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
+			if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
+				twa_get_request_id(tw_dev, &request_id);
+
+				error = twa_aen_read_queue(tw_dev, request_id);
+				if (error) {
+					tw_dev->state[request_id] = TW_S_COMPLETED;
+					twa_free_request_id(tw_dev, request_id);
+					clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
+				}
+			}
+		}
+
+		/* Handle command interrupt */
+		if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
+			TW_MASK_COMMAND_INTERRUPT(tw_dev);
+			/* Drain as many pending commands as we can */
+			while (tw_dev->pending_request_count > 0) {
+				request_id = tw_dev->pending_queue[tw_dev->pending_head];
+				if (tw_dev->state[request_id] != TW_S_PENDING) {
+					TW_PRINTK(tw_dev->host, TW_DRIVER, 0x19, "Found request id that wasn't pending");
+					TW_CLEAR_ALL_INTERRUPTS(tw_dev);
+					goto twa_interrupt_bail;
+				}
+				if (twa_post_command_packet(tw_dev, request_id, 1)==0) {
+					tw_dev->pending_head = (tw_dev->pending_head + 1) % TW_Q_LENGTH;
+					tw_dev->pending_request_count--;
+				} else {
+					/* If we get here, we will continue re-posting on the next command interrupt */
+					break;
+				}
+			}
+		}
+
+		/* Handle response interrupt */
+		if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
+
+			/* Drain the response queue from the board */
+			while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+				/* Complete the response */
+				response_que.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
+				request_id = TW_RESID_OUT(response_que.response_id);
+				full_command_packet = tw_dev->command_packet_virt[request_id];
+				error = 0;
+				command_packet = &full_command_packet->command.oldcommand;
+				/* Check for command packet errors */
+				if (full_command_packet->command.newcommand.status != 0) {
+					if (tw_dev->srb[request_id] != 0) {
+						error = twa_fill_sense(tw_dev, request_id, 1, 1);
+					} else {
+						/* Skip ioctl error prints */
+						if (request_id != tw_dev->chrdev_request_id) {
+							error = twa_fill_sense(tw_dev, request_id, 0, 1);
+						}
+					}
+				}
+
+				/* Check for correct state */
+				if (tw_dev->state[request_id] != TW_S_POSTED) {
+					if (tw_dev->srb[request_id] != 0) {
+						TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted");
+					        TW_CLEAR_ALL_INTERRUPTS(tw_dev);
+						goto twa_interrupt_bail;
+					}
+				}
+
+				/* Check for internal command completion */
+				if (tw_dev->srb[request_id] == 0) {
+					if (request_id != tw_dev->chrdev_request_id) {
+						if (twa_aen_complete(tw_dev, request_id))
+							TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt");
+					} else {
+						tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+						wake_up(&tw_dev->ioctl_wqueue);
+					}
+				} else {
+					twa_scsiop_execute_scsi_complete(tw_dev, request_id);
+					/* If no error command was a success */
+					if (error == 0) {
+						tw_dev->srb[request_id]->result = (DID_OK << 16);
+					}
+
+					/* If error, command failed */
+					if (error == 1) {
+						/* Ask for a host reset */
+						tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
+					}
+
+					/* Now complete the io */
+					tw_dev->state[request_id] = TW_S_COMPLETED;
+					twa_free_request_id(tw_dev, request_id);
+					tw_dev->posted_request_count--;
+					tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+					twa_unmap_scsi_data(tw_dev, request_id);
+				}
+
+				/* Check for valid status after each drain */
+				status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+				if (twa_check_bits(status_reg_value)) {
+					if (twa_decode_bits(tw_dev, status_reg_value)) {
+						TW_CLEAR_ALL_INTERRUPTS(tw_dev);
+						goto twa_interrupt_bail;
+					}
+				}
+			}
+		}
+	}
+twa_interrupt_bail:
+	spin_unlock(tw_dev->host->host_lock);
+	return IRQ_RETVAL(handled);
+} /* End twa_interrupt() */
+
+/* This function will load the request id and various sgls for ioctls */
+static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
+{
+	TW_Command *oldcommand;
+	TW_Command_Apache *newcommand;
+	TW_SG_Entry *sgl;
+
+	if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
+		newcommand = &full_command_packet->command.newcommand;
+		newcommand->request_id = request_id;
+		newcommand->sg_list[0].address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
+		newcommand->sg_list[0].length = length;
+	} else {
+		oldcommand = &full_command_packet->command.oldcommand;
+		oldcommand->request_id = request_id;
+
+		if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
+			/* Load the sg list */
+			sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
+			sgl->address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
+			sgl->length = length;
+		}
+	}
+} /* End twa_load_sgl() */
+
+/* This function will perform a pci-dma mapping for a scatter gather list */
+static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
+{
+	int use_sg;
+	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+	struct pci_dev *pdev = tw_dev->tw_pci_dev;
+	int retval = 0;
+
+	if (cmd->use_sg == 0)
+		goto out;
+
+	use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
+
+	if (use_sg == 0) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
+		goto out;
+	}
+
+	cmd->SCp.phase = TW_PHASE_SGLIST;
+	cmd->SCp.have_data_in = use_sg;
+	retval = use_sg;
+out:
+	return retval;
+} /* End twa_map_scsi_sg_data() */
+
+/* This function will perform a pci-dma map for a single buffer */
+static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int request_id)
+{
+	dma_addr_t mapping;
+	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+	struct pci_dev *pdev = tw_dev->tw_pci_dev;
+	int retval = 0;
+
+	if (cmd->request_bufflen == 0) {
+		retval = 0;
+		goto out;
+	}
+
+	mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, DMA_BIDIRECTIONAL);
+
+	if (mapping == 0) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Failed to map page");
+		goto out;
+	}
+
+	cmd->SCp.phase = TW_PHASE_SINGLE;
+	cmd->SCp.have_data_in = mapping;
+	retval = mapping;
+out:
+	return retval;
+} /* End twa_map_scsi_single_data() */
+
+/* This function will poll for a response interrupt of a request */
+static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
+{
+	int retval = 1, found = 0, response_request_id;
+	TW_Response_Queue response_queue;
+	TW_Command_Full *full_command_packet = tw_dev->command_packet_virt[request_id];
+
+	if (twa_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, seconds) == 0) {
+		response_queue.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
+		response_request_id = TW_RESID_OUT(response_queue.response_id);
+		if (request_id != response_request_id) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "Found unexpected request id while polling for response");
+			goto out;
+		}
+		if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
+			if (full_command_packet->command.newcommand.status != 0) {
+				/* bad response */
+				twa_fill_sense(tw_dev, request_id, 0, 0);
+				goto out;
+			}
+			found = 1;
+		} else {
+			if (full_command_packet->command.oldcommand.status != 0) {
+				/* bad response */
+				twa_fill_sense(tw_dev, request_id, 0, 0);
+				goto out;
+			}
+			found = 1;
+		}
+	}
+
+	if (found)
+		retval = 0;
+out:
+	return retval;
+} /* End twa_poll_response() */
+
+/* This function will poll the status register for a flag */
+static int twa_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
+{
+	u32 status_reg_value; 
+	unsigned long before;
+	int retval = 1;
+
+	status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+	before = jiffies;
+
+	if (twa_check_bits(status_reg_value))
+		twa_decode_bits(tw_dev, status_reg_value);
+
+	while ((status_reg_value & flag) != flag) {
+		status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+
+		if (twa_check_bits(status_reg_value))
+			twa_decode_bits(tw_dev, status_reg_value);
+
+		if (time_after(jiffies, before + HZ * seconds))
+			goto out;
+
+		msleep(50);
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twa_poll_status() */
+
+/* This function will poll the status register for disappearance of a flag */
+static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
+{
+	u32 status_reg_value;
+	unsigned long before;
+	int retval = 1;
+
+	status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+	before = jiffies;
+
+	if (twa_check_bits(status_reg_value))
+		twa_decode_bits(tw_dev, status_reg_value);
+
+	while ((status_reg_value & flag) != 0) {
+		status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+		if (twa_check_bits(status_reg_value))
+			twa_decode_bits(tw_dev, status_reg_value);
+
+		if (time_after(jiffies, before + HZ * seconds))
+			goto out;
+
+		msleep(50);
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twa_poll_status_gone() */
+
+/* This function will attempt to post a command packet to the board */
+static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal)
+{
+	u32 status_reg_value;
+	unsigned long command_que_value;
+	int retval = 1;
+
+	command_que_value = tw_dev->command_packet_phys[request_id];
+	status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
+
+	if (twa_check_bits(status_reg_value))
+		twa_decode_bits(tw_dev, status_reg_value);
+
+	if (((tw_dev->pending_request_count > 0) && (tw_dev->state[request_id] != TW_S_PENDING)) || (status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL)) {
+
+		/* Only pend internal driver commands */
+		if (!internal) {
+			retval = SCSI_MLQUEUE_HOST_BUSY;
+			goto out;
+		}
+
+		/* Couldn't post the command packet, so we do it later */
+		if (tw_dev->state[request_id] != TW_S_PENDING) {
+			tw_dev->state[request_id] = TW_S_PENDING;
+			tw_dev->pending_request_count++;
+			if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
+				tw_dev->max_pending_request_count = tw_dev->pending_request_count;
+			}
+			tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
+			tw_dev->pending_tail = (tw_dev->pending_tail + 1) % TW_Q_LENGTH;
+		}
+		TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
+		goto out;
+	} else {
+		/* We successfully posted the command packet */
+#if BITS_PER_LONG > 32
+		writeq(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
+#else
+		writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
+#endif
+		tw_dev->state[request_id] = TW_S_POSTED;
+		tw_dev->posted_request_count++;
+		if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
+			tw_dev->max_posted_request_count = tw_dev->posted_request_count;
+		}
+	}
+	retval = 0;
+out:
+	return retval;
+} /* End twa_post_command_packet() */
+
+/* This function will reset a device extension */
+static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
+{
+	int i = 0;
+	int retval = 1;
+
+	/* Abort all requests that are in progress */
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		if ((tw_dev->state[i] != TW_S_FINISHED) &&
+		    (tw_dev->state[i] != TW_S_INITIAL) &&
+		    (tw_dev->state[i] != TW_S_COMPLETED)) {
+			if (tw_dev->srb[i]) {
+				tw_dev->srb[i]->result = (DID_RESET << 16);
+				tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
+				twa_unmap_scsi_data(tw_dev, i);
+			}
+		}
+	}
+
+	/* Reset queues and counts */
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		tw_dev->free_queue[i] = i;
+		tw_dev->state[i] = TW_S_INITIAL;
+	}
+	tw_dev->free_head = TW_Q_START;
+	tw_dev->free_tail = TW_Q_START;
+	tw_dev->posted_request_count = 0;
+	tw_dev->pending_request_count = 0;
+	tw_dev->pending_head = TW_Q_START;
+	tw_dev->pending_tail = TW_Q_START;
+	tw_dev->reset_print = 0;
+	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+	tw_dev->flags = 0;
+
+	TW_DISABLE_INTERRUPTS(tw_dev);
+
+	if (twa_reset_sequence(tw_dev, 1))
+		goto out;
+
+        TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+
+	retval = 0;
+out:
+	return retval;
+} /* End twa_reset_device_extension() */
+
+/* This function will reset a controller */
+static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
+{
+	int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset;
+
+	while (tries < TW_MAX_RESET_TRIES) {
+		if (do_soft_reset)
+			TW_SOFT_RESET(tw_dev);
+
+		/* Make sure controller is in a good state */
+		if (twa_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset == 1 ? TW_STATUS_ATTENTION_INTERRUPT : 0), 30)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Microcontroller not ready during reset sequence");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		}
+
+		/* Empty response queue */
+		if (twa_empty_response_queue(tw_dev)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Response queue empty failed during reset sequence");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		}
+
+		flashed = 0;
+
+		/* Check for compatibility/flash */
+		if (twa_check_srl(tw_dev, &flashed)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Compatibility check failed during reset sequence");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		} else {
+			if (flashed) {
+				tries++;
+				continue;
+			}
+		}
+
+		/* Drain the AEN queue */
+		if (twa_aen_drain_queue(tw_dev, soft_reset)) {
+			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x22, "AEN drain failed during reset sequence");
+			do_soft_reset = 1;
+			tries++;
+			continue;
+		}
+
+		/* If we got here, controller is in a good state */
+		retval = 0;
+		goto out;
+	}
+out:
+	return retval;
+} /* End twa_reset_sequence() */
+
+/* This funciton returns unit geometry in cylinders/heads/sectors */
+static int twa_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
+{
+	int heads, sectors, cylinders;
+	TW_Device_Extension *tw_dev;
+
+	tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
+
+	if (capacity >= 0x200000) {
+		heads = 255;
+		sectors = 63;
+		cylinders = sector_div(capacity, heads * sectors);
+	} else {
+		heads = 64;
+		sectors = 32;
+		cylinders = sector_div(capacity, heads * sectors);
+	}
+
+	geom[0] = heads;
+	geom[1] = sectors;
+	geom[2] = cylinders;
+
+	return 0;
+} /* End twa_scsi_biosparam() */
+
+/* This is the new scsi eh abort function */
+static int twa_scsi_eh_abort(struct scsi_cmnd *SCpnt)
+{
+	int i;
+	TW_Device_Extension *tw_dev = NULL;
+	int retval = FAILED;
+
+	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+	spin_unlock_irq(tw_dev->host->host_lock);
+
+	tw_dev->num_aborts++;
+
+	/* If we find any IO's in process, we have to reset the card */
+	for (i = 0; i < TW_Q_LENGTH; i++) {
+		if ((tw_dev->state[i] != TW_S_FINISHED) && (tw_dev->state[i] != TW_S_INITIAL)) {
+			printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n",
+			       tw_dev->host->host_no, TW_DRIVER, 0x2c,
+			       SCpnt->device->id, SCpnt->cmnd[0]);
+			if (twa_reset_device_extension(tw_dev)) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2a, "Controller reset failed during scsi abort");
+				goto out;
+			}
+			break;
+		}
+	}
+	retval = SUCCESS;
+out:
+	spin_lock_irq(tw_dev->host->host_lock);
+	return retval;
+} /* End twa_scsi_eh_abort() */
+
+/* This is the new scsi eh reset function */
+static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
+{
+	TW_Device_Extension *tw_dev = NULL;
+	int retval = FAILED;
+
+	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+	spin_unlock_irq(tw_dev->host->host_lock);
+
+	tw_dev->num_resets++;
+
+	printk(KERN_WARNING "3w-9xxx: scsi%d: SCSI host reset started.\n", tw_dev->host->host_no);
+
+	/* Now reset the card and some of the device extension data */
+	if (twa_reset_device_extension(tw_dev)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
+		goto out;
+	}
+	printk(KERN_WARNING "3w-9xxx: scsi%d: SCSI host reset succeeded.\n", tw_dev->host->host_no);
+	retval = SUCCESS;
+out:
+	spin_lock_irq(tw_dev->host->host_lock);
+	return retval;
+} /* End twa_scsi_eh_reset() */
+
+/* This is the main scsi queue function to handle scsi opcodes */
+static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+{
+	int request_id, retval;
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+
+	/* Save done function into scsi_cmnd struct */
+	SCpnt->scsi_done = done;
+		
+	/* Get a free request id */
+	twa_get_request_id(tw_dev, &request_id);
+
+	/* Save the scsi command for use by the ISR */
+	tw_dev->srb[request_id] = SCpnt;
+
+	/* Initialize phase to zero */
+	SCpnt->SCp.phase = TW_PHASE_INITIAL;
+
+	retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
+	switch (retval) {
+	case SCSI_MLQUEUE_HOST_BUSY:
+		twa_free_request_id(tw_dev, request_id);
+		break;
+	case 1:
+		tw_dev->state[request_id] = TW_S_COMPLETED;
+		twa_free_request_id(tw_dev, request_id);
+		SCpnt->result = (DID_ERROR << 16);
+		done(SCpnt);
+	}
+
+	return retval;
+} /* End twa_scsi_queue() */
+
+/* This function hands scsi cdb's to the firmware */
+static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Apache *sglistarg)
+{
+	TW_Command_Full *full_command_packet;
+	TW_Command_Apache *command_packet;
+	u32 num_sectors = 0x0;
+	int i, sg_count;
+	struct scsi_cmnd *srb = NULL;
+	struct scatterlist *sglist = NULL;
+	u32 buffaddr = 0x0;
+	int retval = 1;
+
+	if (tw_dev->srb[request_id]) {
+		if (tw_dev->srb[request_id]->request_buffer) {
+			sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
+		}
+		srb = tw_dev->srb[request_id];
+	}
+
+	/* Initialize command packet */
+	full_command_packet = tw_dev->command_packet_virt[request_id];
+	full_command_packet->header.header_desc.size_header = 128;
+	full_command_packet->header.status_block.error = 0;
+	full_command_packet->header.status_block.severity__reserved = 0;
+
+	command_packet = &full_command_packet->command.newcommand;
+	command_packet->status = 0;
+	command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
+
+	/* We forced 16 byte cdb use earlier */
+	if (!cdb)
+		memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
+	else
+		memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
+
+	if (srb)
+		command_packet->unit = srb->device->id;
+	else
+		command_packet->unit = 0;
+
+	command_packet->request_id = request_id;
+	command_packet->sgl_offset = 16;
+
+	if (!sglistarg) {
+		/* Map sglist from scsi layer to cmd packet */
+		if (tw_dev->srb[request_id]->use_sg == 0) {
+			if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) {
+				command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
+				command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
+			} else {
+				buffaddr = twa_map_scsi_single_data(tw_dev, request_id);
+				if (buffaddr == 0)
+					goto out;
+
+				command_packet->sg_list[0].address = buffaddr;
+				command_packet->sg_list[0].length = tw_dev->srb[request_id]->request_bufflen;
+			}
+			command_packet->sgl_entries = 1;
+
+			if (command_packet->sg_list[0].address & TW_ALIGNMENT_9000_SGL) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi");
+				goto out;
+			}
+		}
+
+		if (tw_dev->srb[request_id]->use_sg > 0) {
+			sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
+			if (sg_count == 0)
+				goto out;
+
+			for (i = 0; i < sg_count; i++) {
+				command_packet->sg_list[i].address = sg_dma_address(&sglist[i]);
+				command_packet->sg_list[i].length = sg_dma_len(&sglist[i]);
+				if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
+					TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
+					goto out;
+				}
+			}
+			command_packet->sgl_entries = tw_dev->srb[request_id]->use_sg;
+		}
+	} else {
+		/* Internal cdb post */
+		for (i = 0; i < use_sg; i++) {
+			command_packet->sg_list[i].address = sglistarg[i].address;
+			command_packet->sg_list[i].length = sglistarg[i].length;
+			if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
+				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post");
+				goto out;
+			}
+		}
+		command_packet->sgl_entries = use_sg;
+	}
+
+	if (srb) {
+		if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6)
+			num_sectors = (u32)srb->cmnd[4];
+
+		if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10)
+			num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
+	}
+
+	/* Update sector statistic */
+	tw_dev->sector_count = num_sectors;
+	if (tw_dev->sector_count > tw_dev->max_sector_count)
+		tw_dev->max_sector_count = tw_dev->sector_count;
+
+	/* Update SG statistics */
+	if (srb) {
+		tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
+		if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
+			tw_dev->max_sgl_entries = tw_dev->sgl_entries;
+	}
+
+	/* Now post the command to the board */
+	if (srb) {
+		retval = twa_post_command_packet(tw_dev, request_id, 0);
+	} else {
+		twa_post_command_packet(tw_dev, request_id, 1);
+		retval = 0;
+	}
+out:
+	return retval;
+} /* End twa_scsiop_execute_scsi() */
+
+/* This function completes an execute scsi operation */
+static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+	/* Copy the response if too small */
+	if ((tw_dev->srb[request_id]->request_buffer) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
+		memcpy(tw_dev->srb[request_id]->request_buffer,
+		       tw_dev->generic_buffer_virt[request_id],
+		       tw_dev->srb[request_id]->request_bufflen);
+	}
+} /* End twa_scsiop_execute_scsi_complete() */
+
+/* This function tells the controller to shut down */
+static void __twa_shutdown(TW_Device_Extension *tw_dev)
+{
+	/* Disable interrupts */
+	TW_DISABLE_INTERRUPTS(tw_dev);
+
+	printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no);
+
+	/* Tell the card we are shutting down */
+	if (twa_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x31, "Connection shutdown failed");
+	} else {
+		printk(KERN_WARNING "3w-9xxx: Shutdown complete.\n");
+	}
+
+	/* Clear all interrupts just before exit */
+	TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+} /* End __twa_shutdown() */
+
+/* Wrapper for __twa_shutdown */
+static void twa_shutdown(struct device *dev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	__twa_shutdown(tw_dev);
+} /* End twa_shutdown() */
+
+/* This function will look up a string */
+static char *twa_string_lookup(twa_message_type *table, unsigned int code)
+{
+	int index;
+
+	for (index = 0; ((code != table[index].code) &&
+		      (table[index].text != (char *)0)); index++);
+	return(table[index].text);
+} /* End twa_string_lookup() */
+
+/* This function will perform a pci-dma unmap */
+static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
+{
+	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+	struct pci_dev *pdev = tw_dev->tw_pci_dev;
+
+	switch(cmd->SCp.phase) {
+	case TW_PHASE_SINGLE:
+		pci_unmap_single(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, DMA_BIDIRECTIONAL);
+		break;
+	case TW_PHASE_SGLIST:
+		pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
+		break;
+	}
+} /* End twa_unmap_scsi_data() */
+
+/* scsi_host_template initializer */
+static struct scsi_host_template driver_template = {
+	.module			= THIS_MODULE,
+	.name			= "3ware 9000 Storage Controller",
+	.queuecommand		= twa_scsi_queue,
+	.eh_abort_handler	= twa_scsi_eh_abort,
+	.eh_host_reset_handler	= twa_scsi_eh_reset,
+	.bios_param		= twa_scsi_biosparam,
+	.can_queue		= TW_Q_LENGTH-2,
+	.this_id		= -1,
+	.sg_tablesize		= TW_APACHE_MAX_SGL_LENGTH,
+	.max_sectors		= TW_MAX_SECTORS,
+	.cmd_per_lun		= TW_MAX_CMDS_PER_LUN,
+	.use_clustering		= ENABLE_CLUSTERING,
+	.shost_attrs		= twa_host_attrs,
+	.sdev_attrs		= twa_dev_attrs,
+	.emulated		= 1
+};
+
+/* This function will probe and initialize a card */
+static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
+{
+	struct Scsi_Host *host = NULL;
+	TW_Device_Extension *tw_dev;
+	u32 mem_addr;
+	int retval = -ENODEV;
+
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device");
+		goto out_disable_device;
+	}
+
+	pci_set_master(pdev);
+
+	retval = pci_set_dma_mask(pdev, TW_DMA_MASK);
+	if (retval) {
+		TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
+		goto out_disable_device;
+	}
+
+	host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
+	if (!host) {
+		TW_PRINTK(host, TW_DRIVER, 0x24, "Failed to allocate memory for device extension");
+		retval = -ENOMEM;
+		goto out_disable_device;
+	}
+	tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	memset(tw_dev, 0, sizeof(TW_Device_Extension));
+
+	/* Save values to device extension */
+	tw_dev->host = host;
+	tw_dev->tw_pci_dev = pdev;
+
+	if (twa_initialize_device_extension(tw_dev)) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x25, "Failed to initialize device extension");
+		goto out_free_device_extension;
+	}
+
+	/* Request IO regions */
+	retval = pci_request_regions(pdev, "3w-9xxx");
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Failed to get mem region");
+		goto out_free_device_extension;
+	}
+
+	mem_addr = pci_resource_start(pdev, 1);
+
+	/* Save base address */
+	tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE);
+	if (!tw_dev->base_addr) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap");
+		goto out_release_mem_region;
+	}
+
+	/* Disable interrupts on the card */
+	TW_DISABLE_INTERRUPTS(tw_dev);
+
+	/* Initialize the card */
+	if (twa_reset_sequence(tw_dev, 0))
+		goto out_release_mem_region;
+
+	/* Set host specific parameters */
+	host->max_id = TW_MAX_UNITS;
+	host->max_cmd_len = TW_MAX_CDB_LEN;
+
+	/* Luns and channels aren't supported by adapter */
+	host->max_lun = 0;
+	host->max_channel = 0;
+
+	/* Register the card with the kernel SCSI layer */
+	retval = scsi_add_host(host, &pdev->dev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed");
+		goto out_release_mem_region;
+	}
+
+	pci_set_drvdata(pdev, host);
+
+	printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%x, IRQ: %d.\n",
+	       host->host_no, mem_addr, pdev->irq);
+	printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n",
+	       host->host_no,
+	       (char *)twa_get_param(tw_dev, 0, TW_VERSION_TABLE,
+				     TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
+	       (char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE,
+				     TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
+	       *(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE,
+				     TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH));
+
+	/* Now setup the interrupt handler */
+	retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev);
+	if (retval) {
+		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x30, "Error requesting IRQ");
+		goto out_remove_host;
+	}
+
+	twa_device_extension_list[twa_device_extension_count] = tw_dev;
+	twa_device_extension_count++;
+
+	/* Re-enable interrupts on the card */
+	TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+
+	/* Finally, scan the host */
+	scsi_scan_host(host);
+
+	if (twa_major == -1) {
+		if ((twa_major = register_chrdev (0, "twa", &twa_fops)) < 0)
+			TW_PRINTK(host, TW_DRIVER, 0x29, "Failed to register character device");
+	}
+	return 0;
+
+out_remove_host:
+	scsi_remove_host(host);
+out_release_mem_region:
+	pci_release_regions(pdev);
+out_free_device_extension:
+	twa_free_device_extension(tw_dev);
+	scsi_host_put(host);
+out_disable_device:
+	pci_disable_device(pdev);
+
+	return retval;
+} /* End twa_probe() */
+
+/* This function is called to remove a device */
+static void twa_remove(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+	scsi_remove_host(tw_dev->host);
+
+	__twa_shutdown(tw_dev);
+
+	/* Free up the IRQ */
+	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
+	/* Free up the mem region */
+	pci_release_regions(pdev);
+
+	/* Free up device extension resources */
+	twa_free_device_extension(tw_dev);
+
+	/* Unregister character device */
+	if (twa_major >= 0) {
+		unregister_chrdev(twa_major, "twa");
+		twa_major = -1;
+	}
+
+	scsi_host_put(tw_dev->host);
+	pci_disable_device(pdev);
+	twa_device_extension_count--;
+} /* End twa_remove() */
+
+/* PCI Devices supported by this driver */
+static struct pci_device_id twa_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
+
+/* pci_driver initializer */
+static struct pci_driver twa_driver = {
+	.name		= "3w-9xxx",
+	.id_table	= twa_pci_tbl,
+	.probe		= twa_probe,
+	.remove		= twa_remove,
+	.driver		= {
+		.shutdown = twa_shutdown
+	}
+};
+
+/* This function is called on driver initialization */
+static int __init twa_init(void)
+{
+	printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", twa_driver_version);
+
+	return pci_module_init(&twa_driver);
+} /* End twa_init() */
+
+/* This function is called on driver exit */
+static void __exit twa_exit(void)
+{
+	pci_unregister_driver(&twa_driver);
+} /* End twa_exit() */
+
+module_init(twa_init);
+module_exit(twa_exit);
+
diff -puN /dev/null drivers/scsi/3w-9xxx.h
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/drivers/scsi/3w-9xxx.h	2004-06-14 00:10:34.732028232 -0700
@@ -0,0 +1,704 @@
+/*
+   3w-9xxx.h -- 3ware 9000 Storage Controller device driver for Linux.
+
+   Written By: Adam Radford <linuxraid@amcc.com>
+
+   Copyright (C) 2004 Applied Micro Circuits Corporation.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   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.
+
+   NO WARRANTY
+   THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+   LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+   solely responsible for determining the appropriateness of using and
+   distributing the Program and assumes all risks associated with its
+   exercise of rights under this Agreement, including but not limited to
+   the risks and costs of program errors, damage to or loss of data,
+   programs or equipment, and unavailability or interruption of operations.
+
+   DISCLAIMER OF LIABILITY
+   NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+   USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+   HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+   Bugs/Comments/Suggestions should be mailed to:
+   linuxraid@amcc.com
+
+   For more information, goto:
+   http://www.amcc.com
+*/
+
+#ifndef _3W_9XXX_H
+#define _3W_9XXX_H
+
+/* AEN string type */
+typedef struct TAG_twa_message_type {
+  unsigned int   code;
+  char*          text;
+} twa_message_type;
+
+/* AEN strings */
+static twa_message_type twa_aen_table[] = {
+	{0x0000, "AEN queue empty"},
+	{0x0001, "Controller reset occurred"},
+	{0x0002, "Degraded unit detected"},
+	{0x0003, "Controller error occured"},
+	{0x0004, "Background rebuild failed"},
+	{0x0005, "Background rebuild done"},
+	{0x0006, "Incomplete unit detected"},
+	{0x0007, "Background initialize done"},
+	{0x0008, "Unclean shutdown detected"},
+	{0x0009, "Drive timeout detected"},
+	{0x000A, "Drive error detected"},
+	{0x000B, "Rebuild started"},
+	{0x000C, "Background initialize started"},
+	{0x000D, "Entire logical unit was deleted"},
+	{0x000E, "Background initialize failed"},
+	{0x000F, "SMART attribute exceeded threshold"},
+	{0x0010, "Power supply reported AC under range"},
+	{0x0011, "Power supply reported DC out of range"},
+	{0x0012, "Power supply reported a malfunction"},
+	{0x0013, "Power supply predicted malfunction"},
+	{0x0014, "Battery charge is below threshold"},
+	{0x0015, "Fan speed is below threshold"},
+	{0x0016, "Temperature sensor is above threshold"},
+	{0x0017, "Power supply was removed"},
+	{0x0018, "Power supply was inserted"},
+	{0x0019, "Drive was removed from a bay"},
+	{0x001A, "Drive was inserted into a bay"},
+	{0x001B, "Drive bay cover door was opened"},
+	{0x001C, "Drive bay cover door was closed"},
+	{0x001D, "Product case was opened"},
+	{0x0020, "Prepare for shutdown (power-off)"},
+	{0x0021, "Downgrade UDMA mode to lower speed"},
+	{0x0022, "Upgrade UDMA mode to higher speed"},
+	{0x0023, "Sector repair completed"},
+	{0x0024, "Sbuf memory test failed"},
+	{0x0025, "Error flushing cached write data to array"},
+	{0x0026, "Drive reported data ECC error"},
+	{0x0027, "DCB has checksum error"},
+	{0x0028, "DCB version is unsupported"},
+	{0x0029, "Background verify started"},
+	{0x002A, "Background verify failed"},
+	{0x002B, "Background verify done"},
+	{0x002C, "Bad sector overwritten during rebuild"},
+	{0x002D, "Background rebuild error on source drive"},
+	{0x002E, "Replace failed because replacement drive too small"},
+	{0x002F, "Verify failed because array was never initialized"},
+	{0x0030, "Unsupported ATA drive"},
+	{0x0031, "Synchronize host/controller time"},
+	{0x0032, "Spare capacity is inadequate for some units"},
+	{0x0033, "Background migration started"},
+	{0x0034, "Background migration failed"},
+	{0x0035, "Background migration done"},
+	{0x0036, "Verify detected and fixed data/parity mismatch"},
+	{0x0037, "SO-DIMM incompatible"},
+	{0x0038, "SO-DIMM not detected"},
+	{0x0039, "Corrected Sbuf ECC error"},
+	{0x003A, "Drive power on reset detected"},
+	{0x003B, "Background rebuild paused"},
+	{0x003C, "Background initialize paused"},
+	{0x003D, "Background verify paused"},
+	{0x003E, "Background migration paused"},
+	{0x003F, "Corrupt flash file system detected"},
+	{0x0040, "Flash file system repaired"},
+	{0x0041, "Unit number assignments were lost"},
+	{0x0042, "Error during read of primary DCB"},
+	{0x0043, "Latent error found in backup DCB"},
+	{0x00FC, "Recovered/finished array membership update"},
+	{0x00FD, "Handler lockup"},
+	{0x00FE, "Retrying PCI transfer"},
+	{0x00FF, "AEN queue is full"},
+	{0xFFFFFFFF, (char*) 0}
+};
+
+/* AEN severity table */
+static char *twa_aen_severity_table[] =
+{
+	"None", "ERROR", "WARNING", "INFO", "DEBUG", (char*) 0
+};
+
+/* Error strings */
+static twa_message_type twa_error_table[] = {
+	{0x0100, "SGL entry contains zero data"},
+	{0x0101, "Invalid command opcode"},
+	{0x0102, "SGL entry has unaligned address"},
+	{0x0103, "SGL size does not match command"},
+	{0x0104, "SGL entry has illegal length"},
+	{0x0105, "Command packet is not aligned"},
+	{0x0106, "Invalid request ID"},
+	{0x0107, "Duplicate request ID"},
+	{0x0108, "ID not locked"},
+	{0x0109, "LBA out of range"},
+	{0x010A, "Logical unit not supported"},
+	{0x010B, "Parameter table does not exist"},
+	{0x010C, "Parameter index does not exist"},
+	{0x010D, "Invalid field in CDB"},
+	{0x010E, "Specified port has invalid drive"},
+	{0x010F, "Parameter item size mismatch"},
+	{0x0110, "Failed memory allocation"},
+	{0x0111, "Memory request too large"},
+	{0x0112, "Out of memory segments"},
+	{0x0113, "Invalid address to deallocate"},
+	{0x0114, "Out of memory"},
+	{0x0115, "Out of heap"},
+	{0x0120, "Double degrade"},
+	{0x0121, "Drive not degraded"},
+	{0x0122, "Reconstruct error"},
+	{0x0123, "Replace not accepted"},
+	{0x0124, "Replace drive capacity too small"},
+	{0x0125, "Sector count not allowed"},
+	{0x0126, "No spares left"},
+	{0x0127, "Reconstruct error"},
+	{0x0128, "Unit is offline"},
+	{0x0129, "Cannot update status to DCB"},
+	{0x0130, "Invalid stripe handle"},
+	{0x0131, "Handle that was not locked"},
+	{0x0132, "Handle that was not empty"},
+	{0x0133, "Handle has different owner"},
+	{0x0140, "IPR has parent"},
+	{0x0150, "Illegal Pbuf address alignment"},
+	{0x0151, "Illegal Pbuf transfer length"},
+	{0x0152, "Illegal Sbuf address alignment"},
+	{0x0153, "Illegal Sbuf transfer length"},
+	{0x0160, "Command packet too large"},
+	{0x0161, "SGL exceeds maximum length"},
+	{0x0162, "SGL has too many entries"},
+	{0x0170, "Insufficient resources for rebuilder"},
+	{0x0171, "Verify error (data != parity)"},
+	{0x0180, "Requested segment not in directory of this DCB"},
+	{0x0181, "DCB segment has unsupported version"},
+	{0x0182, "DCB segment has checksum error"},
+	{0x0183, "DCB support (settings) segment invalid"},
+	{0x0184, "DCB UDB (unit descriptor block) segment invalid"},
+	{0x0185, "DCB GUID (globally unique identifier) segment invalid"},
+	{0x01A0, "Could not clear Sbuf"},
+	{0x01C0, "Flash identify failed"},
+	{0x01C1, "Flash out of bounds"},
+	{0x01C2, "Flash verify error"},
+	{0x01C3, "Flash file object not found"},
+	{0x01C4, "Flash file already present"},
+	{0x01C5, "Flash file system full"},
+	{0x01C6, "Flash file not present"},
+	{0x01C7, "Flash file size error"},
+	{0x01C8, "Bad flash file checksum"},
+	{0x01CA, "Corrupt flash file system detected"},
+	{0x01D0, "Invalid field in parameter list"},
+	{0x01D1, "Parameter list length error"},
+	{0x01D2, "Parameter item is not changeable"},
+	{0x01D3, "Parameter item is not saveable"},
+	{0x0200, "UDMA CRC error"},
+	{0x0201, "Internal CRC error"},
+	{0x0202, "Data ECC error"},
+	{0x0203, "ADP level 1 error"},
+	{0x0204, "Port timeout"},
+	{0x0205, "Drive power on reset"},
+	{0x0206, "ADP level 2 error"},
+	{0x0207, "Soft reset failed"},
+	{0x0208, "Drive not ready"},
+	{0x0209, "Unclassified port error"},
+	{0x020A, "Drive aborted command"},
+	{0x0210, "Internal CRC error"},
+	{0x0211, "PCI abort error"},
+	{0x0212, "PCI parity error"},
+	{0x0213, "Port handler error"},
+	{0x0214, "Token interrupt count error"},
+	{0x0215, "Timeout waiting for PCI transfer"},
+	{0x0216, "Corrected buffer ECC"},
+	{0x0217, "Uncorrected buffer ECC"},
+	{0x0230, "Unsupported command during flash recovery"},
+	{0x0231, "Next image buffer expected"},
+	{0x0232, "Binary image architecture incompatible"},
+	{0x0233, "Binary image has no signature"},
+	{0x0234, "Binary image has bad checksum"},
+	{0x0235, "Image downloaded overflowed buffer"},
+	{0x0240, "I2C device not found"},
+	{0x0241, "I2C transaction aborted"},
+	{0x0242, "SO-DIMM parameter(s) incompatible using defaults"},
+	{0x0243, "SO-DIMM unsupported"},
+	{0x0248, "SPI transfer status error"},
+	{0x0249, "SPI transfer timeout error"},
+	{0x0250, "Invalid unit descriptor size in CreateUnit"},
+	{0x0251, "Unit descriptor size exceeds data buffer in CreateUnit"},
+	{0x0252, "Invalid value in CreateUnit descriptor"},
+	{0x0253, "Inadequate disk space to support descriptor in CreateUnit"},
+	{0x0254, "Unable to create data channel for this unit descriptor"},
+	{0x0255, "CreateUnit descriptor specifies a drive already in use"},
+	{0x0256, "Unable to write configuration to all disks during CreateUnit"},
+	{0x0257, "CreateUnit does not support this descriptor version"},
+	{0x0258, "Invalid subunit for RAID 0 or 5 in CreateUnit"},
+	{0x0259, "Too many descriptors in CreateUnit"},
+	{0x025A, "Invalid configuration specified in CreateUnit descriptor"},
+	{0x025B, "Invalid LBA offset specified in CreateUnit descriptor"},
+	{0x025C, "Invalid stripelet size specified in CreateUnit descriptor"},
+	{0x0260, "SMART attribute exceeded threshold"},
+	{0xFFFFFFFF, (char*) 0}
+};
+
+/* Control register bit definitions */
+#define TW_CONTROL_CLEAR_HOST_INTERRUPT	       0x00080000
+#define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT   0x00040000
+#define TW_CONTROL_MASK_COMMAND_INTERRUPT      0x00020000
+#define TW_CONTROL_MASK_RESPONSE_INTERRUPT     0x00010000
+#define TW_CONTROL_UNMASK_COMMAND_INTERRUPT    0x00008000
+#define TW_CONTROL_UNMASK_RESPONSE_INTERRUPT   0x00004000
+#define TW_CONTROL_CLEAR_ERROR_STATUS	       0x00000200
+#define TW_CONTROL_ISSUE_SOFT_RESET	       0x00000100
+#define TW_CONTROL_ENABLE_INTERRUPTS	       0x00000080
+#define TW_CONTROL_DISABLE_INTERRUPTS	       0x00000040
+#define TW_CONTROL_ISSUE_HOST_INTERRUPT	       0x00000020
+#define TW_CONTROL_CLEAR_PARITY_ERROR          0x00800000
+#define TW_CONTROL_CLEAR_QUEUE_ERROR           0x00400000
+#define TW_CONTROL_CLEAR_PCI_ABORT             0x00100000
+#define TW_CONTROL_CLEAR_SBUF_WRITE_ERROR      0x00000008
+
+/* Status register bit definitions */
+#define TW_STATUS_MAJOR_VERSION_MASK	       0xF0000000
+#define TW_STATUS_MINOR_VERSION_MASK	       0x0F000000
+#define TW_STATUS_PCI_PARITY_ERROR	       0x00800000
+#define TW_STATUS_QUEUE_ERROR		       0x00400000
+#define TW_STATUS_MICROCONTROLLER_ERROR	       0x00200000
+#define TW_STATUS_PCI_ABORT		       0x00100000
+#define TW_STATUS_HOST_INTERRUPT	       0x00080000
+#define TW_STATUS_ATTENTION_INTERRUPT	       0x00040000
+#define TW_STATUS_COMMAND_INTERRUPT	       0x00020000
+#define TW_STATUS_RESPONSE_INTERRUPT	       0x00010000
+#define TW_STATUS_COMMAND_QUEUE_FULL	       0x00008000
+#define TW_STATUS_RESPONSE_QUEUE_EMPTY	       0x00004000
+#define TW_STATUS_MICROCONTROLLER_READY	       0x00002000
+#define TW_STATUS_COMMAND_QUEUE_EMPTY	       0x00001000
+#define TW_STATUS_EXPECTED_BITS		       0x00002000
+#define TW_STATUS_UNEXPECTED_BITS	       0x00F00008
+#define TW_STATUS_SBUF_WRITE_ERROR             0x00000008
+#define TW_STATUS_VALID_INTERRUPT              0x00DF0008
+
+/* RESPONSE QUEUE BIT DEFINITIONS */
+#define TW_RESPONSE_ID_MASK		       0x00000FF0
+
+/* PCI related defines */
+#define TW_DEVICE_NAME			       "3w-9xxx"
+#define TW_NUMDEVICES 1
+#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
+#define TW_PCI_CLEAR_PCI_ABORT     0x2000
+
+/* Command packet opcodes used by the driver */
+#define TW_OP_INIT_CONNECTION 0x1
+#define TW_OP_GET_PARAM	      0x12
+#define TW_OP_SET_PARAM	      0x13
+#define TW_OP_EXECUTE_SCSI    0x10
+#define TW_OP_DOWNLOAD_FIRMWARE 0x16
+#define TW_OP_RESET             0x1C
+
+/* Asynchronous Event Notification (AEN) codes used by the driver */
+#define TW_AEN_QUEUE_EMPTY       0x0000
+#define TW_AEN_SOFT_RESET        0x0001
+#define TW_AEN_SYNC_TIME_WITH_HOST 0x031
+#define TW_AEN_SEVERITY_ERROR    0x1
+#define TW_AEN_SEVERITY_DEBUG    0x4
+#define TW_AEN_NOT_RETRIEVED 0x1
+#define TW_AEN_RETRIEVED 0x2
+
+/* Command state defines */
+#define TW_S_INITIAL   0x1  /* Initial state */
+#define TW_S_STARTED   0x2  /* Id in use */
+#define TW_S_POSTED    0x4  /* Posted to the controller */
+#define TW_S_PENDING   0x8  /* Waiting to be posted in isr */
+#define TW_S_COMPLETED 0x10 /* Completed by isr */
+#define TW_S_FINISHED  0x20 /* I/O completely done */
+
+/* Compatibility defines */
+#define TW_9000_ARCH_ID 0x5
+#define TW_CURRENT_FW_SRL 24
+#define TW_CURRENT_FW_BUILD 5
+#define TW_CURRENT_FW_BRANCH 1
+
+/* Phase defines */
+#define TW_PHASE_INITIAL 0
+#define TW_PHASE_SINGLE  1
+#define TW_PHASE_SGLIST  2
+
+/* Misc defines */
+#define TW_SECTOR_SIZE                        512
+#define TW_ALIGNMENT_9000                     4  /* 4 bytes */
+#define TW_ALIGNMENT_9000_SGL                 0x3
+#define TW_MAX_UNITS			      16
+#define TW_INIT_MESSAGE_CREDITS		      0x100
+#define TW_INIT_COMMAND_PACKET_SIZE	      0x3
+#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED  0x6
+#define TW_EXTENDED_INIT_CONNECT	      0x2
+#define TW_BUNDLED_FW_SAFE_TO_FLASH	      0x4
+#define TW_CTLR_FW_RECOMMENDS_FLASH	      0x8
+#define TW_CTLR_FW_COMPATIBLE		      0x2
+#define TW_BASE_FW_SRL			      0x17
+#define TW_BASE_FW_BRANCH		      0
+#define TW_BASE_FW_BUILD		      1
+#if BITS_PER_LONG > 32
+#define TW_APACHE_MAX_SGL_LENGTH 72
+#define TW_ESCALADE_MAX_SGL_LENGTH 41
+#define TW_APACHE_CMD_PKT_SIZE 5
+#else
+#define TW_APACHE_MAX_SGL_LENGTH 109
+#define TW_ESCALADE_MAX_SGL_LENGTH 62
+#define TW_APACHE_CMD_PKT_SIZE 4
+#endif
+#define TW_ATA_PASS_SGL_MAX                   60
+#define TW_Q_LENGTH			      256
+#define TW_Q_START			      0
+#define TW_MAX_SLOT			      32
+#define TW_MAX_RESET_TRIES		      2
+#define TW_MAX_CMDS_PER_LUN		      254
+#define TW_MAX_RESPONSE_DRAIN		      256
+#define TW_MAX_AEN_DRAIN		      40
+#define TW_IN_IOCTL                           2
+#define TW_IN_CHRDEV_IOCTL                    3
+#define TW_IN_ATTENTION_LOOP		      4
+#define TW_MAX_SECTORS                        256
+#define TW_AEN_WAIT_TIME                      1000
+#define TW_IOCTL_WAIT_TIME                    (1 * HZ) /* 1 second */
+#define TW_MAX_CDB_LEN                        16
+#define TW_ISR_DONT_COMPLETE                  2
+#define TW_ISR_DONT_RESULT                    3
+#define TW_IOCTL_CHRDEV_TIMEOUT               60 /* 60 seconds */
+#define TW_IOCTL_CHRDEV_FREE                  -1
+#define TW_COMMAND_OFFSET                     128 /* 128 bytes */
+#define TW_VERSION_TABLE                      0x0402
+#define TW_TIMEKEEP_TABLE		      0x040A
+#define TW_INFORMATION_TABLE		      0x0403
+#define TW_PARAM_FWVER			      3
+#define TW_PARAM_FWVER_LENGTH		      16
+#define TW_PARAM_BIOSVER		      4
+#define TW_PARAM_BIOSVER_LENGTH		      16
+#define TW_PARAM_PORTCOUNT		      3
+#define TW_PARAM_PORTCOUNT_LENGTH	      1
+#define TW_MIN_SGL_LENGTH                     0x200 /* 512 bytes */
+#define TW_MAX_SENSE_LENGTH                   256
+#define TW_EVENT_SOURCE_AEN                   0x1000
+#define TW_EVENT_SOURCE_COMMAND               0x1001
+#define TW_EVENT_SOURCE_PCHIP                 0x1002
+#define TW_EVENT_SOURCE_DRIVER                0x1003
+#define TW_IOCTL_GET_COMPATIBILITY_INFO	      0x101
+#define TW_IOCTL_GET_LAST_EVENT               0x102
+#define TW_IOCTL_GET_FIRST_EVENT              0x103
+#define TW_IOCTL_GET_NEXT_EVENT               0x104
+#define TW_IOCTL_GET_PREVIOUS_EVENT           0x105
+#define TW_IOCTL_GET_LOCK                     0x106
+#define TW_IOCTL_RELEASE_LOCK                 0x107
+#define TW_IOCTL_FIRMWARE_PASS_THROUGH        0x108
+#define TW_IOCTL_ERROR_STATUS_NOT_LOCKED      0x1001 // Not locked
+#define TW_IOCTL_ERROR_STATUS_LOCKED          0x1002 // Already locked
+#define TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS  0x1003 // No more events
+#define TW_IOCTL_ERROR_STATUS_AEN_CLOBBER     0x1004 // AEN clobber occurred
+#define TW_IOCTL_ERROR_OS_EFAULT	      -EFAULT // Bad address
+#define TW_IOCTL_ERROR_OS_EINTR		      -EINTR  // Interrupted system call
+#define TW_IOCTL_ERROR_OS_EINVAL	      -EINVAL // Invalid argument
+#define TW_IOCTL_ERROR_OS_ENOMEM	      -ENOMEM // Out of memory
+#define TW_IOCTL_ERROR_OS_ERESTARTSYS	      -ERESTARTSYS // Restart system call
+#define TW_IOCTL_ERROR_OS_EIO		      -EIO // I/O error
+#define TW_IOCTL_ERROR_OS_ENOTTY	      -ENOTTY // Not a typewriter
+#define TW_IOCTL_ERROR_OS_ENODEV	      -ENODEV // No such device
+#define TW_ALLOCATION_LENGTH		      128
+#define TW_SENSE_DATA_LENGTH		      18
+#define TW_STATUS_CHECK_CONDITION	      2
+#define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED   0x10a
+#define TW_ERROR_UNIT_OFFLINE                 0x128
+#define TW_MESSAGE_SOURCE_CONTROLLER_ERROR    3
+#define TW_MESSAGE_SOURCE_CONTROLLER_EVENT    4
+#define TW_MESSAGE_SOURCE_LINUX_DRIVER        6
+#define TW_DRIVER TW_MESSAGE_SOURCE_LINUX_DRIVER
+#define TW_MESSAGE_SOURCE_LINUX_OS            9
+#define TW_OS TW_MESSAGE_SOURCE_LINUX_OS
+#if BITS_PER_LONG > 32
+#define TW_COMMAND_SIZE			      5
+#define TW_DMA_MASK			      DMA_64BIT_MASK
+#else
+#define TW_COMMAND_SIZE			      4
+#define TW_DMA_MASK			      DMA_32BIT_MASK
+#endif
+#ifndef PCI_DEVICE_ID_3WARE_9000
+#define PCI_DEVICE_ID_3WARE_9000 0x1002
+#endif
+
+/* Bitmask macros to eliminate bitfields */
+
+/* opcode: 5, reserved: 3 */
+#define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f))
+#define TW_OP_OUT(x) (x & 0x1f)
+
+/* opcode: 5, sgloffset: 3 */
+#define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
+#define TW_SGL_OUT(x) ((x >> 5) & 0x7)
+
+/* severity: 3, reserved: 5 */
+#define TW_SEV_OUT(x) (x & 0x7)
+
+/* reserved_1: 4, response_id: 8, reserved_2: 20 */
+#define TW_RESID_OUT(x) ((x >> 4) & 0xff)
+
+/* Macros */
+#define TW_CONTROL_REG_ADDR(x) (x->base_addr)
+#define TW_STATUS_REG_ADDR(x) ((unsigned char *)x->base_addr + 0x4)
+#if BITS_PER_LONG > 32
+#define TW_COMMAND_QUEUE_REG_ADDR(x) ((unsigned char *)x->base_addr + 0x20)
+#else
+#define TW_COMMAND_QUEUE_REG_ADDR(x) ((unsigned char *)x->base_addr + 0x8)
+#endif
+#define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char *)x->base_addr + 0xC)
+#define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
+#define TW_CLEAR_ATTENTION_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
+#define TW_CLEAR_HOST_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
+#define TW_DISABLE_INTERRUPTS(x) (writel(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
+#define TW_ENABLE_AND_CLEAR_INTERRUPTS(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | TW_CONTROL_UNMASK_RESPONSE_INTERRUPT | TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
+#define TW_MASK_COMMAND_INTERRUPT(x) (writel(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
+#define TW_UNMASK_COMMAND_INTERRUPT(x) (writel(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
+#define TW_SOFT_RESET(x) (writel(TW_CONTROL_ISSUE_SOFT_RESET | \
+			TW_CONTROL_CLEAR_HOST_INTERRUPT | \
+			TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
+			TW_CONTROL_MASK_COMMAND_INTERRUPT | \
+			TW_CONTROL_MASK_RESPONSE_INTERRUPT | \
+			TW_CONTROL_CLEAR_ERROR_STATUS | \
+			TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
+#define TW_PRINTK(h,a,b,c) { \
+if (h) \
+printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \
+else \
+printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \
+}
+
+#pragma pack(1)
+
+/* Scatter Gather List Entry */
+typedef struct TAG_TW_SG_Entry {
+	unsigned long address;
+	u32 length;
+} TW_SG_Entry;
+
+/* Command Packet */
+typedef struct TW_Command {
+	unsigned char opcode__sgloffset;
+	unsigned char size;
+	unsigned char request_id;
+	unsigned char unit__hostid;
+	/* Second DWORD */
+	unsigned char status;
+	unsigned char flags;
+	union {
+		unsigned short block_count;
+		unsigned short parameter_count;
+	} byte6_offset;
+	union {
+		struct {
+			u32 lba;
+			TW_SG_Entry sgl[TW_ESCALADE_MAX_SGL_LENGTH];
+#if BITS_PER_LONG > 32
+			u32 padding[2];	/* pad to 512 bytes */
+#else
+			u32 padding;
+#endif
+		} io;
+		struct {
+			TW_SG_Entry sgl[TW_ESCALADE_MAX_SGL_LENGTH];
+#if BITS_PER_LONG > 32
+			u32 padding[3];
+#else
+			u32 padding[2];
+#endif
+		} param;
+	} byte8_offset;
+} TW_Command;
+
+/* Scatter gather element for 9000+ controllers */
+typedef struct TAG_TW_SG_Apache {
+	unsigned long address;
+	u32 length;
+} TW_SG_Apache;
+
+/* Command Packet for 9000+ controllers */
+typedef struct TAG_TW_Command_Apache {
+	unsigned char opcode__reserved;
+	unsigned char unit;
+	unsigned short request_id;
+	unsigned char status;
+	unsigned char sgl_offset;
+	unsigned short sgl_entries;
+	unsigned char cdb[16];
+	TW_SG_Apache sg_list[TW_APACHE_MAX_SGL_LENGTH];
+#if BITS_PER_LONG > 32
+	unsigned char padding[8];
+#endif
+} TW_Command_Apache;
+
+/* New command packet header */
+typedef struct TAG_TW_Command_Apache_Header {
+	unsigned char sense_data[TW_SENSE_DATA_LENGTH];
+	struct {
+		char reserved[4];
+		unsigned short error;
+		unsigned char padding;
+		unsigned char severity__reserved;
+	} status_block;
+	unsigned char err_specific_desc[98];
+	struct {
+		unsigned char size_header;
+		unsigned short reserved;
+		unsigned char size_sense;
+	} header_desc;
+} TW_Command_Apache_Header;
+
+/* This struct is a union of the 2 command packets */
+typedef struct TAG_TW_Command_Full {
+	TW_Command_Apache_Header header;
+	union {
+		TW_Command oldcommand;
+		TW_Command_Apache newcommand;
+	} command;
+} TW_Command_Full;
+
+/* Initconnection structure */
+typedef struct TAG_TW_Initconnect {
+	unsigned char opcode__reserved;
+	unsigned char size;
+	unsigned char request_id;
+	unsigned char res2;
+	unsigned char status;
+	unsigned char flags;
+	unsigned short message_credits;
+	u32 features;
+	unsigned short fw_srl;
+	unsigned short fw_arch_id;
+	unsigned short fw_branch;
+	unsigned short fw_build;
+	u32 result;
+} TW_Initconnect;
+
+/* Event info structure */
+typedef struct TAG_TW_Event
+{
+	unsigned int sequence_id;
+	unsigned int time_stamp_sec;
+	unsigned short aen_code;
+	unsigned char severity;
+	unsigned char retrieved;
+	unsigned char repeat_count;
+	unsigned char parameter_len;
+	unsigned char parameter_data[98];
+} TW_Event;
+
+typedef struct TAG_TW_Ioctl_Driver_Command {
+	unsigned int control_code;
+	unsigned int status;
+	unsigned int unique_id;
+	unsigned int sequence_id;
+	unsigned int os_specific;
+	unsigned int buffer_length;
+} TW_Ioctl_Driver_Command;
+
+typedef struct TAG_TW_Ioctl_Apache {
+	TW_Ioctl_Driver_Command driver_command;
+        char padding[488];
+	TW_Command_Full firmware_command;
+	char data_buffer[1];
+} TW_Ioctl_Buf_Apache;
+
+/* Lock structure for ioctl get/release lock */
+typedef struct TAG_TW_Lock {
+	unsigned long timeout_msec;
+	unsigned long time_remaining_msec;
+	unsigned long force_flag;
+} TW_Lock;
+
+/* GetParam descriptor */
+typedef struct {
+	unsigned short	table_id;
+	unsigned short	parameter_id;
+	unsigned short	parameter_size_bytes;
+	unsigned short  actual_parameter_size_bytes;
+	unsigned char	data[1];
+} TW_Param_Apache, *PTW_Param_Apache;
+
+/* Response queue */
+typedef union TAG_TW_Response_Queue {
+	u32 response_id;
+	u32 value;
+} TW_Response_Queue;
+
+typedef struct TAG_TW_Info {
+	char *buffer;
+	int length;
+	int offset;
+	int position;
+} TW_Info;
+
+/* Compatibility information structure */
+typedef struct TAG_TW_Compatibility_Info
+{
+	char driver_version[32];
+	unsigned short working_srl;
+	unsigned short working_branch;
+	unsigned short working_build;
+} TW_Compatibility_Info;
+
+typedef struct TAG_TW_Device_Extension {
+	u32                     *base_addr;
+	unsigned long	       	*generic_buffer_virt[TW_Q_LENGTH];
+	unsigned long	       	generic_buffer_phys[TW_Q_LENGTH];
+	TW_Command_Full	       	*command_packet_virt[TW_Q_LENGTH];
+	unsigned long		command_packet_phys[TW_Q_LENGTH];
+	struct pci_dev		*tw_pci_dev;
+	struct scsi_cmnd	*srb[TW_Q_LENGTH];
+	unsigned char		free_queue[TW_Q_LENGTH];
+	unsigned char		free_head;
+	unsigned char		free_tail;
+	unsigned char		pending_queue[TW_Q_LENGTH];
+	unsigned char		pending_head;
+	unsigned char		pending_tail;
+	int     		state[TW_Q_LENGTH];
+	unsigned int		posted_request_count;
+	unsigned int		max_posted_request_count;
+	unsigned int	        pending_request_count;
+	unsigned int		max_pending_request_count;
+	unsigned int		max_sgl_entries;
+	unsigned int		sgl_entries;
+	unsigned int		num_aborts;
+	unsigned int		num_resets;
+	unsigned int		sector_count;
+	unsigned int		max_sector_count;
+	unsigned int		aen_count;
+	struct Scsi_Host	*host;
+	long			flags;
+	int			reset_print;
+	TW_Event                *event_queue[TW_Q_LENGTH];
+	unsigned char           error_index;
+	unsigned char		event_queue_wrapped;
+	unsigned int            error_sequence_id;
+	int                     ioctl_sem_lock;
+	u32                     ioctl_msec;
+	int			chrdev_request_id;
+	wait_queue_head_t	ioctl_wqueue;
+	struct semaphore	ioctl_sem;
+	char			aen_clobber;
+	unsigned short		working_srl;
+	unsigned short		working_branch;
+	unsigned short		working_build;
+} TW_Device_Extension;
+
+#pragma pack()
+
+#endif /* _3W_9XXX_H */
+
diff -puN drivers/scsi/3w-xxxx.c~bk-scsi drivers/scsi/3w-xxxx.c
--- 25/drivers/scsi/3w-xxxx.c~bk-scsi	2004-06-14 00:10:34.458069880 -0700
+++ 25-akpm/drivers/scsi/3w-xxxx.c	2004-06-14 00:10:34.735027776 -0700
@@ -220,7 +220,7 @@ MODULE_LICENSE("GPL");
 #define __3W_C			/* let 3w-xxxx.h know it is use */
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "3w-xxxx.h"
 
diff -puN drivers/scsi/53c700.c~bk-scsi drivers/scsi/53c700.c
--- 25/drivers/scsi/53c700.c~bk-scsi	2004-06-14 00:10:34.460069576 -0700
+++ 25-akpm/drivers/scsi/53c700.c	2004-06-14 00:10:34.739027168 -0700
@@ -125,18 +125,21 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/blkdev.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/byteorder.h>
-#include <linux/blkdev.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "scsi.h"
-#include "hosts.h"
 
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_spi.h>
 
@@ -164,15 +167,15 @@ MODULE_LICENSE("GPL");
 #include "53c700_d.h"
 
 
-STATIC int NCR_700_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-STATIC int NCR_700_abort(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_dev_reset(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
 STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
 STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
-STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt);
-STATIC void NCR_700_slave_destroy(Scsi_Device *SDpnt);
+STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
+STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
 
 STATIC struct device_attribute *NCR_700_dev_attrs[];
 
@@ -279,7 +282,7 @@ NCR_700_offset_period_to_sxfer(struct NC
 }
 
 static inline __u8
-NCR_700_get_SXFER(Scsi_Device *SDp)
+NCR_700_get_SXFER(struct scsi_device *SDp)
 {
 	struct NCR_700_Host_Parameters *hostdata = 
 		(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
@@ -289,7 +292,7 @@ NCR_700_get_SXFER(Scsi_Device *SDp)
 }
 
 struct Scsi_Host *
-NCR_700_detect(Scsi_Host_Template *tpnt,
+NCR_700_detect(struct scsi_host_template *tpnt,
 	       struct NCR_700_Host_Parameters *hostdata)
 {
 	dma_addr_t pScript, pSlots;
@@ -561,7 +564,7 @@ free_slot(struct NCR_700_command_slot *s
    the ITL and (if tagged) the ITLQ lists in _queuecommand */
 STATIC void
 save_for_reselection(struct NCR_700_Host_Parameters *hostdata,
-		     Scsi_Cmnd *SCp, __u32 dsp)
+		     struct scsi_cmnd *SCp, __u32 dsp)
 {
 	/* Its just possible that this gets executed twice */
 	if(SCp != NULL) {
@@ -575,27 +578,25 @@ save_for_reselection(struct NCR_700_Host
 }
 
 STATIC inline void
-NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
+NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp,
 	      struct NCR_700_command_slot *slot)
 {
-	if(SCp->sc_data_direction != SCSI_DATA_NONE &&
-	   SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
-		enum dma_data_direction direction = SCp->sc_data_direction;
+	if(SCp->sc_data_direction != DMA_NONE &&
+	   SCp->sc_data_direction != DMA_BIDIRECTIONAL) {
 		if(SCp->use_sg) {
 			dma_unmap_sg(hostdata->dev, SCp->buffer,
-				     SCp->use_sg, direction);
+				     SCp->use_sg, SCp->sc_data_direction);
 		} else {
-			dma_unmap_single(hostdata->dev,
-					 slot->dma_handle,
+			dma_unmap_single(hostdata->dev, slot->dma_handle,
 					 SCp->request_bufflen,
-					 direction);
+					 SCp->sc_data_direction);
 		}
 	}
 }
 
 STATIC inline void
 NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
-	       Scsi_Cmnd *SCp, int result)
+	       struct scsi_cmnd *SCp, int result)
 {
 	hostdata->state = NCR_700_HOST_FREE;
 	hostdata->cmd = NULL;
@@ -611,7 +612,7 @@ NCR_700_scsi_done(struct NCR_700_Host_Pa
 #ifdef NCR_700_DEBUG
 			printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
 			       SCp, SCp->cmnd[7], result);
-			print_sense("53c700", SCp);
+			scsi_print_sense("53c700", SCp);
 
 #endif
 			/* restore the old result if the request sense was
@@ -780,7 +781,7 @@ NCR_700_chip_reset(struct Scsi_Host *hos
 STATIC __u32
 process_extended_message(struct Scsi_Host *host, 
 			 struct NCR_700_Host_Parameters *hostdata,
-			 Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+			 struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
 {
 	__u32 resume_offset = dsp, temp = dsp + 8;
 	__u8 pun = 0xff, lun = 0xff;
@@ -849,7 +850,7 @@ process_extended_message(struct Scsi_Hos
 		printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
 		       host->host_no, pun, lun,
 		       NCR_700_phase[(dsps & 0xf00) >> 8]);
-		print_msg(hostdata->msgin);
+		scsi_print_msg(hostdata->msgin);
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
@@ -865,7 +866,7 @@ process_extended_message(struct Scsi_Hos
 
 STATIC __u32
 process_message(struct Scsi_Host *host,	struct NCR_700_Host_Parameters *hostdata,
-		Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+		struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
 {
 	/* work out where to return to */
 	__u32 temp = dsp + 8, resume_offset = dsp;
@@ -879,7 +880,7 @@ process_message(struct Scsi_Host *host,	
 #ifdef NCR_700_DEBUG
 	printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
 	       NCR_700_phase[(dsps & 0xf00) >> 8]);
-	print_msg(hostdata->msgin);
+	scsi_print_msg(hostdata->msgin);
 	printk("\n");
 #endif
 
@@ -927,7 +928,7 @@ process_message(struct Scsi_Host *host,	
 		       host->host_no, pun, lun,
 		       NCR_700_phase[(dsps & 0xf00) >> 8]);
 
-		print_msg(hostdata->msgin);
+		scsi_print_msg(hostdata->msgin);
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
@@ -946,7 +947,7 @@ process_message(struct Scsi_Host *host,	
 }
 
 STATIC __u32
-process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
+process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
 			 struct Scsi_Host *host,
 			 struct NCR_700_Host_Parameters *hostdata)
 {
@@ -975,7 +976,7 @@ process_script_interrupt(__u32 dsps, __u
 				NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
 			} else {
 #ifdef NCR_DEBUG
-				print_command(SCp->cmnd);
+				scsi_print_command(SCp);
 				printk("  cmd %p has status %d, requesting sense\n",
 				       SCp, hostdata->status[0]);
 #endif
@@ -1004,7 +1005,7 @@ process_script_interrupt(__u32 dsps, __u
 				SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
 				SCp->cmnd[7] = hostdata->status[0];
 				SCp->use_sg = 0;
-				SCp->sc_data_direction = SCSI_DATA_READ;
+				SCp->sc_data_direction = DMA_FROM_DEVICE;
 				dma_sync_single_for_device(hostdata->dev, slot->pCmd,
 							   SCp->cmd_len, DMA_TO_DEVICE);
 				SCp->request_bufflen = sizeof(SCp->sense_buffer);
@@ -1053,7 +1054,7 @@ process_script_interrupt(__u32 dsps, __u
 		       NCR_700_phase[i],
 		       sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
 		printk(KERN_ERR "         len = %d, cmd =", SCp->cmd_len);
-		print_command(SCp->cmnd);
+		scsi_print_command(SCp);
 
 		NCR_700_internal_bus_reset(host);
 	} else if((dsps & 0xfffff000) == A_FATAL) {
@@ -1080,7 +1081,7 @@ process_script_interrupt(__u32 dsps, __u
 		__u8 lun;
 		struct NCR_700_command_slot *slot;
 		__u8 reselection_id = hostdata->reselection_id;
-		Scsi_Device *SDp;
+		struct scsi_device *SDp;
 
 		lun = hostdata->msgin[0] & 0x1f;
 
@@ -1095,7 +1096,7 @@ process_script_interrupt(__u32 dsps, __u
 			BUG();
 		}
 		if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {
-			Scsi_Cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);
+			struct scsi_cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);
 			if(unlikely(SCp == NULL)) {
 				printk(KERN_ERR "scsi%d: (%d:%d) no saved request for tag %d\n", 
 				       host->host_no, reselection_id, lun, hostdata->msgin[2]);
@@ -1107,7 +1108,7 @@ process_script_interrupt(__u32 dsps, __u
 			       host->host_no, SDp->id, SDp->lun,
 			       hostdata->msgin[2], slot, slot->tag));
 		} else {
-			Scsi_Cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
+			struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
 			if(unlikely(SCp == NULL)) {
 				printk(KERN_ERR "scsi%d: (%d:%d) no saved request for untagged cmd\n", 
 				       host->host_no, reselection_id, lun);
@@ -1234,7 +1235,7 @@ process_script_interrupt(__u32 dsps, __u
 		       host->host_no, pun, lun, NCR_700_condition[i],
 		       NCR_700_phase[j], dsp - hostdata->pScript);
 		if(SCp != NULL) {
-			print_command(SCp->cmnd);
+			scsi_print_command(SCp);
 
 			if(SCp->use_sg) {
 				for(i = 0; i < SCp->use_sg + 1; i++) {
@@ -1270,7 +1271,7 @@ process_selection(struct Scsi_Host *host
 	__u32 resume_offset = 0;
 	struct NCR_700_Host_Parameters *hostdata =
 		(struct NCR_700_Host_Parameters *)host->hostdata[0];
-	Scsi_Cmnd *SCp = hostdata->cmd;
+	struct scsi_cmnd *SCp = hostdata->cmd;
 	__u8 sbcl;
 
 	for(count = 0; count < 5; count++) {
@@ -1373,7 +1374,7 @@ NCR_700_flush_fifo(struct Scsi_Host *hos
 /* The queue lock with interrupts disabled must be held on entry to
  * this function */
 STATIC int
-NCR_700_start_command(Scsi_Cmnd *SCp)
+NCR_700_start_command(struct scsi_cmnd *SCp)
 {
 	struct NCR_700_command_slot *slot =
 		(struct NCR_700_command_slot *)SCp->host_scribble;
@@ -1481,7 +1482,7 @@ NCR_700_intr(int irq, void *dev_id, stru
 		__u32 dsps;
 		__u8 sstat0 = 0, dstat = 0;
 		__u32 dsp;
-		Scsi_Cmnd *SCp = hostdata->cmd;
+		struct scsi_cmnd *SCp = hostdata->cmd;
 		enum NCR_700_Host_State state;
 
 		handled = 1;
@@ -1514,7 +1515,7 @@ NCR_700_intr(int irq, void *dev_id, stru
 		}
 
 		if(sstat0 & SCSI_RESET_DETECTED) {
-			Scsi_Device *SDp;
+			struct scsi_device *SDp;
 			int i;
 
 			hostdata->state = NCR_700_HOST_BUSY;
@@ -1530,7 +1531,7 @@ NCR_700_intr(int irq, void *dev_id, stru
 			
 			/* clear all the slots and their pending commands */
 			for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
-				Scsi_Cmnd *SCp;
+				struct scsi_cmnd *SCp;
 				struct NCR_700_command_slot *slot =
 					&hostdata->slots[i];
 
@@ -1590,7 +1591,7 @@ NCR_700_intr(int irq, void *dev_id, stru
 				printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n",
 				       host->host_no, pun, lun,
 				       SGcount, data_transfer);
-				print_command(SCp->cmnd);
+				scsi_print_command(SCp);
 				if(residual) {
 					printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x, residual %d\n",
 				       host->host_no, pun, lun,
@@ -1731,7 +1732,7 @@ NCR_700_intr(int irq, void *dev_id, stru
 }
 
 STATIC int
-NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
+NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 {
 	struct NCR_700_Host_Parameters *hostdata = 
 		(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
@@ -1781,7 +1782,7 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, voi
 
 #ifdef NCR_700_DEBUG
 	printk("53c700: scsi%d, command ", SCp->device->host->host_no);
-	print_command(SCp->cmnd);
+	scsi_print_command(SCp);
 #endif
 	if(SCp->device->tagged_supported && !SCp->device->simple_tags
 	   && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
@@ -1827,13 +1828,13 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, voi
 	/* sanity check: some of the commands generated by the mid-layer
 	 * have an eccentric idea of their sc_data_direction */
 	if(!SCp->use_sg && !SCp->request_bufflen 
-	   && SCp->sc_data_direction != SCSI_DATA_NONE) {
+	   && SCp->sc_data_direction != DMA_NONE) {
 #ifdef NCR_700_DEBUG
 		printk("53c700: Command");
-		print_command(SCp->cmnd);
+		scsi_print_command(SCp);
 		printk("Has wrong data direction %d\n", SCp->sc_data_direction);
 #endif
-		SCp->sc_data_direction = SCSI_DATA_NONE;
+		SCp->sc_data_direction = DMA_NONE;
 	}
 
 	switch (SCp->cmnd[0]) {
@@ -1844,20 +1845,20 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, voi
 	default:
 		/* OK, get it from the command */
 		switch(SCp->sc_data_direction) {
-		case SCSI_DATA_UNKNOWN:
+		case DMA_BIDIRECTIONAL:
 		default:
 			printk(KERN_ERR "53c700: Unknown command for data direction ");
-			print_command(SCp->cmnd);
+			scsi_print_command(SCp);
 			
 			move_ins = 0;
 			break;
-		case SCSI_DATA_NONE:
+		case DMA_NONE:
 			move_ins = 0;
 			break;
-		case SCSI_DATA_READ:
+		case DMA_FROM_DEVICE:
 			move_ins = SCRIPT_MOVE_DATA_IN;
 			break;
-		case SCSI_DATA_WRITE:
+		case DMA_TO_DEVICE:
 			move_ins = SCRIPT_MOVE_DATA_OUT;
 			break;
 		}
@@ -1914,13 +1915,13 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, voi
 }
 
 STATIC int
-NCR_700_abort(Scsi_Cmnd * SCp)
+NCR_700_abort(struct scsi_cmnd * SCp)
 {
 	struct NCR_700_command_slot *slot;
 
 	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t",
 	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-	print_command(SCp->cmnd);
+	scsi_print_command(SCp);
 
 	slot = (struct NCR_700_command_slot *)SCp->host_scribble;
 
@@ -1946,7 +1947,7 @@ NCR_700_abort(Scsi_Cmnd * SCp)
 }
 
 STATIC int
-NCR_700_bus_reset(Scsi_Cmnd * SCp)
+NCR_700_bus_reset(struct scsi_cmnd * SCp)
 {
 	DECLARE_COMPLETION(complete);
 	struct NCR_700_Host_Parameters *hostdata = 
@@ -1954,7 +1955,7 @@ NCR_700_bus_reset(Scsi_Cmnd * SCp)
 
 	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
 	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
-	print_command(SCp->cmnd);
+	scsi_print_command(SCp);
 	/* In theory, eh_complete should always be null because the
 	 * eh is single threaded, but just in case we're handling a
 	 * reset via sg or something */
@@ -1976,21 +1977,21 @@ NCR_700_bus_reset(Scsi_Cmnd * SCp)
 }
 
 STATIC int
-NCR_700_dev_reset(Scsi_Cmnd * SCp)
+NCR_700_dev_reset(struct scsi_cmnd * SCp)
 {
 	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t",
 	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-	print_command(SCp->cmnd);
+	scsi_print_command(SCp);
 	
 	return FAILED;
 }
 
 STATIC int
-NCR_700_host_reset(Scsi_Cmnd * SCp)
+NCR_700_host_reset(struct scsi_cmnd * SCp)
 {
 	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t",
 	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-	print_command(SCp->cmnd);
+	scsi_print_command(SCp);
 
 	NCR_700_internal_bus_reset(SCp->device->host);
 	NCR_700_chip_reset(SCp->device->host);
@@ -2043,7 +2044,7 @@ NCR_700_set_offset(struct scsi_device *S
 
 
 STATIC int
-NCR_700_slave_configure(Scsi_Device *SDp)
+NCR_700_slave_configure(struct scsi_device *SDp)
 {
 	struct NCR_700_Host_Parameters *hostdata = 
 		(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
@@ -2066,7 +2067,7 @@ NCR_700_slave_configure(Scsi_Device *SDp
 }
 
 STATIC void
-NCR_700_slave_destroy(Scsi_Device *SDp)
+NCR_700_slave_destroy(struct scsi_device *SDp)
 {
 	/* to do here: deallocate memory */
 }
diff -puN drivers/scsi/53c700.h~bk-scsi drivers/scsi/53c700.h
--- 25/drivers/scsi/53c700.h~bk-scsi	2004-06-14 00:10:34.461069424 -0700
+++ 25-akpm/drivers/scsi/53c700.h	2004-06-14 00:10:34.740027016 -0700
@@ -9,9 +9,11 @@
 #define _53C700_H
 
 #include <linux/interrupt.h>
-
 #include <asm/io.h>
 
+#include <scsi/scsi_device.h>
+
+
 #if defined(CONFIG_53C700_MEM_MAPPED) && defined(CONFIG_53C700_IO_MAPPED)
 #define CONFIG_53C700_BOTH_MAPPED
 #endif
@@ -57,7 +59,8 @@
 struct NCR_700_Host_Parameters;
 
 /* These are the externally used routines */
-struct Scsi_Host *NCR_700_detect(Scsi_Host_Template *, struct NCR_700_Host_Parameters *);
+struct Scsi_Host *NCR_700_detect(struct scsi_host_template *,
+		struct NCR_700_Host_Parameters *);
 int NCR_700_release(struct Scsi_Host *host);
 irqreturn_t NCR_700_intr(int, void *, struct pt_regs *);
 
@@ -102,7 +105,7 @@ struct NCR_700_SG_List {
 #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19)
 
 static inline void
-NCR_700_set_depth(Scsi_Device *SDp, __u8 depth)
+NCR_700_set_depth(struct scsi_device *SDp, __u8 depth)
 {
 	long l = (long)SDp->hostdata;
 
@@ -111,27 +114,27 @@ NCR_700_set_depth(Scsi_Device *SDp, __u8
 	SDp->hostdata = (void *)l;
 }
 static inline __u8
-NCR_700_get_depth(Scsi_Device *SDp)
+NCR_700_get_depth(struct scsi_device *SDp)
 {
 	return ((((unsigned long)SDp->hostdata) & 0xff00)>>8);
 }
 static inline int
-NCR_700_is_flag_set(Scsi_Device *SDp, __u32 flag)
+NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag)
 {
 	return (((unsigned long)SDp->hostdata) & flag) == flag;
 }
 static inline int
-NCR_700_is_flag_clear(Scsi_Device *SDp, __u32 flag)
+NCR_700_is_flag_clear(struct scsi_device *SDp, __u32 flag)
 {
 	return (((unsigned long)SDp->hostdata) & flag) == 0;
 }
 static inline void
-NCR_700_set_flag(Scsi_Device *SDp, __u32 flag)
+NCR_700_set_flag(struct scsi_device *SDp, __u32 flag)
 {
 	SDp->hostdata = (void *)((long)SDp->hostdata | (flag & 0xffff0000));
 }
 static inline void
-NCR_700_clear_flag(Scsi_Device *SDp, __u32 flag)
+NCR_700_clear_flag(struct scsi_device *SDp, __u32 flag)
 {
 	SDp->hostdata = (void *)((long)SDp->hostdata & ~(flag & 0xffff0000));
 }
@@ -147,7 +150,7 @@ struct NCR_700_command_slot {
 	__u8	state;
 	int	tag;
 	__u32	resume_offset;
-	Scsi_Cmnd	*cmnd;
+	struct scsi_cmnd *cmnd;
 	/* The pci_mapped address of the actual command in cmnd */
 	dma_addr_t	pCmd;
 	__u32		temp;
@@ -185,7 +188,7 @@ struct NCR_700_Host_Parameters {
 	__u32	pScript;		/* physical mem addr of script */
 
 	enum NCR_700_Host_State state; /* protected by state lock */
-	Scsi_Cmnd *cmd;
+	struct scsi_cmnd *cmd;
 	/* Note: pScript contains the single consistent block of
 	 * memory.  All the msgin, msgout and status are allocated in
 	 * this memory too (at separate cache lines).  TOTAL_MEM_SIZE
diff -puN drivers/scsi/53c7xx.c~bk-scsi drivers/scsi/53c7xx.c
--- 25/drivers/scsi/53c7xx.c~bk-scsi	2004-06-14 00:10:34.464068968 -0700
+++ 25-akpm/drivers/scsi/53c7xx.c	2004-06-14 00:10:34.745026256 -0700
@@ -280,7 +280,7 @@
 #endif
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "53c7xx.h"
 #include <linux/stat.h>
 #include <linux/stddef.h>
diff -puN drivers/scsi/a2091.c~bk-scsi drivers/scsi/a2091.c
--- 25/drivers/scsi/a2091.c~bk-scsi	2004-06-14 00:10:34.466068664 -0700
+++ 25-akpm/drivers/scsi/a2091.c	2004-06-14 00:10:34.758024280 -0700
@@ -16,7 +16,7 @@
 #include <linux/spinlock.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "wd33c93.h"
 #include "a2091.h"
 
diff -puN drivers/scsi/a3000.c~bk-scsi drivers/scsi/a3000.c
--- 25/drivers/scsi/a3000.c~bk-scsi	2004-06-14 00:10:34.467068512 -0700
+++ 25-akpm/drivers/scsi/a3000.c	2004-06-14 00:10:34.759024128 -0700
@@ -15,7 +15,7 @@
 #include <asm/irq.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "wd33c93.h"
 #include "a3000.h"
 
diff -puN drivers/scsi/advansys.c~bk-scsi drivers/scsi/advansys.c
--- 25/drivers/scsi/advansys.c~bk-scsi	2004-06-14 00:10:34.472067752 -0700
+++ 25-akpm/drivers/scsi/advansys.c	2004-06-14 00:10:34.784020328 -0700
@@ -756,27 +756,6 @@
 
 */
 
-
-/*
- * --- Linux Version
- */
-
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif /* LINUX_VERSION_CODE */
-
-/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
-#define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
-#define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
-#define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0))
-
-/* Driver supported only in version 2.2 and version >= 2.4. */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \
-    (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \
-     LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
-#error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels."
-#endif
-
 /*
  * --- Linux Include Files
  */
@@ -801,13 +780,14 @@
 #include <linux/blkdev.h>
 #include <linux/stat.h>
 #include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/dma.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "advansys.h"
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
@@ -874,9 +854,6 @@
 
 typedef unsigned char uchar;
 
-#ifndef NULL
-#define NULL     (0)
-#endif
 #ifndef TRUE
 #define TRUE     (1)
 #endif
@@ -986,49 +963,6 @@ typedef unsigned char uchar;
 #define ASC_MIN_SENSE_LEN   14
 #define ASC_MAX_CDB_LEN     12
 #define ASC_SCSI_RESET_HOLD_TIME_US  60
-#define SCSICMD_TestUnitReady     0x00
-#define SCSICMD_Rewind            0x01
-#define SCSICMD_Rezero            0x01
-#define SCSICMD_RequestSense      0x03
-#define SCSICMD_Format            0x04
-#define SCSICMD_FormatUnit        0x04
-#define SCSICMD_Read6             0x08
-#define SCSICMD_Write6            0x0A
-#define SCSICMD_Seek6             0x0B
-#define SCSICMD_Inquiry           0x12
-#define SCSICMD_Verify6           0x13
-#define SCSICMD_ModeSelect6       0x15
-#define SCSICMD_ModeSense6        0x1A
-#define SCSICMD_StartStopUnit     0x1B
-#define SCSICMD_LoadUnloadTape    0x1B
-#define SCSICMD_ReadCapacity      0x25
-#define SCSICMD_Read10            0x28
-#define SCSICMD_Write10           0x2A
-#define SCSICMD_Seek10            0x2B
-#define SCSICMD_Erase10           0x2C
-#define SCSICMD_WriteAndVerify10  0x2E
-#define SCSICMD_Verify10          0x2F
-#define SCSICMD_WriteBuffer       0x3B
-#define SCSICMD_ReadBuffer        0x3C
-#define SCSICMD_ReadLong          0x3E
-#define SCSICMD_WriteLong         0x3F
-#define SCSICMD_ReadTOC           0x43
-#define SCSICMD_ReadHeader        0x44
-#define SCSICMD_ModeSelect10      0x55
-#define SCSICMD_ModeSense10       0x5A
-
-/* Inquiry Data Peripheral Device Types */
-#define SCSI_TYPE_DASD     0x00
-#define SCSI_TYPE_SASD     0x01
-#define SCSI_TYPE_PRN      0x02
-#define SCSI_TYPE_PROC     0x03
-#define SCSI_TYPE_WORM     0x04
-#define SCSI_TYPE_CDROM    0x05
-#define SCSI_TYPE_SCANNER  0x06
-#define SCSI_TYPE_OPTMEM   0x07
-#define SCSI_TYPE_MED_CHG  0x08
-#define SCSI_TYPE_COMM     0x09
-#define SCSI_TYPE_UNKNOWN  0x1F
 
 #define ADV_INQ_CLOCKING_ST_ONLY    0x0
 #define ADV_INQ_CLOCKING_DT_ONLY    0x1
@@ -1047,36 +981,11 @@ typedef unsigned char uchar;
 #define ASC_SCSIDIR_T2H      0x08
 #define ASC_SCSIDIR_H2T      0x10
 #define ASC_SCSIDIR_NODATA   0x18
-#define SCSI_SENKEY_NO_SENSE      0x00
-#define SCSI_SENKEY_UNDEFINED     0x01
-#define SCSI_SENKEY_NOT_READY     0x02
-#define SCSI_SENKEY_MEDIUM_ERR    0x03
-#define SCSI_SENKEY_HW_ERR        0x04
-#define SCSI_SENKEY_ILLEGAL       0x05
-#define SCSI_SENKEY_ATTENTION     0x06
-#define SCSI_SENKEY_PROTECTED     0x07
-#define SCSI_SENKEY_BLANK         0x08
-#define SCSI_SENKEY_V_UNIQUE      0x09
-#define SCSI_SENKEY_CPY_ABORT     0x0A
-#define SCSI_SENKEY_ABORT         0x0B
-#define SCSI_SENKEY_EQUAL         0x0C
-#define SCSI_SENKEY_VOL_OVERFLOW  0x0D
-#define SCSI_SENKEY_MISCOMP       0x0E
-#define SCSI_SENKEY_RESERVED      0x0F
 #define SCSI_ASC_NOMEDIA          0x3A
 #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
 #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
-#define SS_GOOD              0x00
-#define SS_CHK_CONDITION     0x02
-#define SS_CONDITION_MET     0x04
-#define SS_TARGET_BUSY       0x08
-#define SS_INTERMID          0x10
-#define SS_INTERMID_COND_MET 0x14
-#define SS_RSERV_CONFLICT    0x18
-#define SS_CMD_TERMINATED    0x22
-#define SS_QUEUE_FULL        0x28
 #define MS_CMD_DONE    0x00
 #define MS_EXTEND      0x01
 #define MS_SDTR_LEN    0x03
@@ -1085,26 +994,6 @@ typedef unsigned char uchar;
 #define MS_WDTR_CODE   0x03
 #define MS_MDP_LEN    0x05
 #define MS_MDP_CODE   0x00
-#define M1_SAVE_DATA_PTR        0x02
-#define M1_RESTORE_PTRS         0x03
-#define M1_DISCONNECT           0x04
-#define M1_INIT_DETECTED_ERR    0x05
-#define M1_ABORT                0x06
-#define M1_MSG_REJECT           0x07
-#define M1_NO_OP                0x08
-#define M1_MSG_PARITY_ERR       0x09
-#define M1_LINK_CMD_DONE        0x0A
-#define M1_LINK_CMD_DONE_WFLAG  0x0B
-#define M1_BUS_DVC_RESET        0x0C
-#define M1_ABORT_TAG            0x0D
-#define M1_CLR_QUEUE            0x0E
-#define M1_INIT_RECOVERY        0x0F
-#define M1_RELEASE_RECOVERY     0x10
-#define M1_KILL_IO_PROC         0x11
-#define M2_QTAG_MSG_SIMPLE      0x20
-#define M2_QTAG_MSG_HEAD        0x21
-#define M2_QTAG_MSG_ORDERED     0x22
-#define M2_IGNORE_WIDE_RESIDUE  0x23
 
 /*
  * Inquiry data structure and bitfield macros
@@ -1576,7 +1465,7 @@ typedef struct asc_dvc_cfg {
     uchar               sdtr_period_offset[ASC_MAX_TID + 1];
     ushort              pci_slot_info;
     uchar               adapter_info[6];
-    struct pci_dev	*pci_dev;
+    struct device	*dev;
 } ASC_DVC_CFG;
 
 #define ASC_DEF_DVC_CNTL       0xFFFF
@@ -3082,7 +2971,7 @@ typedef struct adv_dvc_cfg {
   ushort serial1;           /* EEPROM serial number word 1 */
   ushort serial2;           /* EEPROM serial number word 2 */
   ushort serial3;           /* EEPROM serial number word 3 */
-  struct pci_dev *pci_dev;  /* pointer to the pci dev structure for this board */
+  struct device *dev;  /* pointer to the pci dev structure for this board */
 } ADV_DVC_CFG;
 
 struct adv_dvc_var;
@@ -3581,19 +3470,6 @@ typedef struct {
 
 #define NO_ISA_DMA              0xff        /* No ISA DMA Channel Used */
 
-/*
- * If the Linux kernel version supports freeing initialization code
- * and data after loading, define macros for this purpose. These macros
- * are not used when the driver is built as a module, cf. linux/init.h.
- */
-#if ASC_LINUX_KERNEL24
-#define ASC_INITFUNC(type, func)        type __init func
-#elif ASC_LINUX_KERNEL22
-#define ASC_INITFUNC(type, func)        __initfunc(type func)
-#endif
-#define ASC_INITDATA                    __initdata
-#define ASC_INIT                        __init
-
 #define ASC_INFO_SIZE           128            /* advansys_info() line size */
 
 #ifdef CONFIG_PROC_FS
@@ -3610,8 +3486,6 @@ typedef struct {
         } \
         cp += len; \
     }
-
-#define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
 #endif /* CONFIG_PROC_FS */
 
 /* Asc Library return codes */
@@ -3685,53 +3559,6 @@ typedef Scsi_Cmnd            REQ, *REQP;
 /* Return non-zero, if the queue is empty. */
 #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
 
-/* PCI configuration declarations */
-
-#define PCI_BASE_CLASS_PREDEFINED               0x00
-#define PCI_BASE_CLASS_MASS_STORAGE             0x01
-#define PCI_BASE_CLASS_NETWORK                  0x02
-#define PCI_BASE_CLASS_DISPLAY                  0x03
-#define PCI_BASE_CLASS_MULTIMEDIA               0x04
-#define PCI_BASE_CLASS_MEMORY_CONTROLLER        0x05
-#define PCI_BASE_CLASS_BRIDGE_DEVICE            0x06
-
-/* MASS STORAGE */
-#define PCI_SUB_CLASS_SCSI_CONTROLLER           0x00
-#define PCI_SUB_CLASS_IDE_CONTROLLER            0x01
-#define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER    0x02
-#define PCI_SUB_CLASS_IPI_BUS_CONTROLLER        0x03
-#define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER     0x80
-
-/* NETWORK CONTROLLER */
-#define PCI_SUB_CLASS_ETHERNET_CONTROLLER       0x00
-#define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER     0x01
-#define PCI_SUB_CLASS_FDDI_CONTROLLER           0x02
-#define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER  0x80
-
-/* DISPLAY CONTROLLER */
-#define PCI_SUB_CLASS_VGA_CONTROLLER            0x00
-#define PCI_SUB_CLASS_XGA_CONTROLLER            0x01
-#define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER  0x80
-
-/* MULTIMEDIA CONTROLLER */
-#define PCI_SUB_CLASS_VIDEO_DEVICE              0x00
-#define PCI_SUB_CLASS_AUDIO_DEVICE              0x01
-#define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE   0x80
-
-/* MEMORY CONTROLLER */
-#define PCI_SUB_CLASS_RAM_CONTROLLER            0x00
-#define PCI_SUB_CLASS_FLASH_CONTROLLER          0x01
-#define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER   0x80
-
-/* BRIDGE CONTROLLER */
-#define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER    0x00
-#define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER     0x01
-#define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER    0x02
-#define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER      0x03
-#define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER    0x04
-#define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER  0x05
-#define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER   0x80
-
 #define PCI_MAX_SLOT            0x1F
 #define PCI_MAX_BUS             0xFF
 #define PCI_IOADDRESS_MASK      0xFFFE
@@ -3744,25 +3571,6 @@ typedef Scsi_Cmnd            REQ, *REQP;
 #define ASC_PCI_DEVICE_ID_2500  0x2500  /* ASC-38C0800 */
 #define ASC_PCI_DEVICE_ID_2700  0x2700  /* ASC-38C1600 */
 
-/* PCI IO Port Addresses to generate special cycle */
-
-#define PCI_CONFIG_ADDRESS_MECH1          0x0CF8
-#define PCI_CONFIG_DATA_MECH1             0x0CFC
-
-#define PCI_CONFIG_FORWARD_REGISTER       0x0CFA    /* 0=type 0; 1=type 1; */
-
-#define PCI_CONFIG_BUS_NUMBER_MASK        0x00FF0000
-#define PCI_CONFIG_DEVICE_FUNCTION_MASK   0x0000FF00
-#define PCI_CONFIG_REGISTER_NUMBER_MASK   0x000000F8
-
-#define PCI_DEVICE_FOUND                0x0000
-#define PCI_DEVICE_NOT_FOUND            0xffff
-
-#define SUBCLASS_OFFSET         0x0A
-#define CLASSCODE_OFFSET        0x0B
-#define VENDORID_OFFSET         0x00
-#define DEVICEID_OFFSET         0x02
-
 #ifndef ADVANSYS_STATS
 #define ASC_STATS(shp, counter)
 #define ASC_STATS_ADD(shp, counter, count)
@@ -4145,19 +3953,6 @@ typedef struct _PCI_CONFIG_SPACE_
 
 /* Note: All driver global data should be initialized. */
 
-#if ASC_LINUX_KERNEL22
-#ifdef CONFIG_PROC_FS
-struct proc_dir_entry proc_scsi_advansys =
-{
-    PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
-    8,                               /* unsigned short namelen */
-    "advansys",                      /* const char *name */
-    S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
-    2                                /* nlink_t nlink */
-};
-#endif /* CONFIG_PROC_FS */
-#endif /* ASC_LINUX_KERNEL22 */
-
 /* Number of boards detected in system. */
 STATIC int asc_board_count = 0;
 STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
@@ -4172,7 +3967,7 @@ STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } }
 STATIC ASC_SG_HEAD asc_sg_head = { 0 };
 
 /* List of supported bus types. */
-STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
+STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = {
     ASC_IS_ISA,
     ASC_IS_VL,
     ASC_IS_EISA,
@@ -4210,11 +4005,11 @@ STATIC PortAddr     _asc_def_iop_base[];
 
 STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *);
 STATIC int	  advansys_slave_configure(Scsi_Device *);
-STATIC void       asc_scsi_done_list(Scsi_Cmnd *, int from_isr);
+STATIC void       asc_scsi_done_list(Scsi_Cmnd *);
 STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
 STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
 STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
-STATIC int        adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *);
+STATIC int        adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *, int);
 STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
 STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
 STATIC void       adv_async_callback(ADV_DVC_VAR *, uchar);
@@ -4505,10 +4300,8 @@ advansys_proc_info(struct Scsi_Host *sho
  * it must not call SCSI mid-level functions including scsi_malloc()
  * and scsi_free().
  */
-ASC_INITFUNC(
-int,
+int __init
 advansys_detect(Scsi_Host_Template *tpnt)
-)
 {
     static int          detect_called = ASC_FALSE;
     int                 iop;
@@ -4526,6 +4319,7 @@ advansys_detect(Scsi_Host_Template *tpnt
     struct pci_dev      *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
     int                 pci_card_cnt_max = 0;
     int                 pci_card_cnt = 0;
+    struct device	*dev = NULL;
     struct pci_dev      *pci_devp = NULL;
     int                 pci_device_id_cnt = 0;
     unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
@@ -4550,12 +4344,6 @@ advansys_detect(Scsi_Host_Template *tpnt
 
     ASC_DBG(1, "advansys_detect: begin\n");
 
-#if ASC_LINUX_KERNEL24
-    tpnt->proc_name = "advansys";
-#elif ASC_LINUX_KERNEL22
-    tpnt->proc_dir = &proc_scsi_advansys;
-#endif
-
     asc_board_count = 0;
 
     /*
@@ -4681,13 +4469,9 @@ advansys_detect(Scsi_Host_Template *tpnt
                             NULL) {
                             pci_device_id_cnt++;
                         } else {
-#if ASC_LINUX_KERNEL24
                             if (pci_enable_device(pci_devp) == 0) {
                                 pci_devicep[pci_card_cnt_max++] = pci_devp;
                             }
-#elif ASC_LINUX_KERNEL22
-                            pci_devicep[pci_card_cnt_max++] = pci_devp;
-#endif
                         }
                     }
 
@@ -4724,17 +4508,16 @@ advansys_detect(Scsi_Host_Template *tpnt
                     ASC_DBG2(2,
                         "advansys_detect: devfn %d, bus number %d\n",
                         pci_devp->devfn, pci_devp->bus->number);
-#if ASC_LINUX_KERNEL24
                     iop = pci_resource_start(pci_devp, 0);
-#elif ASC_LINUX_KERNEL22
-                    iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
-#endif
                     ASC_DBG2(1,
                         "advansys_detect: vendorID %X, deviceID %X\n",
                         pci_devp->vendor, pci_devp->device);
                     ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
                         iop, pci_devp->irq);
                 }
+		if(pci_devp)
+		    dev = &pci_devp->dev;
+
 #endif /* CONFIG_PCI */
                 break;
 
@@ -4765,7 +4548,7 @@ advansys_detect(Scsi_Host_Template *tpnt
                 continue;
             }
 
-	    scsi_set_device(shp, &pci_devp->dev);
+	    scsi_set_device(shp, dev);
 
             /* Save a pointer to the Scsi_Host of each board found. */
             asc_host[asc_board_count++] = shp;
@@ -4849,11 +4632,7 @@ advansys_detect(Scsi_Host_Template *tpnt
                     iolen = ADV_38C1600_IOLEN;
                 }
 #ifdef CONFIG_PCI
-#if ASC_LINUX_KERNEL24
                 pci_memory_address = pci_resource_start(pci_devp, 1);
-#elif ASC_LINUX_KERNEL22
-                pci_memory_address = pci_devp->base_address[1];
-#endif
                 ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
                     (ulong) pci_memory_address);
                 if ((boardp->ioremap_addr =
@@ -4904,7 +4683,8 @@ advansys_detect(Scsi_Host_Template *tpnt
 #endif /* CONFIG_PROC_FS */
 
             if (ASC_NARROW_BOARD(boardp)) {
-                /*
+		asc_dvc_varp->cfg->dev = dev;
+		/*
                  * Set the board bus type and PCI IRQ before
                  * calling AscInitGetConfig().
                  */
@@ -4926,7 +4706,6 @@ advansys_detect(Scsi_Host_Template *tpnt
 #ifdef CONFIG_PCI
                 case ASC_IS_PCI:
                     shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
-                    asc_dvc_varp->cfg->pci_dev = pci_devp;
                     asc_dvc_varp->cfg->pci_slot_info =
                         ASC_PCI_MKID(pci_devp->bus->number,
                             PCI_SLOT(pci_devp->devfn),
@@ -4944,13 +4723,13 @@ advansys_detect(Scsi_Host_Template *tpnt
                     break;
                 }
             } else {
+                adv_dvc_varp->cfg->dev = dev;
                 /*
                  * For Wide boards set PCI information before calling
                  * AdvInitGetConfig().
                  */
 #ifdef CONFIG_PCI
                 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
-                adv_dvc_varp->cfg->pci_dev = pci_devp;
                 adv_dvc_varp->cfg->pci_slot_info =
                     ASC_PCI_MKID(pci_devp->bus->number,
                         PCI_SLOT(pci_devp->devfn),
@@ -5321,11 +5100,7 @@ advansys_detect(Scsi_Host_Template *tpnt
 
             /* BIOS start address. */
             if (ASC_NARROW_BOARD(boardp)) {
-#if ASC_LINUX_KERNEL24
                 shp->base =
-#elif ASC_LINUX_KERNEL22
-                shp->base = (char *)
-#endif
                         ((ulong) AscGetChipBiosAddress(
                             asc_dvc_varp->iop_base,
                             asc_dvc_varp->bus_type));
@@ -5360,11 +5135,7 @@ advansys_detect(Scsi_Host_Template *tpnt
                      * Convert x86 realmode code segment to a linear
                      * address by shifting left 4.
                      */
-                    shp->base =
-#if ASC_LINUX_KERNEL22
-                        (char *)
-#endif
-                        ((ulong) boardp->bios_codeseg << 4);
+                    shp->base = ((ulong) boardp->bios_codeseg << 4);
                 } else {
                     shp->base = 0;
                 }
@@ -5385,7 +5156,6 @@ advansys_detect(Scsi_Host_Template *tpnt
             ASC_DBG2(2,
                 "advansys_detect: request_region port 0x%lx, len 0x%x\n",
                 (ulong) shp->io_port, boardp->asc_n_io_port);
-#if ASC_LINUX_KERNEL24
             if (request_region(shp->io_port, boardp->asc_n_io_port,
                                "advansys") == NULL) {
                 ASC_PRINT3(
@@ -5398,9 +5168,6 @@ advansys_detect(Scsi_Host_Template *tpnt
                 asc_board_count--;
                 continue;
             }
-#elif ASC_LINUX_KERNEL22
-            request_region(shp->io_port, boardp->asc_n_io_port, "advansys");
-#endif
 
             /* Register DMA Channel for Narrow boards. */
             shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
@@ -5880,7 +5647,7 @@ advansys_queuecommand(Scsi_Cmnd *scp, vo
     default:
         done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
         /* Interrupts could be enabled here. */
-        asc_scsi_done_list(done_scp, 0);
+        asc_scsi_done_list(done_scp);
         break;
     }
     spin_unlock_irqrestore(&boardp->lock, flags);
@@ -6063,7 +5830,7 @@ advansys_reset(Scsi_Cmnd *scp)
      * Complete all the 'done_scp' requests.
      */
     if (done_scp != NULL) {
-        asc_scsi_done_list(done_scp, 0);
+        asc_scsi_done_list(done_scp);
     }
 
     ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
@@ -6149,10 +5916,8 @@ advansys_biosparam(struct scsi_device *s
  * ints[2] - second argument
  * ...
  */
-ASC_INITFUNC(
-void,
+void __init
 advansys_setup(char *str, int *ints)
-)
 {
     int    i;
 
@@ -6328,7 +6093,7 @@ advansys_interrupt(int irq, void *dev_id
      * Complete all requests on the done list.
      */
 
-    asc_scsi_done_list(done_scp, 1);
+    asc_scsi_done_list(done_scp);
 
     ASC_DBG(1, "advansys_interrupt: end\n");
     return IRQ_HANDLED;
@@ -6374,23 +6139,38 @@ advansys_slave_configure(Scsi_Device *de
  * Interrupts can be enabled on entry.
  */
 STATIC void
-asc_scsi_done_list(Scsi_Cmnd *scp, int from_isr)
+asc_scsi_done_list(Scsi_Cmnd *scp)
 {
     Scsi_Cmnd    *tscp;
-    ulong	  flags = 0;
 
     ASC_DBG(2, "asc_scsi_done_list: begin\n");
     while (scp != NULL) {
+	asc_board_t *boardp;
+	struct device *dev;
+
         ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
         tscp = REQPNEXT(scp);
         scp->host_scribble = NULL;
+
+	boardp = ASC_BOARDP(scp->device->host);
+
+	if (ASC_NARROW_BOARD(boardp))
+	    dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
+	else
+	    dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
+
+	if (scp->use_sg)
+	    dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer,
+			 scp->use_sg, scp->sc_data_direction);
+	else if (scp->request_bufflen)
+	    dma_unmap_single(dev, scp->SCp.dma_handle,
+			     scp->request_bufflen, scp->sc_data_direction);
+
         ASC_STATS(scp->device->host, done);
         ASC_ASSERT(scp->scsi_done != NULL);
-	if (from_isr)
-	    spin_lock_irqsave(scp->device->host->host_lock, flags);
+
         scp->scsi_done(scp);
-	if (from_isr)
-	    spin_unlock_irqrestore(scp->device->host->host_lock, flags);
+
         scp = tscp;
     }
     ASC_DBG(2, "asc_scsi_done_list: done\n");
@@ -6619,6 +6399,8 @@ asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
 STATIC int
 asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
 {
+    struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
+
     /*
      * Mutually exclusive access is required to 'asc_scsi_q' and
      * 'asc_sg_head' until after the request is started.
@@ -6665,9 +6447,9 @@ asc_build_req(asc_board_t *boardp, Scsi_
      */
     if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
         (boardp->reqcnt[scp->device->id] % 255) == 0) {
-        asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
+        asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
     } else {
-        asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
+        asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
     }
 
     /*
@@ -6679,8 +6461,10 @@ asc_build_req(asc_board_t *boardp, Scsi_
          * CDB request of single contiguous buffer.
          */
         ASC_STATS(scp->device->host, cont_cnt);
-        asc_scsi_q.q1.data_addr =
-            cpu_to_le32(virt_to_bus(scp->request_buffer));
+	scp->SCp.dma_handle = scp->request_bufflen ?
+	    dma_map_single(dev, scp->request_buffer,
+			   scp->request_bufflen, scp->sc_data_direction) : 0;
+	asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
         asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
         ASC_STATS_ADD(scp->device->host, cont_xfer,
                       ASC_CEILING(scp->request_bufflen, 512));
@@ -6691,12 +6475,17 @@ asc_build_req(asc_board_t *boardp, Scsi_
          * CDB scatter-gather request list.
          */
         int                     sgcnt;
+	int			use_sg;
         struct scatterlist      *slp;
 
-        if (scp->use_sg > scp->device->host->sg_tablesize) {
+	slp = (struct scatterlist *)scp->request_buffer;
+	use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+
+	if (use_sg > scp->device->host->sg_tablesize) {
             ASC_PRINT3(
 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
-                boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
+		boardp->id, use_sg, scp->device->host->sg_tablesize);
+	    dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
             return ASC_ERROR;
@@ -6715,19 +6504,16 @@ asc_build_req(asc_board_t *boardp, Scsi_
         asc_scsi_q.q1.data_cnt = 0;
         asc_scsi_q.q1.data_addr = 0;
         /* This is a byte value, otherwise it would need to be swapped. */
-        asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
+	asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
         ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
 
         /*
          * Convert scatter-gather list into ASC_SG_HEAD list.
          */
-        slp = (struct scatterlist *) scp->request_buffer;
-        for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
-            asc_sg_head.sg_list[sgcnt].addr =
-                cpu_to_le32(virt_to_bus(
-		(unsigned char *)page_address(slp->page) + slp->offset));
-            asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
-            ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
+	for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
+	    asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp));
+	    asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp));
+	    ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
         }
     }
 
@@ -6755,6 +6541,7 @@ adv_build_req(asc_board_t *boardp, Scsi_
     ADV_SCSI_REQ_Q      *scsiqp;
     int                 i;
     int                 ret;
+    struct device	*dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
 
     /*
      * Allocate an adv_req_t structure from the board to execute
@@ -6827,15 +6614,23 @@ adv_build_req(asc_board_t *boardp, Scsi_
      * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
      * buffer command.
      */
-    scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
-    scsiqp->vdata_addr = scp->request_buffer;
-    scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
 
     if (scp->use_sg == 0) {
         /*
          * CDB request of single contiguous buffer.
          */
         reqp->sgblkp = NULL;
+	scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
+	if (scp->request_bufflen) {
+	    scsiqp->vdata_addr = scp->request_buffer;
+	    scp->SCp.dma_handle =
+	        dma_map_single(dev, scp->request_buffer,
+			       scp->request_bufflen, scp->sc_data_direction);
+	} else {
+	    scsiqp->vdata_addr = 0;
+	    scp->SCp.dma_handle = 0;
+	}
+	scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
         scsiqp->sg_list_ptr = NULL;
         scsiqp->sg_real_addr = 0;
         ASC_STATS(scp->device->host, cont_cnt);
@@ -6845,10 +6640,21 @@ adv_build_req(asc_board_t *boardp, Scsi_
         /*
          * CDB scatter-gather request list.
          */
-        if (scp->use_sg > ADV_MAX_SG_LIST) {
+	struct scatterlist *slp;
+	int use_sg;
+
+	scsiqp->data_cnt = 0;
+	scsiqp->vdata_addr = 0;
+	scsiqp->data_addr = 0;
+
+	slp = (struct scatterlist *)scp->request_buffer;
+	use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+
+	if (use_sg > ADV_MAX_SG_LIST) {
             ASC_PRINT3(
 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
-                boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
+		boardp->id, use_sg, scp->device->host->sg_tablesize);
+	    dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
             scp->result = HOST_BYTE(DID_ERROR);
             asc_enqueue(&boardp->done, scp, ASC_BACK);
 
@@ -6862,7 +6668,7 @@ adv_build_req(asc_board_t *boardp, Scsi_
             return ASC_ERROR;
         }
 
-        if ((ret = adv_get_sglist(boardp, reqp, scp)) != ADV_SUCCESS) {
+	if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) {
             /*
              * Free the adv_req_t structure by adding it back to the
              * board free list.
@@ -6874,7 +6680,7 @@ adv_build_req(asc_board_t *boardp, Scsi_
         }
 
         ASC_STATS(scp->device->host, sg_cnt);
-        ASC_STATS_ADD(scp->device->host, sg_elem, scp->use_sg);
+	ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
     }
 
     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
@@ -6898,7 +6704,7 @@ adv_build_req(asc_board_t *boardp, Scsi_
  *      ADV_ERROR(-1) - SG List creation failed
  */
 STATIC int
-adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
+adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp, int use_sg)
 {
     adv_sgblk_t         *sgblkp;
     ADV_SCSI_REQ_Q      *scsiqp;
@@ -6910,7 +6716,7 @@ adv_get_sglist(asc_board_t *boardp, adv_
 
     scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
     slp = (struct scatterlist *) scp->request_buffer;
-    sg_elem_cnt = scp->use_sg;
+    sg_elem_cnt = use_sg;
     prev_sg_block = NULL;
     reqp->sgblkp = NULL;
 
@@ -6982,11 +6788,9 @@ adv_get_sglist(asc_board_t *boardp, adv_
 
         for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
         {
-            sg_block->sg_list[i].sg_addr =
-                cpu_to_le32(virt_to_bus(
-                   (unsigned char *)page_address(slp->page) + slp->offset));
-            sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
-            ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
+	    sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp));
+	    sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp));
+	    ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
 
             if (--sg_elem_cnt == 0)
             {   /* Last ADV_SG_BLOCK and scatter-gather entry. */
@@ -7079,14 +6883,13 @@ asc_isr_callback(ASC_DVC_VAR *asc_dvc_va
          * If an INQUIRY command completed successfully, then call
          * the AscInquiryHandling() function to set-up the device.
          */
-        if (scp->cmnd[0] == SCSICMD_Inquiry && scp->device->lun == 0 &&
+        if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
             (scp->request_bufflen - qdonep->remain_bytes) >= 8)
         {
             AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
                 (ASC_SCSI_INQUIRY *) scp->request_buffer);
         }
 
-#if ASC_LINUX_KERNEL24
         /*
          * Check for an underrun condition.
          *
@@ -7099,15 +6902,14 @@ asc_isr_callback(ASC_DVC_VAR *asc_dvc_va
             (unsigned) qdonep->remain_bytes);
             scp->resid = qdonep->remain_bytes;
         }
-#endif
         break;
 
     case QD_WITH_ERROR:
         ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
         switch (qdonep->d3.host_stat) {
         case QHSTA_NO_ERROR:
-            if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
-                ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
+            if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
+                ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
                     sizeof(scp->sense_buffer));
                 /*
@@ -7185,9 +6987,7 @@ adv_isr_callback(ADV_DVC_VAR *adv_dvc_va
     Scsi_Cmnd           *scp;
     struct Scsi_Host    *shp;
     int                 i;
-#if ASC_LINUX_KERNEL24
     ADV_DCNT            resid_cnt;
-#endif
 
 
     ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
@@ -7270,7 +7070,6 @@ adv_isr_callback(ADV_DVC_VAR *adv_dvc_va
         ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
         scp->result = 0;
 
-#if ASC_LINUX_KERNEL24
         /*
          * Check for an underrun condition.
          *
@@ -7284,15 +7083,14 @@ adv_isr_callback(ADV_DVC_VAR *adv_dvc_va
                 (ulong) resid_cnt);
             scp->resid = resid_cnt;
         }
-#endif
         break;
 
     case QD_WITH_ERROR:
         ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
         switch (scsiqp->host_status) {
         case QHSTA_NO_ERROR:
-            if (scsiqp->scsi_status == SS_CHK_CONDITION) {
-                ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
+            if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
+                ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
                     sizeof(scp->sense_buffer));
                 /*
@@ -8858,7 +8656,7 @@ asc_proc_copy(off_t advoffset, off_t off
             (unsigned) offset, (unsigned) advoffset, cplen);
     if (offset <= advoffset) {
         /* Read offset below current offset, copy everything. */
-        cnt = ASC_MIN(cplen, leftlen);
+        cnt = min(cplen, leftlen);
         ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
                 (ulong) curbuf, (ulong) cp, cnt);
         memcpy(curbuf, cp, cnt);
@@ -8866,7 +8664,7 @@ asc_proc_copy(off_t advoffset, off_t off
         /* Read offset within current range, partial copy. */
         cnt = (advoffset + cplen) - offset;
         cp = (cp + cplen) - cnt;
-        cnt = ASC_MIN(cnt, leftlen);
+        cnt = min(cnt, leftlen);
         ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
                 (ulong) curbuf, (ulong) cp, cnt);
         memcpy(curbuf, cp, cnt);
@@ -8899,7 +8697,7 @@ asc_prt_line(char *buf, int buflen, char
         (void) printk(s);
         ret = 0;
     } else {
-        ret = ASC_MIN(buflen, ret);
+        ret = min(buflen, ret);
         memcpy(buf, s, ret);
     }
     va_end(args);
@@ -9002,16 +8800,14 @@ DvcGetQinfo(PortAddr iop_base, ushort s_
 /*
  * Read a PCI configuration byte.
  */
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 DvcReadPCIConfigByte(
         ASC_DVC_VAR *asc_dvc,
         ushort offset)
-)
 {
 #ifdef CONFIG_PCI
     uchar byte_data;
-    pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
+    pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
     return byte_data;
 #else /* !defined(CONFIG_PCI) */
     return 0;
@@ -9021,16 +8817,14 @@ DvcReadPCIConfigByte(
 /*
  * Write a PCI configuration byte.
  */
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 DvcWritePCIConfigByte(
         ASC_DVC_VAR *asc_dvc,
         ushort offset,
         uchar  byte_data)
-)
 {
 #ifdef CONFIG_PCI
-    pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
+    pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
 #endif /* CONFIG_PCI */
 }
 
@@ -9038,13 +8832,10 @@ DvcWritePCIConfigByte(
  * Return the BIOS address of the adapter at the specified
  * I/O port and with the specified bus type.
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetChipBiosAddress(
         PortAddr iop_base,
-        ushort bus_type
-)
-)
+        ushort bus_type)
 {
     ushort  cfg_lsw;
     ushort  bios_addr;
@@ -9119,16 +8910,14 @@ DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_
 /*
  * Read a PCI configuration byte.
  */
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 DvcAdvReadPCIConfigByte(
         ADV_DVC_VAR *asc_dvc,
         ushort offset)
-)
 {
 #ifdef CONFIG_PCI
     uchar byte_data;
-    pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
+    pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
     return byte_data;
 #else /* CONFIG_PCI */
     return 0;
@@ -9138,16 +8927,14 @@ DvcAdvReadPCIConfigByte(
 /*
  * Write a PCI configuration byte.
  */
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 DvcAdvWritePCIConfigByte(
         ADV_DVC_VAR *asc_dvc,
         ushort offset,
         uchar  byte_data)
-)
 {
 #ifdef CONFIG_PCI
-    pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
+    pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
 #else /* CONFIG_PCI */
     return 0;
 #endif /* CONFIG_PCI */
@@ -9358,16 +9145,6 @@ asc_prt_scsi_host(struct Scsi_Host *s)
         s->host_busy, s->host_no,
         (unsigned) s->last_reset);
 
-#if ASC_LINUX_KERNEL24
-    printk(
-" hostt 0x%lx\n",
-        (ulong) s->hostt);
-#elif ASC_LINUX_KERNEL22
-    printk(
-" host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n",
-        (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block);
-#endif
-
     printk(
 " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
         (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
@@ -9404,11 +9181,9 @@ asc_prt_scsi_cmnd(Scsi_Cmnd *s)
 
     asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
 
-#if ASC_LINUX_KERNEL24
     printk (
 "sc_data_direction %u, resid %d\n",
         s->sc_data_direction, s->resid);
-#endif
 
     printk(
 " use_sg %u, sglist_len %u, abort_reason 0x%x\n",
@@ -9423,15 +9198,9 @@ asc_prt_scsi_cmnd(Scsi_Cmnd *s)
 " timeout_per_command %d, timeout_total %d, timeout %d\n",
         s->timeout_per_command, s->timeout_total, s->timeout);
 
-#if ASC_LINUX_KERNEL24
     printk(
 " internal_timeout %u, flags %u\n",
         s->internal_timeout, s->flags);
-#elif ASC_LINUX_KERNEL22
-    printk(
-" internal_timeout %u, flags %u, this_count %d\n",
-        s->internal_timeout, s->flags,s->this_count);
-#endif
 
     printk(
 " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
@@ -9507,7 +9276,8 @@ asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
 
     printk(
 " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
-          h->pci_dev->device, h->lib_serial_no, h->lib_version, h->mcode_date);
+	   to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
+	   h->mcode_date);
 
     printk(
 " mcode_version %d, overrun_buf 0x%lx\n",
@@ -9632,7 +9402,7 @@ asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
 
     printk(
 "  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
-       h->mcode_version, h->pci_dev->device, h->lib_version);
+       h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
 
     printk(
 "  control_flag 0x%x, pci_slot_info 0x%x\n",
@@ -9787,12 +9557,9 @@ asc_prt_hex(char *f, uchar *s, int l)
  * --- Asc Library Functions
  */
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetEisaChipCfg(
-                     PortAddr iop_base
-)
-)
+                     PortAddr iop_base)
 {
     PortAddr            eisa_cfg_iop;
 
@@ -9801,13 +9568,11 @@ AscGetEisaChipCfg(
     return (inpw(eisa_cfg_iop));
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscSetChipScsiID(
                     PortAddr iop_base,
                     uchar new_host_id
 )
-)
 {
     ushort              cfg_lsw;
 
@@ -9821,12 +9586,9 @@ AscSetChipScsiID(
     return (AscGetChipScsiID(iop_base));
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscGetChipScsiCtrl(
-                      PortAddr iop_base
-)
-)
+		PortAddr iop_base)
 {
     uchar               sc;
 
@@ -9836,13 +9598,11 @@ AscGetChipScsiCtrl(
     return (sc);
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscGetChipVersion(
                      PortAddr iop_base,
                      ushort bus_type
 )
-)
 {
     if ((bus_type & ASC_IS_EISA) != 0) {
         PortAddr            eisa_iop;
@@ -9855,12 +9615,9 @@ AscGetChipVersion(
     return (AscGetChipVerNo(iop_base));
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetChipBusType(
-                     PortAddr iop_base
-)
-)
+                     PortAddr iop_base)
 {
     ushort              chip_ver;
 
@@ -9940,22 +9697,19 @@ AscFindSignature(
     return (0);
 }
 
-STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
+STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata =
 {
     0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
     ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
 };
 
 #ifdef CONFIG_ISA
-STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
+STATIC uchar _isa_pnp_inited __initdata = 0;
 
-ASC_INITFUNC(
-STATIC PortAddr,
+STATIC PortAddr __init
 AscSearchIOPortAddr(
                        PortAddr iop_beg,
-                       ushort bus_type
-)
-)
+                       ushort bus_type)
 {
     if (bus_type & ASC_IS_VL) {
         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
@@ -9986,12 +9740,10 @@ AscSearchIOPortAddr(
     return (0);
 }
 
-ASC_INITFUNC(
-STATIC PortAddr,
+STATIC PortAddr __init
 AscSearchIOPortAddr11(
                          PortAddr s_addr
 )
-)
 {
     int                 i;
     PortAddr            iop_base;
@@ -10017,11 +9769,8 @@ AscSearchIOPortAddr11(
     return (0);
 }
 
-ASC_INITFUNC(
-STATIC void,
-AscSetISAPNPWaitForKey(
-    void)
-)
+STATIC void __init
+AscSetISAPNPWaitForKey(void)
 {
     outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
     outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
@@ -10029,25 +9778,20 @@ AscSetISAPNPWaitForKey(
 }
 #endif /* CONFIG_ISA */
 
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 AscToggleIRQAct(
                    PortAddr iop_base
 )
-)
 {
     AscSetChipStatus(iop_base, CIW_IRQ_ACT);
     AscSetChipStatus(iop_base, 0);
     return;
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscGetChipIRQ(
                  PortAddr iop_base,
-                 ushort bus_type
-)
-)
+                 ushort bus_type)
 {
     ushort              cfg_lsw;
     uchar               chip_irq;
@@ -10077,14 +9821,11 @@ AscGetChipIRQ(
     return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscSetChipIRQ(
                  PortAddr iop_base,
                  uchar irq_no,
-                 ushort bus_type
-)
-)
+                 ushort bus_type)
 {
     ushort              cfg_lsw;
 
@@ -10119,12 +9860,9 @@ AscSetChipIRQ(
 }
 
 #ifdef CONFIG_ISA
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 AscEnableIsaDma(
-                   uchar dma_channel
-)
-)
+                   uchar dma_channel)
 {
     if (dma_channel < 4) {
         outp(0x000B, (ushort) (0xC0 | dma_channel));
@@ -10285,7 +10023,7 @@ AscIsrChipHalted(
             return (0);
         } else {
 
-            ext_msg.msg_type = M1_MSG_REJECT;
+            ext_msg.msg_type = MESSAGE_REJECT;
             AscMemWordCopyPtrToLram(iop_base,
                                  ASCV_MSGOUT_BEG,
                                  (uchar *) &ext_msg,
@@ -10385,7 +10123,7 @@ AscIsrChipHalted(
                              (ushort) ASCV_SCSIBUSY_B, scsi_busy);
             asc_dvc->queue_full_or_busy |= target_id;
 
-            if (scsi_status == SS_QUEUE_FULL) {
+            if (scsi_status == SAM_STAT_TASK_SET_FULL) {
                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
                     cur_dvc_qng -= 1;
                     asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
@@ -10732,7 +10470,7 @@ AscIsrQDone(
             } else {
                 if ((AscReadLramByte(iop_base,
                           (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
-                     SCSICMD_StartStopUnit)) {
+                     START_STOP)) {
                     asc_dvc->unit_not_ready &= ~target_id;
                     if (scsiq->d3.done_stat != QD_NO_ERROR) {
                         asc_dvc->start_motor &= ~target_id;
@@ -11005,14 +10743,14 @@ STATIC ADV_DCNT _asc_mcode_chksum = 0x01
 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
 {
-    SCSICMD_Inquiry,
-    SCSICMD_RequestSense,
-    SCSICMD_ReadCapacity,
-    SCSICMD_ReadTOC,
-    SCSICMD_ModeSelect6,
-    SCSICMD_ModeSense6,
-    SCSICMD_ModeSelect10,
-    SCSICMD_ModeSense10,
+    INQUIRY,
+    REQUEST_SENSE,
+    READ_CAPACITY,
+    READ_TOC,
+    MODE_SELECT,
+    MODE_SENSE,
+    MODE_SELECT_10,
+    MODE_SENSE_10,
     0xFF,
     0xFF,
     0xFF,
@@ -11065,7 +10803,7 @@ AscExeScsiQueue(
     target_ix = scsiq->q2.target_ix;
     tid_no = ASC_TIX_TO_TID(target_ix);
     n_q_required = 1;
-    if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
+    if (scsiq->cdbptr[0] == REQUEST_SENSE) {
         if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
             asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
@@ -11134,7 +10872,7 @@ AscExeScsiQueue(
         }
     }
     if (disable_syn_offset_one_fix) {
-        scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
+        scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
         scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
                                ASC_TAG_FLAG_DISABLE_DISCONNECT);
     } else {
@@ -11143,8 +10881,8 @@ AscExeScsiQueue(
     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
         if (asc_dvc->bug_fix_cntl) {
             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
-                if ((scsi_cmd == SCSICMD_Read6) ||
-                    (scsi_cmd == SCSICMD_Read10)) {
+                if ((scsi_cmd == READ_6) ||
+                    (scsi_cmd == READ_10)) {
                     addr =
                         (ADV_PADDR) le32_to_cpu(
                             sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
@@ -11193,8 +10931,8 @@ AscExeScsiQueue(
     } else {
         if (asc_dvc->bug_fix_cntl) {
             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
-                if ((scsi_cmd == SCSICMD_Read6) ||
-                    (scsi_cmd == SCSICMD_Read10)) {
+                if ((scsi_cmd == READ_6) ||
+                    (scsi_cmd == READ_10)) {
                     addr = le32_to_cpu(scsiq->q1.data_addr) +
                         le32_to_cpu(scsiq->q1.data_cnt);
                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
@@ -11365,7 +11103,7 @@ AscPutReadyQueue(
     }
     q_addr = ASC_QNO_TO_QADDR(q_no);
     if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
-        scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
+        scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ;
     }
     scsiq->q1.status = QS_FREE;
     AscMemWordCopyPtrToLram(iop_base,
@@ -11862,12 +11600,9 @@ DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc,
 }
 
 #ifdef CONFIG_ISA
-ASC_INITFUNC(
-STATIC ASC_DCNT,
+STATIC ASC_DCNT __init
 AscGetEisaProductID(
-                       PortAddr iop_base
-)
-)
+                       PortAddr iop_base)
 {
     PortAddr            eisa_iop;
     ushort              product_id_high, product_id_low;
@@ -11881,12 +11616,9 @@ AscGetEisaProductID(
     return (product_id);
 }
 
-ASC_INITFUNC(
-STATIC PortAddr,
+STATIC PortAddr __init
 AscSearchIOPortAddrEISA(
-                           PortAddr iop_base
-)
-)
+                           PortAddr iop_base)
 {
     ASC_DCNT            eisa_product_id;
 
@@ -12080,12 +11812,9 @@ AscResetChipAndScsiBus(
     return (AscIsChipHalted(iop_base));
 }
 
-ASC_INITFUNC(
-STATIC ASC_DCNT,
+STATIC ASC_DCNT __init
 AscGetMaxDmaCount(
-                     ushort bus_type
-)
-)
+                     ushort bus_type)
 {
     if (bus_type & ASC_IS_ISA)
         return (ASC_MAX_ISA_DMA_COUNT);
@@ -12095,12 +11824,9 @@ AscGetMaxDmaCount(
 }
 
 #ifdef CONFIG_ISA
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetIsaDmaChannel(
-                       PortAddr iop_base
-)
-)
+                       PortAddr iop_base)
 {
     ushort              channel;
 
@@ -12112,13 +11838,10 @@ AscGetIsaDmaChannel(
     return (channel + 4);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscSetIsaDmaChannel(
                        PortAddr iop_base,
-                       ushort dma_channel
-)
-)
+                       ushort dma_channel)
 {
     ushort              cfg_lsw;
     uchar               value;
@@ -12136,13 +11859,10 @@ AscSetIsaDmaChannel(
     return (0);
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscSetIsaDmaSpeed(
                      PortAddr iop_base,
-                     uchar speed_value
-)
-)
+                     uchar speed_value)
 {
     speed_value &= 0x07;
     AscSetBank(iop_base, 1);
@@ -12151,12 +11871,10 @@ AscSetIsaDmaSpeed(
     return (AscGetIsaDmaSpeed(iop_base));
 }
 
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
 AscGetIsaDmaSpeed(
                      PortAddr iop_base
 )
-)
 {
     uchar               speed_value;
 
@@ -12168,12 +11886,10 @@ AscGetIsaDmaSpeed(
 }
 #endif /* CONFIG_ISA */
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscReadPCIConfigWord(
     ASC_DVC_VAR *asc_dvc,
     ushort pci_config_offset)
-)
 {
     uchar       lsb, msb;
 
@@ -12182,12 +11898,10 @@ AscReadPCIConfigWord(
     return ((ushort) ((msb << 8) | lsb));
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscInitGetConfig(
         ASC_DVC_VAR *asc_dvc
 )
-)
 {
     ushort              warn_code;
     PortAddr            iop_base;
@@ -12267,12 +11981,10 @@ AscInitGetConfig(
     return(warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscInitSetConfig(
                     ASC_DVC_VAR *asc_dvc
 )
-)
 {
     ushort              warn_code = 0;
 
@@ -12288,12 +12000,10 @@ AscInitSetConfig(
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscInitFromAscDvcVar(
                         ASC_DVC_VAR *asc_dvc
 )
-)
 {
     PortAddr            iop_base;
     ushort              cfg_msw;
@@ -12301,7 +12011,7 @@ AscInitFromAscDvcVar(
     ushort              pci_device_id;
 
     iop_base = asc_dvc->iop_base;
-    pci_device_id = asc_dvc->cfg->pci_dev->device;
+    pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
     warn_code = 0;
     cfg_msw = AscGetChipCfgMsw(iop_base);
     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
@@ -12393,12 +12103,9 @@ AscInitAsc1000Driver(
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscInitAscDvcVar(
-                    ASC_DVC_VAR *asc_dvc
-)
-)
+                    ASC_DVC_VAR *asc_dvc)
 {
     int                 i;
     PortAddr            iop_base;
@@ -12508,12 +12215,8 @@ AscInitAscDvcVar(
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
-AscInitFromEEP(
-                  ASC_DVC_VAR *asc_dvc
-)
-)
+STATIC ushort __init
+AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
 {
     ASCEEP_CONFIG       eep_config_buf;
     ASCEEP_CONFIG       *eep_config;
@@ -12729,12 +12432,9 @@ AscInitMicroCodeVar(
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscTestExternalLram(
-                       ASC_DVC_VAR *asc_dvc
-)
-)
+                       ASC_DVC_VAR *asc_dvc)
 {
     PortAddr            iop_base;
     ushort              q_addr;
@@ -12756,13 +12456,11 @@ AscTestExternalLram(
     return (sta);
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscWriteEEPCmdReg(
                      PortAddr iop_base,
                      uchar cmd_reg
 )
-)
 {
     uchar               read_back;
     int                 retry;
@@ -12781,13 +12479,11 @@ AscWriteEEPCmdReg(
     }
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscWriteEEPDataReg(
                       PortAddr iop_base,
                       ushort data_reg
 )
-)
 {
     ushort              read_back;
     int                 retry;
@@ -12806,35 +12502,24 @@ AscWriteEEPDataReg(
     }
 }
 
-ASC_INITFUNC(
-STATIC void,
-AscWaitEEPRead(
-                  void
-)
-)
+STATIC void __init
+AscWaitEEPRead(void)
 {
     DvcSleepMilliSecond(1);
     return;
 }
 
-ASC_INITFUNC(
-STATIC void,
-AscWaitEEPWrite(
-                   void
-)
-)
+STATIC void __init
+AscWaitEEPWrite(void)
 {
     DvcSleepMilliSecond(20);
     return;
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscReadEEPWord(
                   PortAddr iop_base,
-                  uchar addr
-)
-)
+                  uchar addr)
 {
     ushort              read_wval;
     uchar               cmd_reg;
@@ -12849,14 +12534,11 @@ AscReadEEPWord(
     return (read_wval);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscWriteEEPWord(
                    PortAddr iop_base,
                    uchar addr,
-                   ushort word_val
-)
-)
+                   ushort word_val)
 {
     ushort              read_wval;
 
@@ -12876,13 +12558,10 @@ AscWriteEEPWord(
     return (read_wval);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AscGetEEPConfig(
                    PortAddr iop_base,
-                   ASCEEP_CONFIG * cfg_buf, ushort bus_type
-)
-)
+                   ASCEEP_CONFIG * cfg_buf, ushort bus_type)
 {
     ushort              wval;
     ushort              sum;
@@ -12928,13 +12607,10 @@ AscGetEEPConfig(
     return (sum);
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscSetEEPConfigOnce(
                        PortAddr iop_base,
-                       ASCEEP_CONFIG * cfg_buf, ushort bus_type
-)
-)
+                       ASCEEP_CONFIG * cfg_buf, ushort bus_type)
 {
     int                 n_error;
     ushort              *wbuf;
@@ -13026,13 +12702,11 @@ AscSetEEPConfigOnce(
     return (n_error);
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AscSetEEPConfig(
                    PortAddr iop_base,
                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
 )
-)
 {
     int            retry;
     int            n_error;
@@ -13066,17 +12740,17 @@ AscAsyncFix(
     {
         if (!(asc_dvc->init_sdtr & tid_bits))
         {
-            if ((dvc_type == SCSI_TYPE_CDROM) &&
+            if ((dvc_type == TYPE_ROM) &&
                 (AscCompareString((uchar *) inq->vendor_id,
                     (uchar *) "HP ", 3) == 0))
             {
                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
             }
             asc_dvc->pci_fix_asyn_xfer |= tid_bits;
-            if ((dvc_type == SCSI_TYPE_PROC) ||
-                (dvc_type == SCSI_TYPE_SCANNER) ||
-                (dvc_type == SCSI_TYPE_CDROM) ||
-                (dvc_type == SCSI_TYPE_SASD))
+            if ((dvc_type == TYPE_PROCESSOR) ||
+                (dvc_type == TYPE_SCANNER) ||
+                (dvc_type == TYPE_ROM) ||
+                (dvc_type == TYPE_TAPE))
             {
                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
             }
@@ -14470,7 +14144,7 @@ STATIC ADV_DCNT _adv_asc38C1600_chksum =
  * unswapped on big-endian platforms.
  */
 STATIC ADVEEP_3550_CONFIG
-Default_3550_EEPROM_Config ASC_INITDATA = {
+Default_3550_EEPROM_Config __initdata = {
     ADV_EEPROM_BIOS_ENABLE,     /* cfg_lsw */
     0x0000,                     /* cfg_msw */
     0xFFFF,                     /* disc_enable */
@@ -14508,7 +14182,7 @@ Default_3550_EEPROM_Config ASC_INITDATA 
 };
 
 STATIC ADVEEP_3550_CONFIG
-ADVEEP_3550_Config_Field_IsChar ASC_INITDATA = {
+ADVEEP_3550_Config_Field_IsChar __initdata = {
     0,                          /* cfg_lsw */
     0,                          /* cfg_msw */
     0,                          /* -disc_enable */
@@ -14546,7 +14220,7 @@ ADVEEP_3550_Config_Field_IsChar ASC_INIT
 };
 
 STATIC ADVEEP_38C0800_CONFIG
-Default_38C0800_EEPROM_Config ASC_INITDATA = {
+Default_38C0800_EEPROM_Config __initdata = {
     ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
     0x0000,                     /* 01 cfg_msw */
     0xFFFF,                     /* 02 disc_enable */
@@ -14611,7 +14285,7 @@ Default_38C0800_EEPROM_Config ASC_INITDA
 };
 
 STATIC ADVEEP_38C0800_CONFIG
-ADVEEP_38C0800_Config_Field_IsChar ASC_INITDATA = {
+ADVEEP_38C0800_Config_Field_IsChar __initdata = {
     0,                          /* 00 cfg_lsw */
     0,                          /* 01 cfg_msw */
     0,                          /* 02 disc_enable */
@@ -14676,7 +14350,7 @@ ADVEEP_38C0800_Config_Field_IsChar ASC_I
 };
 
 STATIC ADVEEP_38C1600_CONFIG
-Default_38C1600_EEPROM_Config ASC_INITDATA = {
+Default_38C1600_EEPROM_Config __initdata = {
     ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
     0x0000,                     /* 01 cfg_msw */
     0xFFFF,                     /* 02 disc_enable */
@@ -14741,7 +14415,7 @@ Default_38C1600_EEPROM_Config ASC_INITDA
 };
 
 STATIC ADVEEP_38C1600_CONFIG
-ADVEEP_38C1600_Config_Field_IsChar ASC_INITDATA = {
+ADVEEP_38C1600_Config_Field_IsChar __initdata = {
     0,                          /* 00 cfg_lsw */
     0,                          /* 01 cfg_msw */
     0,                          /* 02 disc_enable */
@@ -14813,10 +14487,8 @@ ADVEEP_38C1600_Config_Field_IsChar ASC_I
  * For a non-fatal error return a warning code. If there are no warnings
  * then 0 is returned.
  */
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
-)
 {
     ushort      warn_code;
     AdvPortAddr iop_base;
@@ -16800,10 +16472,8 @@ AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc
  *
  * Note: Chip is stopped on entry.
  */
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
-)
 {
     AdvPortAddr         iop_base;
     ushort              warn_code;
@@ -16974,10 +16644,8 @@ AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
  *
  * Note: Chip is stopped on entry.
  */
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
-)
 {
     AdvPortAddr              iop_base;
     ushort                   warn_code;
@@ -17209,10 +16877,8 @@ AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_d
  *
  * Note: Chip is stopped on entry.
  */
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
 AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
-)
 {
     AdvPortAddr              iop_base;
     ushort                   warn_code;
@@ -17477,10 +17143,8 @@ AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_d
  *
  * Return a checksum based on the EEPROM configuration read.
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
-)
 {
     ushort              wval, chksum;
     ushort              *wbuf;
@@ -17525,11 +17189,9 @@ AdvGet3550EEPConfig(AdvPortAddr iop_base
  *
  * Return a checksum based on the EEPROM configuration read.
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
                        ADVEEP_38C0800_CONFIG *cfg_buf)
-)
 {
     ushort              wval, chksum;
     ushort              *wbuf;
@@ -17574,11 +17236,9 @@ AdvGet38C0800EEPConfig(AdvPortAddr iop_b
  *
  * Return a checksum based on the EEPROM configuration read.
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
                        ADVEEP_38C1600_CONFIG *cfg_buf)
-)
 {
     ushort              wval, chksum;
     ushort              *wbuf;
@@ -17621,10 +17281,8 @@ AdvGet38C1600EEPConfig(AdvPortAddr iop_b
 /*
  * Read the EEPROM from specified location
  */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
-)
 {
     AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
         ASC_EEP_CMD_READ | eep_word_addr);
@@ -17635,10 +17293,8 @@ AdvReadEEPWord(AdvPortAddr iop_base, int
 /*
  * Wait for EEPROM command to complete
  */
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
 AdvWaitEEPCmd(AdvPortAddr iop_base)
-)
 {
     int eep_delay_ms;
 
@@ -18290,7 +17946,7 @@ AdvISR(ADV_DVC_VAR *asc_dvc)
          * the device, otherwise may erroneously set *_able bits.
          */
         if (scsiq->done_status == QD_NO_ERROR &&
-            scsiq->cdb[0] == SCSICMD_Inquiry &&
+            scsiq->cdb[0] == INQUIRY &&
             scsiq->target_lun == 0 &&
             (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
                 == ADV_INQ_RTN_STD_INQUIRY_DATA)
diff -puN drivers/scsi/aha1542.c~bk-scsi drivers/scsi/aha1542.c
--- 25/drivers/scsi/aha1542.c~bk-scsi	2004-06-14 00:10:34.473067600 -0700
+++ 25-akpm/drivers/scsi/aha1542.c	2004-06-14 00:10:34.786020024 -0700
@@ -47,7 +47,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "aha1542.h"
 
 #define SCSI_BUF_PA(address)	isa_virt_to_bus(address)
diff -puN drivers/scsi/aha1740.c~bk-scsi drivers/scsi/aha1740.c
--- 25/drivers/scsi/aha1740.c~bk-scsi	2004-06-14 00:10:34.475067296 -0700
+++ 25-akpm/drivers/scsi/aha1740.c	2004-06-14 00:10:34.787019872 -0700
@@ -56,7 +56,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "aha1740.h"
 
 /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH
diff -puN drivers/scsi/aic7xxx/aic79xx_osm.h~bk-scsi drivers/scsi/aic7xxx/aic79xx_osm.h
--- 25/drivers/scsi/aic7xxx/aic79xx_osm.h~bk-scsi	2004-06-14 00:10:34.476067144 -0700
+++ 25-akpm/drivers/scsi/aic7xxx/aic79xx_osm.h	2004-06-14 00:10:34.788019720 -0700
@@ -68,7 +68,7 @@
 /* Core SCSI definitions */
 #define AIC_LIB_PREFIX ahd
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 /* Name space conflict with BSD queue macros */
 #ifdef LIST_HEAD
diff -puN drivers/scsi/aic7xxx/aic7xxx_osm.h~bk-scsi drivers/scsi/aic7xxx/aic7xxx_osm.h
--- 25/drivers/scsi/aic7xxx/aic7xxx_osm.h~bk-scsi	2004-06-14 00:10:34.478066840 -0700
+++ 25-akpm/drivers/scsi/aic7xxx/aic7xxx_osm.h	2004-06-14 00:10:34.789019568 -0700
@@ -85,7 +85,7 @@
 /* Core SCSI definitions */
 #define AIC_LIB_PREFIX ahc
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 /* Name space conflict with BSD queue macros */
 #ifdef LIST_HEAD
diff -puN drivers/scsi/aic7xxx/aiclib.c~bk-scsi drivers/scsi/aic7xxx/aiclib.c
--- 25/drivers/scsi/aic7xxx/aiclib.c~bk-scsi	2004-06-14 00:10:34.479066688 -0700
+++ 25-akpm/drivers/scsi/aic7xxx/aiclib.c	2004-06-14 00:10:34.790019416 -0700
@@ -36,7 +36,7 @@
 
 /* Core SCSI definitions */
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "aiclib.h"
 #include "cam.h"
 
diff -puN drivers/scsi/aic7xxx_old.c~bk-scsi drivers/scsi/aic7xxx_old.c
--- 25/drivers/scsi/aic7xxx_old.c~bk-scsi	2004-06-14 00:10:34.482066232 -0700
+++ 25-akpm/drivers/scsi/aic7xxx_old.c	2004-06-14 00:10:34.800017896 -0700
@@ -239,7 +239,7 @@
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "aic7xxx_old/aic7xxx.h"
 
 #include "aic7xxx_old/sequencer.h"
diff -puN drivers/scsi/amiga7xx.c~bk-scsi drivers/scsi/amiga7xx.c
--- 25/drivers/scsi/amiga7xx.c~bk-scsi	2004-06-14 00:10:34.484065928 -0700
+++ 25-akpm/drivers/scsi/amiga7xx.c	2004-06-14 00:10:34.800017896 -0700
@@ -25,7 +25,7 @@
 #include <asm/irq.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "53c7xx.h"
 #include "amiga7xx.h"
 
diff -puN drivers/scsi/atari_scsi.c~bk-scsi drivers/scsi/atari_scsi.c
--- 25/drivers/scsi/atari_scsi.c~bk-scsi	2004-06-14 00:10:34.485065776 -0700
+++ 25-akpm/drivers/scsi/atari_scsi.c	2004-06-14 00:10:34.802017592 -0700
@@ -102,7 +102,7 @@
 #include <asm/bitops.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "atari_scsi.h"
 #include "NCR5380.h"
 #include <asm/atari_stdma.h>
diff -puN drivers/scsi/atp870u.c~bk-scsi drivers/scsi/atp870u.c
--- 25/drivers/scsi/atp870u.c~bk-scsi	2004-06-14 00:10:34.488065320 -0700
+++ 25-akpm/drivers/scsi/atp870u.c	2004-06-14 00:10:34.803017440 -0700
@@ -35,7 +35,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "atp870u.h"
 
 /*
diff -puN drivers/scsi/blz1230.c~bk-scsi drivers/scsi/blz1230.c
--- 25/drivers/scsi/blz1230.c~bk-scsi	2004-06-14 00:10:34.489065168 -0700
+++ 25-akpm/drivers/scsi/blz1230.c	2004-06-14 00:10:34.804017288 -0700
@@ -28,7 +28,7 @@
 #include <linux/interrupt.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <linux/zorro.h>
diff -puN drivers/scsi/blz2060.c~bk-scsi drivers/scsi/blz2060.c
--- 25/drivers/scsi/blz2060.c~bk-scsi	2004-06-14 00:10:34.491064864 -0700
+++ 25-akpm/drivers/scsi/blz2060.c	2004-06-14 00:10:34.805017136 -0700
@@ -28,7 +28,7 @@
 #include <linux/interrupt.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <linux/zorro.h>
diff -puN drivers/scsi/BusLogic.c~bk-scsi drivers/scsi/BusLogic.c
--- 25/drivers/scsi/BusLogic.c~bk-scsi	2004-06-14 00:10:34.493064560 -0700
+++ 25-akpm/drivers/scsi/BusLogic.c	2004-06-14 00:10:34.749025648 -0700
@@ -48,7 +48,7 @@
 #include <asm/system.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "BusLogic.h"
 #include "FlashPoint.c"
 
diff -puN drivers/scsi/bvme6000.c~bk-scsi drivers/scsi/bvme6000.c
--- 25/drivers/scsi/bvme6000.c~bk-scsi	2004-06-14 00:10:34.494064408 -0700
+++ 25-akpm/drivers/scsi/bvme6000.c	2004-06-14 00:10:34.805017136 -0700
@@ -17,7 +17,7 @@
 #include <asm/irq.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "53c7xx.h"
 #include "bvme6000.h"
 
diff -puN drivers/scsi/constants.c~bk-scsi drivers/scsi/constants.c
--- 25/drivers/scsi/constants.c~bk-scsi	2004-06-14 00:10:34.496064104 -0700
+++ 25-akpm/drivers/scsi/constants.c	2004-06-14 00:10:34.807016832 -0700
@@ -12,7 +12,7 @@
 #include <linux/blkdev.h>
 #include <linux/kernel.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #define CONST_COMMAND   0x01
 #define CONST_STATUS    0x02
@@ -154,7 +154,7 @@ static void print_opcode(int opcode) {
 }
 #endif  
 
-void print_command (unsigned char *command) {
+void __scsi_print_command (unsigned char *command) {
     int i,s;
     print_opcode(command[0]);
     for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) 
@@ -173,7 +173,7 @@ void print_command (unsigned char *comma
  *	(e.g. "0x2" for Check Condition).
  **/
 void
-print_status(unsigned char scsi_status) {
+scsi_print_status(unsigned char scsi_status) {
 #if (CONSTANTS & CONST_STATUS)
 	const char * ccp;
 
@@ -1014,12 +1014,12 @@ print_sense_internal(const char *devclas
 #endif
 }
 
-void print_sense(const char *devclass, struct scsi_cmnd *cmd)
+void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd)
 {
 	print_sense_internal(devclass, cmd->sense_buffer, cmd->request);
 }
 
-void print_req_sense(const char *devclass, struct scsi_request *sreq)
+void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq)
 {
 	print_sense_internal(devclass, sreq->sr_sense_buffer, sreq->sr_request);
 }
@@ -1051,7 +1051,7 @@ static const char *extended_msgs[] = {
 #define NO_EXTENDED_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
 #endif /* (CONSTANTS & CONST_MSG) */
 
-int print_msg (const unsigned char *msg) {
+int scsi_print_msg (const unsigned char *msg) {
     int len = 0, i;
     if (msg[0] == EXTENDED_MESSAGE) {
 	len = 3 + msg[1];
@@ -1124,13 +1124,13 @@ int print_msg (const unsigned char *msg)
     return len;
 }
 
-void print_Scsi_Cmnd(struct scsi_cmnd *cmd) {
+void scsi_print_command(struct scsi_cmnd *cmd) {
     printk("scsi%d : destination target %d, lun %d\n", 
 	   cmd->device->host->host_no, 
 	   cmd->device->id, 
 	   cmd->device->lun);
     printk("        command = ");
-    print_command(cmd->cmnd);
+    __scsi_print_command(cmd->cmnd);
 }
 
 #if (CONSTANTS & CONST_HOST)
@@ -1139,7 +1139,7 @@ static const char * hostbyte_table[]={
 "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
 "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", NULL};
 
-void print_hostbyte(int scsiresult)
+void scsi_print_hostbyte(int scsiresult)
 {   static int maxcode=0;
     int i;
    
@@ -1155,7 +1155,7 @@ void print_hostbyte(int scsiresult)
     printk("(%s) ",hostbyte_table[host_byte(scsiresult)]);
 }
 #else
-void print_hostbyte(int scsiresult)
+void scsi_print_hostbyte(int scsiresult)
 {   printk("Hostbyte=0x%02x ",host_byte(scsiresult));
 }
 #endif
@@ -1170,7 +1170,7 @@ static const char * driversuggest_table[
 unknown,unknown,unknown, "SUGGEST_SENSE",NULL};
 
 
-void print_driverbyte(int scsiresult)
+void scsi_print_driverbyte(int scsiresult)
 {   static int driver_max=0,suggest_max=0;
     int i,dr=driver_byte(scsiresult)&DRIVER_MASK, 
 	su=(driver_byte(scsiresult)&SUGGEST_MASK)>>4;
@@ -1187,7 +1187,7 @@ void print_driverbyte(int scsiresult)
 	su<suggest_max ? driversuggest_table[su]:"invalid");
 }
 #else
-void print_driverbyte(int scsiresult)
+void scsi_print_driverbyte(int scsiresult)
 {   printk("Driverbyte=0x%02x ",driver_byte(scsiresult));
 }
 #endif
diff -puN drivers/scsi/cpqfcTScontrol.c~bk-scsi drivers/scsi/cpqfcTScontrol.c
--- 25/drivers/scsi/cpqfcTScontrol.c~bk-scsi	2004-06-14 00:10:34.497063952 -0700
+++ 25-akpm/drivers/scsi/cpqfcTScontrol.c	2004-06-14 00:10:34.809016528 -0700
@@ -45,7 +45,7 @@
 #include <linux/spinlock.h>
 
 #include "scsi.h"
-#include "hosts.h"   // Scsi_Host definition for INT handler
+#include <scsi/scsi_host.h>   // Scsi_Host definition for INT handler
 #include "cpqfcTSchip.h"
 #include "cpqfcTSstructs.h"
 
diff -puN drivers/scsi/cpqfcTSinit.c~bk-scsi drivers/scsi/cpqfcTSinit.c
--- 25/drivers/scsi/cpqfcTSinit.c~bk-scsi	2004-06-14 00:10:34.499063648 -0700
+++ 25-akpm/drivers/scsi/cpqfcTSinit.c	2004-06-14 00:10:34.810016376 -0700
@@ -51,7 +51,7 @@
 #include <asm/irq.h>
 #include <linux/spinlock.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
 #include "cpqfcTSchip.h"
 #include "cpqfcTSstructs.h"
@@ -1266,7 +1266,7 @@ static void QueLinkDownCmnd( CPQFCHBA *c
 
 
 
-// The file "hosts.h" says not to call scsi_done from
+// The file <scsi/scsi_host.h> says not to call scsi_done from
 // inside _queuecommand, so we'll do it from the heartbeat timer
 // (clarification: Turns out it's ok to call scsi_done from queuecommand 
 // for cases that don't go to the hardware like scsi cmds destined
diff -puN drivers/scsi/cpqfcTSworker.c~bk-scsi drivers/scsi/cpqfcTSworker.c
--- 25/drivers/scsi/cpqfcTSworker.c~bk-scsi	2004-06-14 00:10:34.502063192 -0700
+++ 25-akpm/drivers/scsi/cpqfcTSworker.c	2004-06-14 00:10:34.816015464 -0700
@@ -39,7 +39,7 @@
 #include <asm/dma.h>
 
 #include "scsi.h"
-#include "hosts.h"   // struct Scsi_Host definition for T handler
+#include <scsi/scsi_host.h>   // struct Scsi_Host definition for T handler
 #include "cpqfcTSchip.h"
 #include "cpqfcTSstructs.h"
 #include "cpqfcTStrigger.h"
diff -puN drivers/scsi/cyberstorm.c~bk-scsi drivers/scsi/cyberstorm.c
--- 25/drivers/scsi/cyberstorm.c~bk-scsi	2004-06-14 00:10:34.503063040 -0700
+++ 25-akpm/drivers/scsi/cyberstorm.c	2004-06-14 00:10:34.817015312 -0700
@@ -31,7 +31,7 @@
 #include <linux/interrupt.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <linux/zorro.h>
diff -puN drivers/scsi/cyberstormII.c~bk-scsi drivers/scsi/cyberstormII.c
--- 25/drivers/scsi/cyberstormII.c~bk-scsi	2004-06-14 00:10:34.504062888 -0700
+++ 25-akpm/drivers/scsi/cyberstormII.c	2004-06-14 00:10:34.817015312 -0700
@@ -27,7 +27,7 @@
 #include <linux/interrupt.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <linux/zorro.h>
diff -puN drivers/scsi/dc390.h~bk-scsi drivers/scsi/dc390.h
--- 25/drivers/scsi/dc390.h~bk-scsi	2004-06-14 00:10:34.506062584 -0700
+++ 25-akpm/drivers/scsi/dc390.h	2004-06-14 00:10:34.818015160 -0700
@@ -14,12 +14,9 @@
 #define DC390_H
 
 #include <linux/version.h>
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#endif
 
 #define DC390_BANNER "Tekram DC390/AM53C974"
-#define DC390_VERSION "2.1b 2004-04-13"
+#define DC390_VERSION "2.1d 2004-05-27"
 
 /* We don't have eh_abort_handler, eh_device_reset_handler, 
  * eh_bus_reset_handler, eh_host_reset_handler yet! 
@@ -32,14 +29,4 @@
 # define NEW_EH use_new_eh_code: 1,
 # define USE_NEW_EH
 #endif
-
-static int DC390_detect(Scsi_Host_Template *psht);
-static int DC390_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
-static int DC390_abort(Scsi_Cmnd *cmd);
-static int DC390_reset(Scsi_Cmnd *cmd);
-static int DC390_bios_param(struct scsi_device *sdev, struct block_device *dev,
-		sector_t capacity, int geom[]);
-
-static int DC390_release(struct Scsi_Host *);
-
 #endif /* DC390_H */
diff -puN drivers/scsi/dc395x.c~bk-scsi drivers/scsi/dc395x.c
--- 25/drivers/scsi/dc395x.c~bk-scsi	2004-06-14 00:10:34.508062280 -0700
+++ 25-akpm/drivers/scsi/dc395x.c	2004-06-14 00:10:34.821014704 -0700
@@ -53,7 +53,7 @@
 #include <linux/blkdev.h>
 #include <asm/io.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "dc395x.h"
 #include <scsi/scsicam.h>	/* needed for scsicam_bios_param */
 #include <linux/interrupt.h>
diff -puN drivers/scsi/dec_esp.c~bk-scsi drivers/scsi/dec_esp.c
--- 25/drivers/scsi/dec_esp.c~bk-scsi	2004-06-14 00:10:34.509062128 -0700
+++ 25-akpm/drivers/scsi/dec_esp.c	2004-06-14 00:10:34.822014552 -0700
@@ -29,7 +29,7 @@
 #include <linux/stat.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <asm/irq.h>
diff -puN drivers/scsi/dmx3191d.c~bk-scsi drivers/scsi/dmx3191d.c
--- 25/drivers/scsi/dmx3191d.c~bk-scsi	2004-06-14 00:10:34.511061824 -0700
+++ 25-akpm/drivers/scsi/dmx3191d.c	2004-06-14 00:10:34.822014552 -0700
@@ -34,7 +34,7 @@
 #include <linux/delay.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "dmx3191d.h"
 
diff -puN drivers/scsi/dpt_i2o.c~bk-scsi drivers/scsi/dpt_i2o.c
--- 25/drivers/scsi/dpt_i2o.c~bk-scsi	2004-06-14 00:10:34.513061520 -0700
+++ 25-akpm/drivers/scsi/dpt_i2o.c	2004-06-14 00:10:34.826013944 -0700
@@ -68,8 +68,11 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Dri
 #include <asm/pgtable.h>
 #include <asm/io.h>		/* for virt_to_bus, etc. */
 
-#include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 
 #include "dpt/dptsig.h"
 #include "dpti.h"
@@ -86,9 +89,9 @@ static dpt_sig_S DPTI_sig = {
 #elif defined(__ia64__)
 	PROC_INTEL, PROC_IA64,
 #elif defined(__sparc__)
-	PROC_ULTRASPARC,
+	PROC_ULTRASPARC, PROC_ULTRASPARC,
 #elif defined(__alpha__)
-	PROC_ALPHA ,
+	PROC_ALPHA, PROC_ALPHA,
 #else
 	(-1),(-1),
 #endif
@@ -173,7 +176,7 @@ static struct pci_device_id dptids[] = {
 };
 MODULE_DEVICE_TABLE(pci,dptids);
 
-static int adpt_detect(Scsi_Host_Template* sht)
+static int adpt_detect(struct scsi_host_template* sht)
 {
 	struct pci_dev *pDev = NULL;
 	adpt_hba* pHba;
@@ -362,7 +365,7 @@ static void adpt_inquiry(adpt_hba* pHba)
 }
 
 
-static int adpt_slave_configure(Scsi_Device * device)
+static int adpt_slave_configure(struct scsi_device * device)
 {
 	struct Scsi_Host *host = device->host;
 	adpt_hba* pHba;
@@ -378,7 +381,7 @@ static int adpt_slave_configure(Scsi_Dev
 	return 0;
 }
 
-static int adpt_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 {
 	adpt_hba* pHba = NULL;
 	struct adpt_device* pDev = NULL;	/* dpt per device information */
@@ -643,7 +646,7 @@ stop_output:
  *===========================================================================
  */
 
-static int adpt_abort(Scsi_Cmnd * cmd)
+static int adpt_abort(struct scsi_cmnd * cmd)
 {
 	adpt_hba* pHba = NULL;	/* host bus adapter structure */
 	struct adpt_device* dptdevice;	/* dpt per device information */
@@ -683,7 +686,7 @@ static int adpt_abort(Scsi_Cmnd * cmd)
 // This is the same for BLK and SCSI devices
 // NOTE this is wrong in the i2o.h definitions
 // This is not currently supported by our adapter but we issue it anyway
-static int adpt_device_reset(Scsi_Cmnd* cmd)
+static int adpt_device_reset(struct scsi_cmnd* cmd)
 {
 	adpt_hba* pHba;
 	u32 msg[4];
@@ -723,7 +726,7 @@ static int adpt_device_reset(Scsi_Cmnd* 
 
 #define I2O_HBA_BUS_RESET 0x87
 // This version of bus reset is called by the eh_error handler
-static int adpt_bus_reset(Scsi_Cmnd* cmd)
+static int adpt_bus_reset(struct scsi_cmnd* cmd)
 {
 	adpt_hba* pHba;
 	u32 msg[4];
@@ -745,7 +748,7 @@ static int adpt_bus_reset(Scsi_Cmnd* cmd
 }
 
 // This version of reset is called by the eh_error_handler
-static int adpt_reset(Scsi_Cmnd* cmd)
+static int adpt_reset(struct scsi_cmnd* cmd)
 {
 	adpt_hba* pHba;
 	int rcode;
@@ -860,7 +863,7 @@ static int adpt_reboot_event(struct noti
 #endif
 
 
-static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) 
+static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) 
 {
 
 	adpt_hba* pHba = NULL;
@@ -1997,7 +2000,7 @@ static int adpt_ioctl(struct inode *inod
 
 static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	Scsi_Cmnd* cmd;
+	struct scsi_cmnd* cmd;
 	adpt_hba* pHba = dev_id;
 	u32 m;
 	ulong reply;
@@ -2059,14 +2062,14 @@ static irqreturn_t adpt_isr(int irq, voi
 				status = I2O_POST_WAIT_OK;
 			}
 			if(!(context & 0x40000000)) {
-				cmd = (Scsi_Cmnd*) readl(reply+12); 
+				cmd = (struct scsi_cmnd*) readl(reply+12); 
 				if(cmd != NULL) {
 					printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
 				}
 			}
 			adpt_i2o_post_wait_complete(context, status);
 		} else { // SCSI message
-			cmd = (Scsi_Cmnd*) readl(reply+12); 
+			cmd = (struct scsi_cmnd*) readl(reply+12); 
 			if(cmd != NULL){
 				if(cmd->serial_number != 0) { // If not timedout
 					adpt_i2o_to_scsi(reply, cmd);
@@ -2083,7 +2086,7 @@ out:	if(pHba->host)
 	return IRQ_RETVAL(handled);
 }
 
-static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* d)
 {
 	int i;
 	u32 msg[MAX_MESSAGE_SIZE];
@@ -2108,16 +2111,16 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pH
 		 * cmd->cmnd[0] is an unsigned char
 		 */
 		switch(cmd->sc_data_direction){
-		case SCSI_DATA_READ:
+		case DMA_FROM_DEVICE:
 			scsidir  =0x40000000;	// DATA IN  (iop<--dev)
 			break;
-		case SCSI_DATA_WRITE:
+		case DMA_TO_DEVICE:
 			direction=0x04000000;	// SGL OUT
 			scsidir  =0x80000000;	// DATA OUT (iop-->dev)
 			break;
-		case SCSI_DATA_NONE:
+		case DMA_NONE:
 			break;
-		case SCSI_DATA_UNKNOWN:
+		case DMA_BIDIRECTIONAL:
 			scsidir  =0x40000000;	// DATA IN  (iop<--dev)
 			// Assume In - and continue;
 			break;
@@ -2156,7 +2159,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pH
 	if(cmd->use_sg) {
 		struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
 		int sg_count = pci_map_sg(pHba->pDev, sg, cmd->use_sg,
-                        scsi_to_pci_dma_dir(cmd->sc_data_direction));
+				cmd->sc_data_direction);
 
 
 		len = 0;
@@ -2184,7 +2187,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pH
 			*mptr++ = pci_map_single(pHba->pDev,
 				cmd->request_buffer,
 				cmd->request_bufflen,
-				scsi_to_pci_dma_dir(cmd->sc_data_direction));
+				cmd->sc_data_direction);
 		}
 	}
 	
@@ -2200,7 +2203,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pH
 }
 
 
-static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht)
+static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
 {
 	struct Scsi_Host *host = NULL;
 
@@ -2231,7 +2234,7 @@ static s32 adpt_scsi_register(adpt_hba* 
 }
 
 
-static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd)
+static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd)
 {
 	adpt_hba* pHba;
 	u32 hba_status;
@@ -2533,8 +2536,8 @@ static s32 adpt_i2o_reparse_lct(adpt_hba
 
 static void adpt_fail_posted_scbs(adpt_hba* pHba)
 {
-	Scsi_Cmnd* 	cmd = NULL;
-	Scsi_Device* 	d = NULL;
+	struct scsi_cmnd* 	cmd = NULL;
+	struct scsi_device* 	d = NULL;
 
 	shost_for_each_device(d, pHba->host) {
 		unsigned long flags;
@@ -3358,7 +3361,7 @@ static static void adpt_delay(int millis
 
 #endif
 
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
 	.name			= "dpt_i2o",
 	.proc_name		= "dpt_i2o",
 	.proc_info		= adpt_proc_info,
diff -puN drivers/scsi/dpti.h~bk-scsi drivers/scsi/dpti.h
--- 25/drivers/scsi/dpti.h~bk-scsi	2004-06-14 00:10:34.514061368 -0700
+++ 25-akpm/drivers/scsi/dpti.h	2004-06-14 00:10:34.827013792 -0700
@@ -37,19 +37,19 @@
  * SCSI interface function Prototypes
  */
 
-static int adpt_detect(Scsi_Host_Template * sht);
-static int adpt_queue(Scsi_Cmnd * cmd, void (*cmdcomplete) (Scsi_Cmnd *));
-static int adpt_abort(Scsi_Cmnd * cmd);
-static int adpt_reset(Scsi_Cmnd* cmd);
+static int adpt_detect(struct scsi_host_template * sht);
+static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *));
+static int adpt_abort(struct scsi_cmnd * cmd);
+static int adpt_reset(struct scsi_cmnd* cmd);
 static int adpt_release(struct Scsi_Host *host);
-static int adpt_slave_configure(Scsi_Device *);
+static int adpt_slave_configure(struct scsi_device *);
 
 static const char *adpt_info(struct Scsi_Host *pSHost);
 static int adpt_bios_param(struct scsi_device * sdev, struct block_device *dev,
 		sector_t, int geom[]);
 
-static int adpt_bus_reset(Scsi_Cmnd* cmd);
-static int adpt_device_reset(Scsi_Cmnd* cmd);
+static int adpt_bus_reset(struct scsi_cmnd* cmd);
+static int adpt_device_reset(struct scsi_cmnd* cmd);
 
 
 /*
@@ -198,7 +198,7 @@ struct adpt_device {
 	u8	state;
 	u16	tid;
 	struct i2o_device* pI2o_dev;
-	Scsi_Device *pScsi_dev;
+	struct scsi_device *pScsi_dev;
 };
 
 struct adpt_channel {
@@ -296,9 +296,9 @@ static s32 adpt_i2o_quiesce_hba(adpt_hba
 static s32 adpt_i2o_status_get(adpt_hba* pHba);
 static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
 static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
-static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* dptdevice);
-static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd);
-static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht);
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
+static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd);
+static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht);
 static s32 adpt_hba_reset(adpt_hba* pHba);
 static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
 static s32 adpt_rescan(adpt_hba* pHba);
@@ -308,7 +308,7 @@ static void adpt_i2o_delete_hba(adpt_hba
 static void adpt_inquiry(adpt_hba* pHba);
 static void adpt_fail_posted_scbs(adpt_hba* pHba);
 static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun);
-static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) ;
+static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ;
 static int adpt_i2o_online_hba(adpt_hba* pHba);
 static void adpt_i2o_post_wait_complete(u32, int);
 static int adpt_i2o_systab_send(adpt_hba* pHba);
diff -puN drivers/scsi/dtc.c~bk-scsi drivers/scsi/dtc.c
--- 25/drivers/scsi/dtc.c~bk-scsi	2004-06-14 00:10:34.516061064 -0700
+++ 25-akpm/drivers/scsi/dtc.c	2004-06-14 00:10:34.827013792 -0700
@@ -84,7 +84,7 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "dtc.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
diff -puN drivers/scsi/eata.c~bk-scsi drivers/scsi/eata.c
--- 25/drivers/scsi/eata.c~bk-scsi	2004-06-14 00:10:34.518060760 -0700
+++ 25-akpm/drivers/scsi/eata.c	2004-06-14 00:10:34.830013336 -0700
@@ -495,7 +495,7 @@
 #include <linux/spinlock.h>
 #include <scsi/scsicam.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <asm/dma.h>
 #include <asm/irq.h>
 
diff -puN drivers/scsi/eata_pio.c~bk-scsi drivers/scsi/eata_pio.c
--- 25/drivers/scsi/eata_pio.c~bk-scsi	2004-06-14 00:10:34.519060608 -0700
+++ 25-akpm/drivers/scsi/eata_pio.c	2004-06-14 00:10:34.831013184 -0700
@@ -63,7 +63,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsicam.h>
 
 #include "eata_generic.h"
@@ -593,14 +593,14 @@ static int get_pio_conf_PIO(u32 base, st
 	int z;
 	unsigned short *p;
 
-	if (check_region(base, 9))
-		return (FALSE);
+	if (!request_region(base, 9, "eata_pio"))
+		return 0;
 
 	memset(buf, 0, sizeof(struct get_conf));
 
 	while (inb(base + HA_RSTATUS) & HA_SBUSY)
 		if (--loop == 0)
-			return (FALSE);
+			goto fail;
 
 	DBG(DBG_PIO && DBG_PROBE, printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#x\n", base));
 	eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG);
@@ -609,30 +609,40 @@ static int get_pio_conf_PIO(u32 base, st
 	for (p = (unsigned short *) buf; (long) p <= ((long) buf + (sizeof(struct get_conf) / 2)); p++) {
 		while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
 			if (--loop == 0)
-				return (FALSE);
+				goto fail;
 
 		loop = HZ / 2;
 		*p = inw(base + HA_RDATA);
 	}
-	if (!(inb(base + HA_RSTATUS) & HA_SERROR)) {	/* Error ? */
-		if (htonl(EATA_SIGNATURE) == buf->signature) {
-			DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found " "at %#4x EATA Level: %x\n", base, (uint) (buf->version)));
-
-			while (inb(base + HA_RSTATUS) & HA_SDRQ)
-				inw(base + HA_RDATA);
-			if (ALLOW_DMA_BOARDS == FALSE) {
-				for (z = 0; z < MAXISA; z++)
-					if (base == ISAbases[z]) {
-						buf->IRQ = ISAirqs[z];
-						break;
-					}
+	if (inb(base + HA_RSTATUS) & HA_SERROR) {
+		DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during "
+					"transfer for HBA at %x\n", base));
+		goto fail;
+	}
+
+	if (htonl(EATA_SIGNATURE) != buf->signature)
+		goto fail;
+
+	DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found "
+				"at %#4x EATA Level: %x\n",
+				base, (uint) (buf->version)));
+
+	while (inb(base + HA_RSTATUS) & HA_SDRQ)
+		inw(base + HA_RDATA);
+
+	if (ALLOW_DMA_BOARDS == FALSE) {
+		for (z = 0; z < MAXISA; z++)
+			if (base == ISAbases[z]) {
+				buf->IRQ = ISAirqs[z];
+				break;
 			}
-			return (TRUE);
-		}
-	} else {
-		DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer " "for HBA at %x\n", base));
 	}
-	return (FALSE);
+
+	return 1;
+
+ fail:
+	release_region(base, 9);
+	return 0;
 }
 
 static void print_pio_config(struct get_conf *gc)
@@ -689,23 +699,19 @@ static int register_pio_HBA(long base, s
 
 	if ((buff = get_pio_board_data((uint) base, gc->IRQ, gc->scsi_id[3], cplen = (htonl(gc->cplen) + 1) / 2, cppadlen = (htons(gc->cppadlen) + 1) / 2)) == NULL) {
 		printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", (unsigned long) base);
-		return (FALSE);
+		return 0;
 	}
 
 	if (print_selftest(base) == FALSE && ALLOW_DMA_BOARDS == FALSE) {
 		printk("HBA at %#lx failed while performing self test & setup.\n", (unsigned long) base);
-		return (FALSE);
+		return 0;
 	}
 
-	request_region(base, 8, "eata_pio");
-
 	size = sizeof(hostdata) + (sizeof(struct eata_ccb) * ntohs(gc->queuesiz));
 
 	sh = scsi_register(tpnt, size);
-	if (sh == NULL) {
-		release_region(base, 8);
-		return FALSE;
-	}
+	if (sh == NULL)
+		return 0;
 
 	if (!reg_IRQ[gc->IRQ]) {	/* Interrupt already registered ? */
 		if (!request_irq(gc->IRQ, do_eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO", sh)) {
@@ -714,14 +720,12 @@ static int register_pio_HBA(long base, s
 				reg_IRQL[gc->IRQ] = TRUE;	/* IRQ is edge triggered */
 		} else {
 			printk("Couldn't allocate IRQ %d, Sorry.\n", gc->IRQ);
-			release_region(base, 8);
-			return (FALSE);
+			return 0;
 		}
 	} else {		/* More than one HBA on this IRQ */
 		if (reg_IRQL[gc->IRQ] == TRUE) {
 			printk("Can't support more than one HBA on this IRQ,\n" "  if the IRQ is edge triggered. Sorry.\n");
-			release_region(base, 8);
-			return (FALSE);
+			return 0;
 		} else
 			reg_IRQ[gc->IRQ]++;
 	}
@@ -780,7 +784,7 @@ static int register_pio_HBA(long base, s
 	sh->unique_id = base;
 	sh->base = base;
 	sh->io_port = base;
-	sh->n_io_port = 8;
+	sh->n_io_port = 9;
 	sh->irq = gc->IRQ;
 	sh->dma_channel = PIO;
 	sh->this_id = gc->scsi_id[3];
@@ -816,12 +820,14 @@ static void find_pio_ISA(struct get_conf
 	int i;
 
 	for (i = 0; i < MAXISA; i++) {
-		if (ISAbases[i]) {
-			if (get_pio_conf_PIO(ISAbases[i], buf) == TRUE) {
-				register_pio_HBA(ISAbases[i], buf, tpnt);
-			}
+		if (!ISAbases[i])
+			continue;
+		if (!get_pio_conf_PIO(ISAbases[i], buf))
+			continue;
+		if (!register_pio_HBA(ISAbases[i], buf, tpnt))
+			release_region(ISAbases[i], 9);
+		else
 			ISAbases[i] = 0;
-		}
 	}
 	return;
 }
@@ -847,12 +853,15 @@ static void find_pio_EISA(struct get_con
 			if (((pal1 == 0x12) && (pal2 == 0x14)) || ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) || ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) {
 				DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: " "%x %x %x \n", (int) pal1, (int) pal2, (int) pal3));
 #endif
-				if (get_pio_conf_PIO(base, buf) == TRUE) {
+				if (get_pio_conf_PIO(base, buf)) {
 					DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf));
 					if (buf->IRQ) {
-						register_pio_HBA(base, buf, tpnt);
-					} else
+						if (!register_pio_HBA(base, buf, tpnt))
+							release_region(base, 9);
+					} else {
 						printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA " "removed from list\n");
+						release_region(base, 9);
+					}
 				}
 				/* Nothing found here so we take it from the list */
 				EISAbases[i] = 0;
@@ -889,16 +898,21 @@ static void find_pio_PCI(struct get_conf
 		base += 0x10;	/* Now, THIS is the real address */
 		if (base != 0x1f8) {
 			/* We didn't find it in the primary search */
-			if (get_pio_conf_PIO(base, buf) == TRUE) {
-				if (buf->FORCADR)	/* If the address is forced */
+			if (get_pio_conf_PIO(base, buf)) {
+				if (buf->FORCADR) {	/* If the address is forced */
+					release_region(base, 9);
 					continue;	/* we'll find it later      */
+				}
 
 				/* OK. We made it till here, so we can go now  
 				 * and register it. We  only have to check and 
 				 * eventually remove it from the EISA and ISA list 
 				 */
 
-				register_pio_HBA(base, buf, tpnt);
+				if (!register_pio_HBA(base, buf, tpnt)) {
+					release_region(base, 9);
+					continue;
+				}
 
 				if (base < 0x1000) {
 					for (x = 0; x < MAXISA; ++x) {
diff -puN drivers/scsi/esp.c~bk-scsi drivers/scsi/esp.c
--- 25/drivers/scsi/esp.c~bk-scsi	2004-06-14 00:10:34.521060304 -0700
+++ 25-akpm/drivers/scsi/esp.c	2004-06-14 00:10:34.835012576 -0700
@@ -27,6 +27,8 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 
+#include "scsi.h"
+#include <scsi/scsi_host.h>
 #include "esp.h"
 
 #include <asm/sbus.h>
diff -puN drivers/scsi/fastlane.c~bk-scsi drivers/scsi/fastlane.c
--- 25/drivers/scsi/fastlane.c~bk-scsi	2004-06-14 00:10:34.523060000 -0700
+++ 25-akpm/drivers/scsi/fastlane.c	2004-06-14 00:10:34.835012576 -0700
@@ -36,7 +36,7 @@
 #include <linux/interrupt.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <linux/zorro.h>
diff -puN drivers/scsi/fcal.c~bk-scsi drivers/scsi/fcal.c
--- 25/drivers/scsi/fcal.c~bk-scsi	2004-06-14 00:10:34.524059848 -0700
+++ 25-akpm/drivers/scsi/fcal.c	2004-06-14 00:10:34.836012424 -0700
@@ -21,7 +21,7 @@
 #include <asm/irq.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "../fc4/fcp_impl.h"
 #include "fcal.h"
 
diff -puN drivers/scsi/fd_mcs.c~bk-scsi drivers/scsi/fd_mcs.c
--- 25/drivers/scsi/fd_mcs.c~bk-scsi	2004-06-14 00:10:34.525059696 -0700
+++ 25-akpm/drivers/scsi/fd_mcs.c	2004-06-14 00:10:34.837012272 -0700
@@ -93,7 +93,7 @@
 #include <asm/system.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "fd_mcs.h"
 
 #define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>"
diff -puN drivers/scsi/fdomain.c~bk-scsi drivers/scsi/fdomain.c
--- 25/drivers/scsi/fdomain.c~bk-scsi	2004-06-14 00:10:34.527059392 -0700
+++ 25-akpm/drivers/scsi/fdomain.c	2004-06-14 00:10:34.839011968 -0700
@@ -284,7 +284,7 @@
 #include <asm/system.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 MODULE_AUTHOR("Rickard E. Faith");
 MODULE_DESCRIPTION("Future domain SCSI driver");
diff -puN drivers/scsi/g_NCR5380.c~bk-scsi drivers/scsi/g_NCR5380.c
--- 25/drivers/scsi/g_NCR5380.c~bk-scsi	2004-06-14 00:10:34.529059088 -0700
+++ 25-akpm/drivers/scsi/g_NCR5380.c	2004-06-14 00:10:34.840011816 -0700
@@ -107,7 +107,7 @@
 #include <linux/sched.h>
 #include <linux/blkdev.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "g_NCR5380.h"
 #include "NCR5380.h"
 #include <linux/stat.h>
diff -puN drivers/scsi/gvp11.c~bk-scsi drivers/scsi/gvp11.c
--- 25/drivers/scsi/gvp11.c~bk-scsi	2004-06-14 00:10:34.530058936 -0700
+++ 25-akpm/drivers/scsi/gvp11.c	2004-06-14 00:10:34.840011816 -0700
@@ -16,7 +16,7 @@
 #include <linux/spinlock.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "wd33c93.h"
 #include "gvp11.h"
 
diff -puN drivers/scsi/i60uscsi.c~bk-scsi drivers/scsi/i60uscsi.c
--- 25/drivers/scsi/i60uscsi.c~bk-scsi	2004-06-14 00:10:34.532058632 -0700
+++ 25-akpm/drivers/scsi/i60uscsi.c	2004-06-14 00:10:34.841011664 -0700
@@ -81,7 +81,7 @@
 #include <asm/io.h>
 #include <linux/blkdev.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "inia100.h"
 
 #define JIFFIES_TO_MS(t) ((t) * 1000 / HZ)
diff -puN drivers/scsi/ibmmca.c~bk-scsi drivers/scsi/ibmmca.c
--- 25/drivers/scsi/ibmmca.c~bk-scsi	2004-06-14 00:10:34.534058328 -0700
+++ 25-akpm/drivers/scsi/ibmmca.c	2004-06-14 00:10:34.843011360 -0700
@@ -45,7 +45,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "ibmmca.h"
 
 /* current version of this driver-source: */
diff -puN drivers/scsi/ide-scsi.c~bk-scsi drivers/scsi/ide-scsi.c
--- 25/drivers/scsi/ide-scsi.c~bk-scsi	2004-06-14 00:10:34.536058024 -0700
+++ 25-akpm/drivers/scsi/ide-scsi.c	2004-06-14 00:10:34.844011208 -0700
@@ -51,7 +51,7 @@
 #include <asm/uaccess.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/sg.h>
 
 #define IDESCSI_DEBUG_LOG		0
diff -puN drivers/scsi/imm.h~bk-scsi drivers/scsi/imm.h
--- 25/drivers/scsi/imm.h~bk-scsi	2004-06-14 00:10:34.537057872 -0700
+++ 25-akpm/drivers/scsi/imm.h	2004-06-14 00:10:34.845011056 -0700
@@ -79,7 +79,7 @@
 #include  <linux/interrupt.h>
 
 #include  <asm/io.h>
-#include  "hosts.h"
+#include  <scsi/scsi_host.h>
 /* batteries not included :-) */
 
 /*
diff -puN drivers/scsi/in2000.c~bk-scsi drivers/scsi/in2000.c
--- 25/drivers/scsi/in2000.c~bk-scsi	2004-06-14 00:10:34.539057568 -0700
+++ 25-akpm/drivers/scsi/in2000.c	2004-06-14 00:10:34.847010752 -0700
@@ -126,7 +126,7 @@
 #include <asm/system.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #define IN2000_VERSION    "1.33-2.5"
 #define IN2000_DATE       "2002/11/03"
diff -puN drivers/scsi/ini9100u.c~bk-scsi drivers/scsi/ini9100u.c
--- 25/drivers/scsi/ini9100u.c~bk-scsi	2004-06-14 00:10:34.540057416 -0700
+++ 25-akpm/drivers/scsi/ini9100u.c	2004-06-14 00:10:34.848010600 -0700
@@ -136,7 +136,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "ini9100u.h"
 
 #ifdef DEBUG_i91u
diff -puN drivers/scsi/ipr.c~bk-scsi drivers/scsi/ipr.c
--- 25/drivers/scsi/ipr.c~bk-scsi	2004-06-14 00:10:34.542057112 -0700
+++ 25-akpm/drivers/scsi/ipr.c	2004-06-14 00:10:34.852009992 -0700
@@ -2884,6 +2884,7 @@ static int ipr_slave_alloc(struct scsi_d
 		    (res->cfgte.res_addr.lun == sdev->lun)) {
 			res->sdev = sdev;
 			res->add_to_ml = 0;
+			res->in_erp = 0;
 			sdev->hostdata = res;
 			res->needs_sync_complete = 1;
 			break;
@@ -3435,8 +3436,10 @@ static void ipr_erp_done(struct ipr_cmnd
 		       SCSI_SENSE_BUFFERSIZE);
 	}
 
-	if (res)
+	if (res) {
 		res->needs_sync_complete = 1;
+		res->in_erp = 0;
+	}
 	ipr_unmap_sglist(ioa_cfg, ipr_cmd);
 	list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
 	scsi_cmd->scsi_done(scsi_cmd);
@@ -3479,6 +3482,12 @@ static void ipr_reinit_ipr_cmnd_for_erp(
 static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd)
 {
 	struct ipr_cmd_pkt *cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
+	u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+
+	if (IPR_IOASC_SENSE_KEY(ioasc) > 0) {
+		ipr_erp_done(ipr_cmd);
+		return;
+	}
 
 	ipr_reinit_ipr_cmnd_for_erp(ipr_cmd);
 
@@ -3756,6 +3765,7 @@ static void ipr_erp_start(struct ipr_ioa
 			ipr_erp_cancel_all(ipr_cmd);
 			return;
 		}
+		res->needs_sync_complete = 1;
 		break;
 	case IPR_IOASC_NR_INIT_CMD_REQUIRED:
 		break;
@@ -4808,6 +4818,7 @@ static int ipr_reset_enable_ioa(struct i
 	ipr_cmd->timer.data = (unsigned long) ipr_cmd;
 	ipr_cmd->timer.expires = jiffies + IPR_OPERATIONAL_TIMEOUT;
 	ipr_cmd->timer.function = (void (*)(unsigned long))ipr_timeout;
+	ipr_cmd->done = ipr_reset_ioa_job;
 	add_timer(&ipr_cmd->timer);
 	list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
 
diff -puN drivers/scsi/ipr.h~bk-scsi drivers/scsi/ipr.h
--- 25/drivers/scsi/ipr.h~bk-scsi	2004-06-14 00:10:34.544056808 -0700
+++ 25-akpm/drivers/scsi/ipr.h	2004-06-14 00:10:34.853009840 -0700
@@ -36,8 +36,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.0.7"
-#define IPR_DRIVER_DATE "(May 21, 2004)"
+#define IPR_DRIVER_VERSION "2.0.9"
+#define IPR_DRIVER_DATE "(May 26, 2004)"
 
 /*
  * IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing
diff -puN drivers/scsi/ips.c~bk-scsi drivers/scsi/ips.c
--- 25/drivers/scsi/ips.c~bk-scsi	2004-06-14 00:10:34.546056504 -0700
+++ 25-akpm/drivers/scsi/ips.c	2004-06-14 00:10:34.859008928 -0700
@@ -176,7 +176,7 @@
 #include <scsi/sg.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "ips.h"
 
 #include <linux/module.h>
diff -puN drivers/scsi/jazz_esp.c~bk-scsi drivers/scsi/jazz_esp.c
--- 25/drivers/scsi/jazz_esp.c~bk-scsi	2004-06-14 00:10:34.548056200 -0700
+++ 25-akpm/drivers/scsi/jazz_esp.c	2004-06-14 00:10:34.860008776 -0700
@@ -16,7 +16,7 @@
 #include <linux/stat.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <asm/irq.h>
diff -puN drivers/scsi/Kconfig~bk-scsi drivers/scsi/Kconfig
--- 25/drivers/scsi/Kconfig~bk-scsi	2004-06-14 00:10:34.550055896 -0700
+++ 25-akpm/drivers/scsi/Kconfig	2004-06-14 00:10:34.752025192 -0700
@@ -227,7 +227,7 @@ config SCSI_DECSII
 	depends on DECSTATION && SCSI
 
 config BLK_DEV_3W_XXXX_RAID
-	tristate "3ware Hardware ATA-RAID support"
+	tristate "3ware 5/6/7/8xxx ATA-RAID support"
 	depends on PCI && SCSI
 	help
 	  3ware is the only hardware ATA-Raid product in Linux to date.
@@ -239,6 +239,17 @@ config BLK_DEV_3W_XXXX_RAID
 	  Please read the comments at the top of
 	  <file:drivers/scsi/3w-xxxx.c>.
 
+config SCSI_3W_9XXX
+	tristate "3ware 9xxx SATA-RAID support"
+	depends on PCI && SCSI
+	help
+	  This driver supports the 9000 series 3ware SATA-RAID cards.
+
+	  <http://www.amcc.com>
+
+	  Please read the comments at the top of
+	  <file:drivers/scsi/3w-9xxx.c>.
+
 config SCSI_7000FASST
 	tristate "7000FASST SCSI support"
 	depends on ISA && SCSI
@@ -478,9 +489,7 @@ config SCSI_BUSLOGIC
 	  Adapters. Consult the SCSI-HOWTO, available from
 	  <http://www.tldp.org/docs.html#howto>, and the files
 	  <file:Documentation/scsi/BusLogic.txt> and
-	  <file:Documentation/scsi/FlashPoint.txt> for more information. If this
-	  driver does not work correctly without modification, please contact
-	  the author, Leonard N. Zubkoff, by email to lnz@dandelion.com.
+	  <file:Documentation/scsi/FlashPoint.txt> for more information.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called BusLogic.
diff -puN drivers/scsi/lasi700.c~bk-scsi drivers/scsi/lasi700.c
--- 25/drivers/scsi/lasi700.c~bk-scsi	2004-06-14 00:10:34.551055744 -0700
+++ 25-akpm/drivers/scsi/lasi700.c	2004-06-14 00:10:34.861008624 -0700
@@ -49,8 +49,7 @@
 #include <asm/parisc-device.h>
 #include <asm/delay.h>
 
-#include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "lasi700.h"
 #include "53c700.h"
@@ -65,7 +64,7 @@ static struct parisc_device_id lasi700_i
 	{ 0 }
 };
 
-static Scsi_Host_Template lasi700_template = {
+static struct scsi_host_template lasi700_template = {
 	.name		= "LASI SCSI 53c700",
 	.proc_name	= "lasi700",
 	.this_id	= 7,
diff -puN drivers/scsi/mac_esp.c~bk-scsi drivers/scsi/mac_esp.c
--- 25/drivers/scsi/mac_esp.c~bk-scsi	2004-06-14 00:10:34.552055592 -0700
+++ 25-akpm/drivers/scsi/mac_esp.c	2004-06-14 00:10:34.862008472 -0700
@@ -26,7 +26,7 @@
 #include <linux/interrupt.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <asm/io.h>
diff -puN drivers/scsi/mac_scsi.c~bk-scsi drivers/scsi/mac_scsi.c
--- 25/drivers/scsi/mac_scsi.c~bk-scsi	2004-06-14 00:10:34.561054224 -0700
+++ 25-akpm/drivers/scsi/mac_scsi.c	2004-06-14 00:10:34.862008472 -0700
@@ -52,7 +52,7 @@
 #include <asm/mac_via.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "mac_scsi.h"
 #include "NCR5380.h"
 
diff -puN drivers/scsi/Makefile~bk-scsi drivers/scsi/Makefile
--- 25/drivers/scsi/Makefile~bk-scsi	2004-06-14 00:10:34.563053920 -0700
+++ 25-akpm/drivers/scsi/Makefile	2004-06-14 00:10:34.753025040 -0700
@@ -109,6 +109,7 @@ obj-$(CONFIG_SCSI_MAC53C94)	+= mac53c94.
 obj-$(CONFIG_SCSI_PLUTO)	+= pluto.o
 obj-$(CONFIG_SCSI_DECNCR)	+= NCR53C9x.o	dec_esp.o
 obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
+obj-$(CONFIG_SCSI_3W_9XXX)	+= 3w-9xxx.o
 obj-$(CONFIG_SCSI_PPA)		+= ppa.o
 obj-$(CONFIG_SCSI_IMM)		+= imm.o
 obj-$(CONFIG_JAZZ_ESP)		+= NCR53C9x.o	jazz_esp.o
diff -puN drivers/scsi/mca_53c9x.c~bk-scsi drivers/scsi/mca_53c9x.c
--- 25/drivers/scsi/mca_53c9x.c~bk-scsi	2004-06-14 00:10:34.564053768 -0700
+++ 25-akpm/drivers/scsi/mca_53c9x.c	2004-06-14 00:10:34.863008320 -0700
@@ -43,7 +43,7 @@
 #include <linux/mca-legacy.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <asm/dma.h>
diff -puN drivers/scsi/megaraid.c~bk-scsi drivers/scsi/megaraid.c
--- 25/drivers/scsi/megaraid.c~bk-scsi	2004-06-14 00:10:34.566053464 -0700
+++ 25-akpm/drivers/scsi/megaraid.c	2004-06-14 00:10:34.866007864 -0700
@@ -49,7 +49,7 @@
 #include <scsi/scsicam.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "megaraid.h"
 
@@ -4068,7 +4068,6 @@ mega_support_ext_cdb(adapter_t *adapter)
 static int
 mega_del_logdrv(adapter_t *adapter, int logdrv)
 {
-	DECLARE_WAIT_QUEUE_HEAD(wq);
 	unsigned long flags;
 	scb_t *scb;
 	int rval;
@@ -4083,11 +4082,9 @@ mega_del_logdrv(adapter_t *adapter, int 
 	 * Wait till all the issued commands are complete and there are no
 	 * commands in the pending queue
 	 */
-	while( atomic_read(&adapter->pend_cmds) > 0 ||
-			!list_empty(&adapter->pending_list) ) {
-
-		sleep_on_timeout( &wq, 1*HZ );	/* sleep for 1s */
-	}
+	while (atomic_read(&adapter->pend_cmds) > 0 ||
+	       !list_empty(&adapter->pending_list))
+		msleep(1000);	/* sleep for 1s */
 
 	rval = mega_do_del_logdrv(adapter, logdrv);
 
@@ -4612,6 +4609,26 @@ megaraid_probe_one(struct pci_dev *pdev,
 	pci_dev_func = pdev->devfn;
 
 	/*
+	 * The megaraid3 stuff reports the ID of the Intel part which is not
+	 * remotely specific to the megaraid
+	 */
+	if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
+		u16 magic;
+		/*
+		 * Don't fall over the Compaq management cards using the same
+		 * PCI identifier
+		 */
+		if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ &&
+		    pdev->subsystem_device == 0xC000)
+		   	return -ENODEV;
+		/* Now check the magic signature byte */
+		pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
+		if (magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE)
+			return -ENODEV;
+		/* Ok it is probably a megaraid */
+	}
+
+	/*
 	 * For these vendor and device ids, signature offsets are not
 	 * valid and 64 bit is implicit
 	 */
diff -puN drivers/scsi/mvme147.c~bk-scsi drivers/scsi/mvme147.c
--- 25/drivers/scsi/mvme147.c~bk-scsi	2004-06-14 00:10:34.568053160 -0700
+++ 25-akpm/drivers/scsi/mvme147.c	2004-06-14 00:10:34.867007712 -0700
@@ -11,7 +11,7 @@
 #include <asm/irq.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "wd33c93.h"
 #include "mvme147.h"
 
diff -puN drivers/scsi/mvme16x.c~bk-scsi drivers/scsi/mvme16x.c
--- 25/drivers/scsi/mvme16x.c~bk-scsi	2004-06-14 00:10:34.569053008 -0700
+++ 25-akpm/drivers/scsi/mvme16x.c	2004-06-14 00:10:34.867007712 -0700
@@ -15,7 +15,7 @@
 #include <asm/irq.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "53c7xx.h"
 #include "mvme16x.h"
 
diff -puN drivers/scsi/NCR53c406a.c~bk-scsi drivers/scsi/NCR53c406a.c
--- 25/drivers/scsi/NCR53c406a.c~bk-scsi	2004-06-14 00:10:34.571052704 -0700
+++ 25-akpm/drivers/scsi/NCR53c406a.c	2004-06-14 00:10:34.757024432 -0700
@@ -54,7 +54,7 @@
 #include <linux/blkdev.h>
 #include <linux/spinlock.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 /* ============================================================= */
 
diff -puN drivers/scsi/ncr53c8xx.c~bk-scsi drivers/scsi/ncr53c8xx.c
--- 25/drivers/scsi/ncr53c8xx.c~bk-scsi	2004-06-14 00:10:34.573052400 -0700
+++ 25-akpm/drivers/scsi/ncr53c8xx.c	2004-06-14 00:10:34.873006800 -0700
@@ -138,7 +138,7 @@
 #include <asm/system.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "ncr53c8xx.h"
 
diff -puN drivers/scsi/NCR53C9x.c~bk-scsi drivers/scsi/NCR53C9x.c
--- 25/drivers/scsi/NCR53C9x.c~bk-scsi	2004-06-14 00:10:34.575052096 -0700
+++ 25-akpm/drivers/scsi/NCR53C9x.c	2004-06-14 00:10:34.756024584 -0700
@@ -36,7 +36,7 @@
 #include <linux/init.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <asm/system.h>
diff -puN drivers/scsi/NCR_D700.c~bk-scsi drivers/scsi/NCR_D700.c
--- 25/drivers/scsi/NCR_D700.c~bk-scsi	2004-06-14 00:10:34.576051944 -0700
+++ 25-akpm/drivers/scsi/NCR_D700.c	2004-06-14 00:10:34.757024432 -0700
@@ -98,9 +98,7 @@
 #include <linux/module.h>
 #include <linux/mca.h>
 #include <asm/io.h>
-
-#include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "53c700.h"
 #include "NCR_D700.h"
@@ -156,7 +154,7 @@ param_setup(char *string)
 
 /* Host template.  The 53c700 routine NCR_700_detect will
  * fill in all of the missing routines */
-static Scsi_Host_Template NCR_D700_driver_template = {
+static struct scsi_host_template NCR_D700_driver_template = {
 	.module			= THIS_MODULE,
 	.name			= "NCR Dual 700 MCA",
 	.proc_name		= "NCR_D700",
diff -puN drivers/scsi/NCR_Q720.c~bk-scsi drivers/scsi/NCR_Q720.c
--- 25/drivers/scsi/NCR_Q720.c~bk-scsi	2004-06-14 00:10:34.578051640 -0700
+++ 25-akpm/drivers/scsi/NCR_Q720.c	2004-06-14 00:10:34.758024280 -0700
@@ -16,7 +16,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "ncr53c8xx.h"
 
diff -puN drivers/scsi/nsp32.c~bk-scsi drivers/scsi/nsp32.c
--- 25/drivers/scsi/nsp32.c~bk-scsi	2004-06-14 00:10:34.580051336 -0700
+++ 25-akpm/drivers/scsi/nsp32.c	2004-06-14 00:10:34.877006192 -0700
@@ -44,7 +44,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi.h>
 
diff -puN drivers/scsi/oktagon_esp.c~bk-scsi drivers/scsi/oktagon_esp.c
--- 25/drivers/scsi/oktagon_esp.c~bk-scsi	2004-06-14 00:10:34.581051184 -0700
+++ 25-akpm/drivers/scsi/oktagon_esp.c	2004-06-14 00:10:34.878006040 -0700
@@ -29,7 +29,7 @@
 
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <linux/zorro.h>
diff -puN drivers/scsi/osst.c~bk-scsi drivers/scsi/osst.c
--- 25/drivers/scsi/osst.c~bk-scsi	2004-06-14 00:10:34.583050880 -0700
+++ 25-akpm/drivers/scsi/osst.c	2004-06-14 00:10:34.882005432 -0700
@@ -61,7 +61,7 @@ const char * osst_version = "0.99.1";
 #define OSST_DEB_MSG  KERN_NOTICE
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_ioctl.h>
 
diff -puN drivers/scsi/pas16.c~bk-scsi drivers/scsi/pas16.c
--- 25/drivers/scsi/pas16.c~bk-scsi	2004-06-14 00:10:34.585050576 -0700
+++ 25-akpm/drivers/scsi/pas16.c	2004-06-14 00:10:34.883005280 -0700
@@ -125,7 +125,7 @@
 #include <linux/init.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "pas16.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
diff -puN drivers/scsi/pc980155.c~bk-scsi drivers/scsi/pc980155.c
--- 25/drivers/scsi/pc980155.c~bk-scsi	2004-06-14 00:10:34.586050424 -0700
+++ 25-akpm/drivers/scsi/pc980155.c	2004-06-14 00:10:34.883005280 -0700
@@ -20,7 +20,7 @@
 #include <asm/dma.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "wd33c93.h"
 #include "pc980155.h"
 
diff -puN drivers/scsi/pci2000.c~bk-scsi drivers/scsi/pci2000.c
--- 25/drivers/scsi/pci2000.c~bk-scsi	2004-06-14 00:10:34.588050120 -0700
+++ 25-akpm/drivers/scsi/pci2000.c	2004-06-14 00:10:34.884005128 -0700
@@ -54,7 +54,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "pci2000.h"
 #include "psi_roy.h"
 
diff -puN drivers/scsi/pci2220i.c~bk-scsi drivers/scsi/pci2220i.c
--- 25/drivers/scsi/pci2220i.c~bk-scsi	2004-06-14 00:10:34.590049816 -0700
+++ 25-akpm/drivers/scsi/pci2220i.c	2004-06-14 00:10:34.887004672 -0700
@@ -59,7 +59,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "pci2220i.h"
 #include "psi_dale.h"
 
diff -puN drivers/scsi/pcmcia/aha152x_stub.c~bk-scsi drivers/scsi/pcmcia/aha152x_stub.c
--- 25/drivers/scsi/pcmcia/aha152x_stub.c~bk-scsi	2004-06-14 00:10:34.592049512 -0700
+++ 25-akpm/drivers/scsi/pcmcia/aha152x_stub.c	2004-06-14 00:10:34.887004672 -0700
@@ -47,7 +47,7 @@
 #include <scsi/scsi_ioctl.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "aha152x.h"
 
 #include <pcmcia/version.h>
diff -puN drivers/scsi/pcmcia/fdomain_stub.c~bk-scsi drivers/scsi/pcmcia/fdomain_stub.c
--- 25/drivers/scsi/pcmcia/fdomain_stub.c~bk-scsi	2004-06-14 00:10:34.593049360 -0700
+++ 25-akpm/drivers/scsi/pcmcia/fdomain_stub.c	2004-06-14 00:10:34.888004520 -0700
@@ -44,7 +44,7 @@
 #include <scsi/scsi_ioctl.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
diff -puN drivers/scsi/pcmcia/qlogic_stub.c~bk-scsi drivers/scsi/pcmcia/qlogic_stub.c
--- 25/drivers/scsi/pcmcia/qlogic_stub.c~bk-scsi	2004-06-14 00:10:34.594049208 -0700
+++ 25-akpm/drivers/scsi/pcmcia/qlogic_stub.c	2004-06-14 00:10:34.888004520 -0700
@@ -46,7 +46,7 @@
 #include <linux/interrupt.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "../qlogicfas408.h"
 
 #include <pcmcia/version.h>
diff -puN drivers/scsi/pluto.c~bk-scsi drivers/scsi/pluto.c
--- 25/drivers/scsi/pluto.c~bk-scsi	2004-06-14 00:10:34.596048904 -0700
+++ 25-akpm/drivers/scsi/pluto.c	2004-06-14 00:10:34.889004368 -0700
@@ -21,7 +21,7 @@
 #include <asm/irq.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "../fc4/fcp_impl.h"
 #include "pluto.h"
 
diff -puN drivers/scsi/ppa.h~bk-scsi drivers/scsi/ppa.h
--- 25/drivers/scsi/ppa.h~bk-scsi	2004-06-14 00:10:34.597048752 -0700
+++ 25-akpm/drivers/scsi/ppa.h	2004-06-14 00:10:34.889004368 -0700
@@ -86,7 +86,7 @@
 #include  <linux/interrupt.h>
 
 #include  <asm/io.h>
-#include  "hosts.h"
+#include  <scsi/scsi_host.h>
 /* batteries not included :-) */
 
 /*
diff -puN drivers/scsi/psi240i.c~bk-scsi drivers/scsi/psi240i.c
--- 25/drivers/scsi/psi240i.c~bk-scsi	2004-06-14 00:10:34.599048448 -0700
+++ 25-akpm/drivers/scsi/psi240i.c	2004-06-14 00:10:34.890004216 -0700
@@ -41,7 +41,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "psi240i.h"
 #include "psi_chip.h"
diff -puN drivers/scsi/qla1280.c~bk-scsi drivers/scsi/qla1280.c
--- 25/drivers/scsi/qla1280.c~bk-scsi	2004-06-14 00:10:34.601048144 -0700
+++ 25-akpm/drivers/scsi/qla1280.c	2004-06-14 00:10:34.894003608 -0700
@@ -357,7 +357,7 @@
 #else
 #include <linux/blk.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "sd.h"
 #endif
 
@@ -3119,6 +3119,7 @@ qla1280_marker(struct scsi_qla_host *ha,
  * Returns:
  *      0 = success, was able to issue command.
  */
+#ifdef QLA_64BIT_PTR
 static int
 qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 {
@@ -3381,9 +3382,8 @@ qla1280_64bit_start_scsi(struct scsi_qla
 
 	return status;
 }
+#else /* !QLA_64BIT_PTR */
 
-
-#ifndef QLA_64BIT_PTR
 /*
  * qla1280_32bit_start_scsi
  *      The start SCSI is responsible for building request packets on
diff -puN drivers/scsi/qla2xxx/qla_os.h~bk-scsi drivers/scsi/qla2xxx/qla_os.h
--- 25/drivers/scsi/qla2xxx/qla_os.h~bk-scsi	2004-06-14 00:10:34.602047992 -0700
+++ 25-akpm/drivers/scsi/qla2xxx/qla_os.h	2004-06-14 00:10:34.894003608 -0700
@@ -59,7 +59,7 @@
 #include <asm/uaccess.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include <scsi/scsicam.h>
 #include <scsi/scsi_ioctl.h>
diff -puN drivers/scsi/qlogicfas408.c~bk-scsi drivers/scsi/qlogicfas408.c
--- 25/drivers/scsi/qlogicfas408.c~bk-scsi	2004-06-14 00:10:34.604047688 -0700
+++ 25-akpm/drivers/scsi/qlogicfas408.c	2004-06-14 00:10:34.896003304 -0700
@@ -56,7 +56,7 @@
 #include <asm/dma.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "qlogicfas408.h"
 
 /*----------------------------------------------------------------*/
diff -puN drivers/scsi/qlogicfas.c~bk-scsi drivers/scsi/qlogicfas.c
--- 25/drivers/scsi/qlogicfas.c~bk-scsi	2004-06-14 00:10:34.605047536 -0700
+++ 25-akpm/drivers/scsi/qlogicfas.c	2004-06-14 00:10:34.895003456 -0700
@@ -32,7 +32,7 @@
 #include <asm/dma.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "qlogicfas408.h"
 
 /* Set the following to 2 to use normal interrupt (active high/totempole-
diff -puN drivers/scsi/qlogicfc.c~bk-scsi drivers/scsi/qlogicfc.c
--- 25/drivers/scsi/qlogicfc.c~bk-scsi	2004-06-14 00:10:34.607047232 -0700
+++ 25-akpm/drivers/scsi/qlogicfc.c	2004-06-14 00:10:34.898003000 -0700
@@ -64,7 +64,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #define pci64_dma_hi32(a) ((u32) (0xffffffff & (((u64)(a))>>32)))
 #define pci64_dma_lo32(a) ((u32) (0xffffffff & (((u64)(a)))))
diff -puN drivers/scsi/qlogicisp.c~bk-scsi drivers/scsi/qlogicisp.c
--- 25/drivers/scsi/qlogicisp.c~bk-scsi	2004-06-14 00:10:34.608047080 -0700
+++ 25-akpm/drivers/scsi/qlogicisp.c	2004-06-14 00:10:34.899002848 -0700
@@ -36,7 +36,7 @@
 #include <asm/irq.h>
 #include <asm/byteorder.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "qlogicisp.h"
 
 /* Configuration section *****************************************************/
diff -puN drivers/scsi/qlogicpti.c~bk-scsi drivers/scsi/qlogicpti.c
--- 25/drivers/scsi/qlogicpti.c~bk-scsi	2004-06-14 00:10:34.610046776 -0700
+++ 25-akpm/drivers/scsi/qlogicpti.c	2004-06-14 00:10:34.901002544 -0700
@@ -27,6 +27,8 @@
 
 #include <asm/byteorder.h>
 
+#include "scsi.h"
+#include <scsi/scsi_host.h>
 #include "qlogicpti.h"
 
 #include <asm/sbus.h>
diff -puN drivers/scsi/scsicam.c~bk-scsi drivers/scsi/scsicam.c
--- 25/drivers/scsi/scsicam.c~bk-scsi	2004-06-14 00:10:34.612046472 -0700
+++ 25-akpm/drivers/scsi/scsicam.c	2004-06-14 00:10:36.108818928 -0700
@@ -19,7 +19,7 @@
 #include <linux/buffer_head.h>
 #include <asm/unaligned.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsicam.h>
 
 static int setsize(unsigned long capacity, unsigned int *cyls, unsigned int *hds,
diff -puN drivers/scsi/scsi_debug.c~bk-scsi drivers/scsi/scsi_debug.c
--- 25/drivers/scsi/scsi_debug.c~bk-scsi	2004-06-14 00:10:34.613046320 -0700
+++ 25-akpm/drivers/scsi/scsi_debug.c	2004-06-14 00:10:34.903002240 -0700
@@ -43,7 +43,7 @@
 
 #include <linux/blkdev.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsicam.h>
 
 #include <linux/stat.h>
diff -puN drivers/scsi/scsi_devinfo.c~bk-scsi drivers/scsi/scsi_devinfo.c
--- 25/drivers/scsi/scsi_devinfo.c~bk-scsi	2004-06-14 00:10:34.615046016 -0700
+++ 25-akpm/drivers/scsi/scsi_devinfo.c	2004-06-14 00:10:34.904002088 -0700
@@ -9,7 +9,7 @@
 #include <scsi/scsi_devinfo.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "scsi_priv.h"
 
 /*
@@ -27,7 +27,7 @@ struct scsi_dev_info_list {
 static const char spaces[] = "                "; /* 16 of them */
 static unsigned scsi_default_dev_flags;
 static LIST_HEAD(scsi_dev_info_list);
-static __init char scsi_dev_flags[256];
+static __initdata char scsi_dev_flags[256];
 
 /*
  * scsi_static_device_list: deprecated list of devices that require
@@ -117,8 +117,10 @@ static struct {
 	 */
 	{"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN},
 	{"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN},
-	{"BELKIN", "USB 2 HS-CF", "1.95",  BLIST_SPARSELUN},
+	{"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN},
+	{"BELKIN", "USB 2 HS-CF", "1.95",  BLIST_FORCELUN},
 	{"CANON", "IPUBJD", NULL, BLIST_SPARSELUN},
+	{"CBOX3", "USB Storage-SMC", "300A", BLIST_FORCELUN},
 	{"CMD", "CRA-7280", NULL, BLIST_SPARSELUN},	/* CMD RAID Controller */
 	{"CNSI", "G7324", NULL, BLIST_SPARSELUN},	/* Chaparral G7324 RAID */
 	{"CNSi", "G8324", NULL, BLIST_SPARSELUN},	/* Chaparral G8324 RAID */
@@ -139,6 +141,7 @@ static struct {
 	{"EMC", "SYMMETRIX", NULL, BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN},
 	{"EMULEX", "MD21/S2     ESDI", NULL, BLIST_SINGLELUN},
 	{"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN},
 	{"Generic", "USB Storage-SMC", "0180", BLIST_FORCELUN},
 	{"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN},
 	{"HITACHI", "DF400", "*", BLIST_SPARSELUN},
@@ -171,6 +174,7 @@ static struct {
 	{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
 	{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
+	{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
 	{"SGI", "RAID3", "*", BLIST_SPARSELUN},
 	{"SGI", "RAID5", "*", BLIST_SPARSELUN},
 	{"SGI", "TP9100", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
@@ -182,6 +186,7 @@ static struct {
 	{"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN},
 	{"TOSHIBA", "CDROM", NULL, BLIST_ISROM},
 	{"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM},
+	{"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN},
 	{"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"Zzyzx", "RocketStor 500S", NULL, BLIST_SPARSELUN},
 	{"Zzyzx", "RocketStor 2000", NULL, BLIST_SPARSELUN},
diff -puN drivers/scsi/scsi_error.c~bk-scsi drivers/scsi/scsi_error.c
--- 25/drivers/scsi/scsi_error.c~bk-scsi	2004-06-14 00:10:34.616045864 -0700
+++ 25-akpm/drivers/scsi/scsi_error.c	2004-06-14 00:10:34.906001784 -0700
@@ -26,7 +26,7 @@
 #include <scsi/scsi_ioctl.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "scsi_priv.h"
 #include "scsi_logging.h"
@@ -1026,7 +1026,8 @@ static int scsi_try_bus_reset(struct scs
 	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
 	if (rtn == SUCCESS) {
-		scsi_sleep(BUS_RESET_SETTLE_TIME);
+		if (!scmd->device->host->hostt->skip_settle_delay)
+			scsi_sleep(BUS_RESET_SETTLE_TIME);
 		spin_lock_irqsave(scmd->device->host->host_lock, flags);
 		scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
 		spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
@@ -1057,7 +1058,8 @@ static int scsi_try_host_reset(struct sc
 	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
 	if (rtn == SUCCESS) {
-		scsi_sleep(HOST_RESET_SETTLE_TIME);
+		if (!scmd->device->host->hostt->skip_settle_delay)
+			scsi_sleep(HOST_RESET_SETTLE_TIME);
 		spin_lock_irqsave(scmd->device->host->host_lock, flags);
 		scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
 		spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
diff -puN drivers/scsi/scsi.h~bk-scsi drivers/scsi/scsi.h
--- 25/drivers/scsi/scsi.h~bk-scsi	2004-06-14 00:10:34.618045560 -0700
+++ 25-akpm/drivers/scsi/scsi.h	2004-06-14 00:10:34.901002544 -0700
@@ -11,6 +11,11 @@
  *       add scatter-gather, multiple outstanding request, and other
  *       enhancements.
  */
+/*
+ * NOTE:  this file only contains compatibility glue for old drivers.  All
+ * these wrappers will be removed sooner or later.  For new code please use
+ * the interfaces declared in the headers in include/scsi/
+ */
 
 #ifndef _SCSI_H
 #define _SCSI_H
@@ -18,6 +23,7 @@
 #include <linux/config.h>	    /* for CONFIG_SCSI_LOGGING */
 
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_request.h>
@@ -47,21 +53,6 @@ struct scsi_target;
 struct scatterlist;
 
 /*
- * Prototypes for functions in constants.c
- * Some of these used to live in constants.h
- */
-extern void print_Scsi_Cmnd(struct scsi_cmnd *);
-extern void print_command(unsigned char *);
-extern void print_sense(const char *, struct scsi_cmnd *);
-extern void print_req_sense(const char *, struct scsi_request *);
-extern void print_driverbyte(int scsiresult);
-extern void print_hostbyte(int scsiresult);
-extern void print_status(unsigned char status);
-extern int print_msg(const unsigned char *);
-extern const char *scsi_sense_key_string(unsigned char);
-extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
-
-/*
  * Legacy dma direction interfaces.
  *
  * This assumes the pci/sbus dma mapping flags have the same numercial
@@ -77,6 +68,42 @@ extern const char *scsi_extd_sense_forma
 #define scsi_to_sbus_dma_dir(scsi_dir)	((int)(scsi_dir))
 
 /*
+ * Old names for debug prettyprinting functions.
+ */
+static inline void print_Scsi_Cmnd(struct scsi_cmnd *cmd)
+{
+	return scsi_print_command(cmd);
+}
+static inline void print_command(unsigned char *cdb)
+{
+	return __scsi_print_command(cdb);
+}
+static inline void print_sense(const char *devclass, struct scsi_cmnd *cmd)
+{
+	return scsi_print_sense(devclass, cmd);
+}
+static inline void print_req_sense(const char *devclass, struct scsi_request *req)
+{
+	return scsi_print_req_sense(devclass, req);
+}
+static inline void print_driverbyte(int scsiresult)
+{
+	return scsi_print_driverbyte(scsiresult);
+}
+static inline void print_hostbyte(int scsiresult)
+{
+	return scsi_print_hostbyte(scsiresult);
+}
+static inline void print_status(unsigned char status)
+{
+	return scsi_print_status(status);
+}
+static inline int print_msg(const unsigned char *msg)
+{
+	return scsi_print_msg(msg);
+}
+
+/*
  * This is the crap from the old error handling code.  We have it in a special
  * place so that we can more easily delete it later on.
  */
diff -puN drivers/scsi/scsi_ioctl.c~bk-scsi drivers/scsi/scsi_ioctl.c
--- 25/drivers/scsi/scsi_ioctl.c~bk-scsi	2004-06-14 00:10:34.619045408 -0700
+++ 25-akpm/drivers/scsi/scsi_ioctl.c	2004-06-14 00:10:34.906001784 -0700
@@ -20,7 +20,7 @@
 
 #include <linux/blkdev.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
 
 #include "scsi_logging.h"
diff -puN drivers/scsi/scsiiom.c~bk-scsi drivers/scsi/scsiiom.c
--- 25/drivers/scsi/scsiiom.c~bk-scsi	2004-06-14 00:10:34.621045104 -0700
+++ 25-akpm/drivers/scsi/scsiiom.c	2004-06-14 00:10:36.111818472 -0700
@@ -12,7 +12,7 @@ dc390_freetag (PDCB pDCB, PSRB pSRB)
 		pDCB->TagMask &= ~(1 << pSRB->TagNumber);   /* free tag mask */
 		pSRB->TagNumber = 255;
 	}
-};
+}
 
 
 static UCHAR
@@ -75,7 +75,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, P
 		printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02x\n", pDCB->TargetID, pDCB->TargetLUN); 
 		return 1;
 		//goto no_tag;
-	};
+	}
 	DC390_write8 (ScsiFifo, SIMPLE_QUEUE_TAG);
 	pDCB->TagMask |= (1 << tag_no); pSRB->TagNumber = tag_no;
 	DC390_write8 (ScsiFifo, tag_no);
@@ -86,7 +86,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, P
       {
 //      no_tag:
 	DEBUG1(printk (KERN_DEBUG "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", (disc_allowed?"":"o"), pSRB->pcmd->pid, pSRB));
-      };
+      }
 
     pSRB->SRBState = SRB_START_;
 
@@ -104,7 +104,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, P
 	//pSRB->SRBState = SRB_MSGOUT_;
 	pSRB->SRBState |= DO_SYNC_NEGO;
 	cmd = SEL_W_ATN_STOP;
-      };
+      }
 
     /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
     if (cmd != SEL_W_ATN_STOP)
@@ -125,7 +125,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, P
 	    ptr = (PUCHAR) pSRB->pcmd->cmnd;
 	    for (i=0; i<pSRB->pcmd->cmd_len; i++)
 	      DC390_write8 (ScsiFifo, *(ptr++));
-	  };
+	  }
       }
     DEBUG0(if (pACB->pActiveDCB)	\
 	   printk (KERN_WARNING "DC390: ActiveDCB != 0\n"));
@@ -141,7 +141,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, P
 	//DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
 	pACB->SelLost++;
 	return 1;
-    };
+    }
     DC390_write8 (ScsiCmd, cmd);
     pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB;
     pACB->Connected = 1;
@@ -176,7 +176,7 @@ dc390_dma_intr (PACB pACB)
     {
 	printk (KERN_ERR "DC390: DMA error (%02x)!\n", dstate);
 	return dstate;
-    };
+    }
   if (dstate & DMA_XFER_DONE)
     {
 	UINT residual, xferCnt; int ctr = 6000000;
@@ -253,7 +253,7 @@ DC390_Interrupt( int irq, void *dev_id, 
       {
 	DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n"));
 	return IRQ_NONE;
-      };
+      }
 #else
     //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
     //dstatus = DC390_read8 (DMA_Status);
@@ -313,7 +313,7 @@ DC390_Interrupt( int irq, void *dev_id, 
 	{
 		printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
 		goto unlock;
-	};
+	}
 	pSRB = pDCB->pActiveSRB;
 	if( pDCB->DCBFlag & ABORT_DEV_ )
 	  dc390_EnableMsgOut_Abort (pACB, pSRB);
@@ -549,7 +549,7 @@ dc390_reprog (PACB pACB, PDCB pDCB)
   DC390_write8 (CtrlReg3, pDCB->CtrlR3);
   DC390_write8 (CtrlReg4, pDCB->CtrlR4);
   dc390_SetXferRate (pACB, pDCB);
-};
+}
 
 
 #ifdef DC390_DEBUG0
@@ -561,7 +561,7 @@ dc390_printMsg (UCHAR *MsgBuf, UCHAR len
   for (i = 1; i < len; i++)
     printk (" %02x", MsgBuf[i]);
   printk ("\n");
-};
+}
 #endif
 
 #define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
@@ -671,11 +671,11 @@ dc390_MsgIn_set_sync (PACB pACB, PSRB pS
 	{
 	  printk (KERN_INFO "DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
 	  pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
-	};
+	}
       memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
       pSRB->MsgCnt = 5;
       DC390_ENABLE_MSGOUT;
-    };
+    }
 
   pSRB->SRBState &= ~DO_SYNC_NEGO;
   pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
@@ -713,7 +713,7 @@ dc390_MsgIn_set_sync (PACB pACB, PSRB pS
     }
   
   dc390_reprog (pACB, pDCB);
-};
+}
 
 
 /* handle RESTORE_PTR */
@@ -761,7 +761,7 @@ dc390_restore_ptr (PACB pACB, PSRB pSRB)
     }
 
   pSRB->TotalXferredLen = pSRB->Saved_Ptr;
-};
+}
 
 
 /* According to the docs, the AM53C974 reads the message and 
@@ -789,7 +789,7 @@ dc390_MsgIn_complete (UCHAR *msgbuf, UIN
 
 
 /* read and eval received messages */
-void
+static void
 dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
 {
     PDCB   pDCB = pACB->pActiveDCB;
@@ -832,7 +832,7 @@ dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUC
 		  dc390_MsgIn_set_async (pACB, pSRB);
 		else
 		  dc390_MsgIn_set_sync (pACB, pSRB);
-	      };
+	      }
 	    
 	    // nothing has to be done
 	  case COMMAND_COMPLETE: break;
@@ -948,7 +948,7 @@ dc390_DataInPhase( PACB pACB, PSRB pSRB,
     dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
 }
 
-void
+static void
 dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
 {
     PDCB   pDCB;
@@ -989,7 +989,7 @@ dc390_StatusPhase( PACB pACB, PSRB pSRB,
     //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
 }
 
-void
+static void
 dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
 {
     UCHAR   bval, i, cnt;
@@ -1097,7 +1097,7 @@ dc390_SetXferRate( PACB pACB, PDCB pDCB 
 }
 
 
-void
+static void
 dc390_Disconnect( PACB pACB )
 {
     PDCB   pDCB;
@@ -1179,7 +1179,7 @@ disc1:
 }
 
 
-void
+static void
 dc390_Reselect( PACB pACB )
 {
     PDCB   pDCB;
@@ -1276,7 +1276,7 @@ dc390_remove_dev (PACB pACB, PDCB pDCB)
 	DCBDEBUG(printk (KERN_INFO "DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n",\
 		pDCB->TargetID, pDCB->TargetLUN, (int)pDCB, pDCB->GoingSRBCnt));
 	return;
-     };
+     }
    pACB->DCBmap[pDCB->TargetID] &= ~(1 << pDCB->TargetLUN);
    
    // The first one
@@ -1302,8 +1302,7 @@ dc390_remove_dev (PACB pACB, PDCB pDCB)
    if (pDCB == pACB->pDCBRunRobin) pACB->pDCBRunRobin = pDCB->pNextDCB;
    kfree (pDCB); 
    pACB->DCBCnt--;
-   /* pACB->DeviceCnt--; */
-};
+}
 
 
 static UCHAR __inline__
@@ -1314,7 +1313,7 @@ dc390_tagq_blacklist (char* name)
      if (memcmp (name, dc390_baddevname1[i], 28) == 0)
 	return 1;
    return 0;
-};
+}
    
 
 static void 
@@ -1336,7 +1335,7 @@ dc390_disc_tagq_set (PDCB pDCB, PSCSI_IN
 	else
 	     pDCB->MaxCommand = 1;
      }
-};
+}
 
 
 static void 
@@ -1346,13 +1345,13 @@ dc390_add_dev (PACB pACB, PDCB pDCB, PSC
    pDCB->DevType = bval1;
    /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
 	dc390_disc_tagq_set (pDCB, ptr);
-};
+}
 
 
-void
+static void
 dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
 {
-    UCHAR  bval, status, i, DCB_removed;
+    UCHAR  bval, status, i;
     PSCSICMD pcmd;
     PSCSI_INQDATA  ptr;
     PSGL   ptr2;
@@ -1362,7 +1361,6 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSR
     /* KG: Moved pci_unmap here */
     dc390_pci_unmap(pSRB);
 
-    DCB_removed = 0;
     status = pSRB->TargetStatus;
     ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
     if( pcmd->use_sg )
@@ -1564,55 +1562,22 @@ ckc_e:
 				   pcmd->sense_buffer[2], pcmd->sense_buffer[3]);
 	    else printk ("\n");
 #endif
-	    if( (host_byte(pcmd->result) != DID_OK && !(status_byte(pcmd->result) & CHECK_CONDITION) && !(status_byte(pcmd->result) & BUSY)) ||
-	       ((driver_byte(pcmd->result) & DRIVER_SENSE) && (pcmd->sense_buffer[0] & 0x70) == 0x70 &&
-		(pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || host_byte(pcmd->result) & DID_ERROR )
-	    {
-	       /* device not present: remove */ 
-	       //dc390_Going_remove (pDCB, pSRB);
-	       dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
-	       
-	       if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
-		  ((pcmd->device->lun == 0) || (pcmd->device->lun == pACB->pScsiHost->max_lun - 1)) )
-		 pACB->scan_devices = 0;
-	    }
-	    else
-	    {
-	        /* device present: add */
-		if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) && 
-		    (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
-		    pACB->scan_devices = END_SCAN ;
-	        /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */
-	    }
 	}
     }
-   
-    //if( pSRB->pcmd->cmnd[0] == INQUIRY && 
-    //  (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) )
+
     if( pcmd->cmnd[0] == INQUIRY && 
 	(pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) )
      {
-	if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV && !DCB_removed)
-	  {
-	     //printk ("DC390: Type = nodev! (%02i-%i)\n", pcmd->target, pcmd->lun);
-	     /* device not present: remove */
-	     //dc390_Going_remove (pDCB, pSRB);
-	     dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
-	  }
-	else
+	if ((ptr->DevType & SCSI_DEVTYPE) != TYPE_NODEV)
 	  {
 	     /* device found: add */ 
 	     dc390_add_dev (pACB, pDCB, ptr);
-	     if (pACB->scan_devices) pACB->DeviceCnt++;
 	  }
-	if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
-	    (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
-	  pACB->scan_devices = 0;
-     };
+     }
 
     pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
 
-    if (!DCB_removed) dc390_Going_remove (pDCB, pSRB);
+    dc390_Going_remove (pDCB, pSRB);
     /* Add to free list */
     dc390_Free_insert (pACB, pSRB);
 
@@ -1625,7 +1590,7 @@ ckc_e:
 
 
 /* Remove all SRBs from Going list and inform midlevel */
-void
+static void
 dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd )
 {
     PDCB   pDCB, pdcb;
@@ -1760,4 +1725,3 @@ dc390_InvalidCmd( PACB pACB )
     if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
 	DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
 }
-
diff -puN drivers/scsi/scsi_lib.c~bk-scsi drivers/scsi/scsi_lib.c
--- 25/drivers/scsi/scsi_lib.c~bk-scsi	2004-06-14 00:10:34.622044952 -0700
+++ 25-akpm/drivers/scsi/scsi_lib.c	2004-06-14 00:10:34.908001480 -0700
@@ -255,7 +255,6 @@ void scsi_wait_req(struct scsi_request *
 	sreq->sr_request->rq_status = RQ_SCSI_BUSY;
 	scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_wait_done,
 			timeout, retries);
-	generic_unplug_device(sreq->sr_device->request_queue);
 	wait_for_completion(&wait);
 	sreq->sr_request->waiting = NULL;
 	if (sreq->sr_request->rq_status != RQ_SCSI_DONE)
diff -puN drivers/scsi/scsi_module.c~bk-scsi drivers/scsi/scsi_module.c
--- 25/drivers/scsi/scsi_module.c~bk-scsi	2004-06-14 00:10:34.624044648 -0700
+++ 25-akpm/drivers/scsi/scsi_module.c	2004-06-14 00:10:34.908001480 -0700
@@ -12,7 +12,7 @@
 #include <linux/module.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 
 static int __init init_this_scsi_driver(void)
diff -puN drivers/scsi/scsi_pc98.c~bk-scsi drivers/scsi/scsi_pc98.c
--- 25/drivers/scsi/scsi_pc98.c~bk-scsi	2004-06-14 00:10:34.626044344 -0700
+++ 25-akpm/drivers/scsi/scsi_pc98.c	2004-06-14 00:10:34.909001328 -0700
@@ -12,7 +12,7 @@
 #include <asm/pc9800.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 
 static int pc98_first_bios_param(struct scsi_device *sdev, int *ip)
diff -puN drivers/scsi/scsi_syms.c~bk-scsi drivers/scsi/scsi_syms.c
--- 25/drivers/scsi/scsi_syms.c~bk-scsi	2004-06-14 00:10:34.627044192 -0700
+++ 25-akpm/drivers/scsi/scsi_syms.c	2004-06-14 00:10:34.909001328 -0700
@@ -46,15 +46,15 @@ EXPORT_SYMBOL(scsicam_bios_param);
 EXPORT_SYMBOL(scsi_partsize);
 EXPORT_SYMBOL(scsi_bios_ptable);
 EXPORT_SYMBOL(scsi_ioctl);
-EXPORT_SYMBOL(print_command);
-EXPORT_SYMBOL(print_sense);
-EXPORT_SYMBOL(print_req_sense);
-EXPORT_SYMBOL(print_msg);
-EXPORT_SYMBOL(print_status);
+EXPORT_SYMBOL(scsi_print_command);
+EXPORT_SYMBOL(__scsi_print_command);
+EXPORT_SYMBOL(scsi_print_sense);
+EXPORT_SYMBOL(scsi_print_req_sense);
+EXPORT_SYMBOL(scsi_print_msg);
+EXPORT_SYMBOL(scsi_print_status);
 EXPORT_SYMBOL(scsi_sense_key_string);
 EXPORT_SYMBOL(scsi_extd_sense_format);
 EXPORT_SYMBOL(kernel_scsi_ioctl);
-EXPORT_SYMBOL(print_Scsi_Cmnd);
 EXPORT_SYMBOL(scsi_block_when_processing_errors);
 EXPORT_SYMBOL(scsi_ioctl_send_command);
 EXPORT_SYMBOL(scsi_set_medium_removal);
diff -puN drivers/scsi/scsi_transport_spi.c~bk-scsi drivers/scsi/scsi_transport_spi.c
diff -puN drivers/scsi/sd.c~bk-scsi drivers/scsi/sd.c
--- 25/drivers/scsi/sd.c~bk-scsi	2004-06-14 00:10:34.630043736 -0700
+++ 25-akpm/drivers/scsi/sd.c	2004-06-14 00:10:36.112818320 -0700
@@ -52,7 +52,7 @@
 #include <asm/uaccess.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_ioctl.h>
@@ -763,11 +763,11 @@ static void sd_rw_intr(struct scsi_cmnd 
 				good_bytes = 0;
 			break;
 
-		case RECOVERED_ERROR:
+		case RECOVERED_ERROR: /* an error occurred, but it recovered */
+		case NO_SENSE: /* LLDD got sense data */
 			/*
-			 * An error occurred, but it recovered.  Inform the
-			 * user, but make sure that it's not treated as a
-			 * hard error.
+			 * Inform the user, but make sure that it's not treated
+			 * as a hard error.
 			 */
 			print_sense("sd", SCpnt);
 			SCpnt->result = 0;
diff -puN drivers/scsi/seagate.c~bk-scsi drivers/scsi/seagate.c
--- 25/drivers/scsi/seagate.c~bk-scsi	2004-06-14 00:10:34.632043432 -0700
+++ 25-akpm/drivers/scsi/seagate.c	2004-06-14 00:10:36.114818016 -0700
@@ -103,7 +103,7 @@
 #include <asm/uaccess.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "seagate.h"
 
 #include <scsi/scsi_ioctl.h>
diff -puN drivers/scsi/sg.c~bk-scsi drivers/scsi/sg.c
--- 25/drivers/scsi/sg.c~bk-scsi	2004-06-14 00:10:34.634043128 -0700
+++ 25-akpm/drivers/scsi/sg.c	2004-06-14 00:10:36.117817560 -0700
@@ -42,7 +42,6 @@ static int sg_version_num = 30531;	/* 2 
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/poll.h>
-#include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
 #include <linux/moduleparam.h>
 #include <linux/devfs_fs_kernel.h>
@@ -51,7 +50,7 @@ static int sg_version_num = 30531;	/* 2 
 
 #include <linux/blkdev.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/sg.h>
@@ -60,7 +59,7 @@ static int sg_version_num = 30531;	/* 2 
 
 #ifdef CONFIG_SCSI_PROC_FS
 #include <linux/proc_fs.h>
-static char *sg_version_date = "20040513";
+static char *sg_version_date = "20040516";
 
 static int sg_proc_init(void);
 static void sg_proc_cleanup(void);
@@ -73,7 +72,7 @@ static void sg_proc_cleanup(void);
 #define SG_ALLOW_DIO_DEF 0
 #define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
 
-#define SG_MAX_DEVS 8192
+#define SG_MAX_DEVS 32768
 
 /*
  * Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
@@ -718,7 +717,6 @@ sg_common_write(Sg_fd * sfp, Sg_request 
 		    (void *) SRpnt->sr_buffer, hp->dxfer_len,
 		    sg_cmd_done, timeout, SG_DEFAULT_RETRIES);
 	/* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
-	generic_unplug_device(q);
 	return 0;
 }
 
@@ -1331,9 +1329,11 @@ static int sg_alloc(struct gendisk *disk
 	void *old_sg_dev_arr = NULL;
 	int k, error;
 
-	sdp = vmalloc(sizeof(Sg_device));
-	if (!sdp)
+	sdp = kmalloc(sizeof(Sg_device), GFP_KERNEL);
+	if (!sdp) {
+		printk(KERN_WARNING "kmalloc Sg_device failure\n");
 		return -ENOMEM;
+	}
 
 	write_lock_irqsave(&sg_dev_arr_lock, iflags);
 	if (unlikely(sg_nr_dev >= sg_dev_max)) {	/* try to resize */
@@ -1341,7 +1341,7 @@ static int sg_alloc(struct gendisk *disk
 		int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP;
 		write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
 
-		tmp_da = vmalloc(tmp_dev_max * sizeof(Sg_device *));
+		tmp_da = kmalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL);
 		if (unlikely(!tmp_da))
 			goto expand_failed;
 
@@ -1375,12 +1375,12 @@ static int sg_alloc(struct gendisk *disk
 
  out:
 	if (error < 0)
-		vfree(sdp);
-	vfree(old_sg_dev_arr);
+		kfree(sdp);
+	kfree(old_sg_dev_arr);
 	return error;
 
  expand_failed:
-	printk(KERN_ERR "sg_alloc: device array cannot be resized\n");
+	printk(KERN_WARNING "sg_alloc: device array cannot be resized\n");
 	error = -ENOMEM;
 	goto out;
 
@@ -1404,20 +1404,26 @@ sg_add(struct class_device *cl_dev)
 	int error, k;
 
 	disk = alloc_disk(1);
-	if (!disk)
+	if (!disk) {
+		printk(KERN_WARNING "alloc_disk failed\n");
 		return -ENOMEM;
+	}
 	disk->major = SCSI_GENERIC_MAJOR;
 
 	error = -ENOMEM;
 	cdev = cdev_alloc();
-	if (!cdev)
+	if (!cdev) {
+		printk(KERN_WARNING "cdev_alloc failed\n");
 		goto out;
+	}
 	cdev->owner = THIS_MODULE;
 	cdev->ops = &sg_fops;
 
 	error = sg_alloc(disk, scsidp);
-	if (error < 0)
+	if (error < 0) {
+		printk(KERN_WARNING "sg_alloc failed\n");
 		goto out;
+	}
 	k = error;
 	sdp = sg_dev_arr[k];
 
@@ -1525,7 +1531,7 @@ sg_remove(struct class_device *cl_dev)
 		put_disk(sdp->disk);
 		sdp->disk = NULL;
 		if (NULL == sdp->headfp)
-			vfree((char *) sdp);
+			kfree((char *) sdp);
 	}
 
 	if (delay)
@@ -1590,7 +1596,7 @@ exit_sg(void)
 	unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
 				 SG_MAX_DEVS);
 	if (sg_dev_arr != NULL) {
-		vfree((char *) sg_dev_arr);
+		kfree((char *) sg_dev_arr);
 		sg_dev_arr = NULL;
 	}
 	sg_dev_max = 0;
@@ -2492,7 +2498,7 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * s
 			}
 			if (k < maxd)
 				sg_dev_arr[k] = NULL;
-			vfree((char *) sdp);
+			kfree((char *) sdp);
 			res = 1;
 		}
 		write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
diff -puN drivers/scsi/sgiwd93.c~bk-scsi drivers/scsi/sgiwd93.c
--- 25/drivers/scsi/sgiwd93.c~bk-scsi	2004-06-14 00:10:34.635042976 -0700
+++ 25-akpm/drivers/scsi/sgiwd93.c	2004-06-14 00:10:36.117817560 -0700
@@ -31,7 +31,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "wd33c93.h"
 #include "sgiwd93.h"
 
diff -puN drivers/scsi/sim710.c~bk-scsi drivers/scsi/sim710.c
--- 25/drivers/scsi/sim710.c~bk-scsi	2004-06-14 00:10:34.637042672 -0700
+++ 25-akpm/drivers/scsi/sim710.c	2004-06-14 00:10:36.118817408 -0700
@@ -35,9 +35,8 @@
 #include <linux/mca.h>
 #include <linux/eisa.h>
 #include <linux/interrupt.h>
+#include <scsi/scsi_host.h>
 
-#include "scsi.h"
-#include "hosts.h"
 #include "53c700.h"
 
 
@@ -86,7 +85,7 @@ param_setup(char *str)
 }
 __setup("sim710=", param_setup);
 
-static Scsi_Host_Template sim710_driver_template = {
+static struct scsi_host_template sim710_driver_template = {
 	.name			= "LSI (Symbios) 710 MCA/EISA",
 	.proc_name		= "sim710",
 	.this_id		= 7,
diff -puN drivers/scsi/sr.c~bk-scsi drivers/scsi/sr.c
--- 25/drivers/scsi/sr.c~bk-scsi	2004-06-14 00:10:34.638042520 -0700
+++ 25-akpm/drivers/scsi/sr.c	2004-06-14 00:10:36.119817256 -0700
@@ -47,7 +47,7 @@
 #include <asm/uaccess.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_ioctl.h>	/* For the door lock/unlock commands */
diff -puN drivers/scsi/sr_ioctl.c~bk-scsi drivers/scsi/sr_ioctl.c
--- 25/drivers/scsi/sr_ioctl.c~bk-scsi	2004-06-14 00:10:34.640042216 -0700
+++ 25-akpm/drivers/scsi/sr_ioctl.c	2004-06-14 00:10:36.119817256 -0700
@@ -11,7 +11,7 @@
 #include <asm/uaccess.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
 
 #include "sr.h"
@@ -331,6 +331,9 @@ int sr_audio_ioctl(struct cdrom_device_i
 	int result;
 	unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
 
+	if (!buffer)
+		return -ENOMEM;
+
 	memset(&cgc, 0, sizeof(struct packet_command));
 	cgc.timeout = IOCTL_TIMEOUT;
 
diff -puN drivers/scsi/sr_vendor.c~bk-scsi drivers/scsi/sr_vendor.c
--- 25/drivers/scsi/sr_vendor.c~bk-scsi	2004-06-14 00:10:34.641042064 -0700
+++ 25-akpm/drivers/scsi/sr_vendor.c	2004-06-14 00:10:36.120817104 -0700
@@ -41,7 +41,7 @@
 
 #include <linux/blkdev.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
 
 #include <linux/cdrom.h>
diff -puN drivers/scsi/st.c~bk-scsi drivers/scsi/st.c
--- 25/drivers/scsi/st.c~bk-scsi	2004-06-14 00:10:34.643041760 -0700
+++ 25-akpm/drivers/scsi/st.c	2004-06-14 00:10:36.123816648 -0700
@@ -58,7 +58,7 @@ static char *verstr = "20040403";
 
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_ioctl.h>
diff -puN drivers/scsi/sun3_scsi.c~bk-scsi drivers/scsi/sun3_scsi.c
--- 25/drivers/scsi/sun3_scsi.c~bk-scsi	2004-06-14 00:10:34.644041608 -0700
+++ 25-akpm/drivers/scsi/sun3_scsi.c	2004-06-14 00:10:36.124816496 -0700
@@ -75,7 +75,7 @@
 #define REAL_DMA
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "sun3_scsi.h"
 #include "NCR5380.h"
 
diff -puN drivers/scsi/sun3_scsi_vme.c~bk-scsi drivers/scsi/sun3_scsi_vme.c
--- 25/drivers/scsi/sun3_scsi_vme.c~bk-scsi	2004-06-14 00:10:34.646041304 -0700
+++ 25-akpm/drivers/scsi/sun3_scsi_vme.c	2004-06-14 00:10:36.125816344 -0700
@@ -41,7 +41,7 @@
 #define REAL_DMA
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "sun3_scsi.h"
 #include "NCR5380.h"
 
diff -puN drivers/scsi/sun3x_esp.c~bk-scsi drivers/scsi/sun3x_esp.c
--- 25/drivers/scsi/sun3x_esp.c~bk-scsi	2004-06-14 00:10:34.647041152 -0700
+++ 25-akpm/drivers/scsi/sun3x_esp.c	2004-06-14 00:10:36.126816192 -0700
@@ -16,7 +16,7 @@
 #include <linux/interrupt.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "NCR53C9x.h"
 
 #include <asm/sun3x.h>
diff -puN drivers/scsi/sym53c416.c~bk-scsi drivers/scsi/sym53c416.c
--- 25/drivers/scsi/sym53c416.c~bk-scsi	2004-06-14 00:10:34.649040848 -0700
+++ 25-akpm/drivers/scsi/sym53c416.c	2004-06-14 00:10:36.127816040 -0700
@@ -43,7 +43,7 @@
 #include <linux/blkdev.h>
 #include <linux/isapnp.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "sym53c416.h"
 
 #define VERSION_STRING        "Version 1.0.0-ac"
@@ -622,12 +622,13 @@ void sym53c416_probe(void)
 	int ints[2];
 
 	ints[0] = 1;
-	for(; *base; base++)
-	{
-		if(!check_region(*base, IO_RANGE) && sym53c416_test(*base))
-		{
-			ints[1] = *base;
-			sym53c416_setup(NULL, ints);
+	for(; *base; base++) {
+		if (request_region(*base, IO_RANGE, ID)) {
+			if (sym53c416_test(*base)) {
+				ints[1] = *base;
+				sym53c416_setup(NULL, ints);
+			}
+			release_region(*base, IO_RANGE);
 		}
 	}
 }
@@ -702,44 +703,42 @@ int __init sym53c416_detect(Scsi_Host_Te
 	sym53c416_probe();
 
 	/* Now we register and set up each host adapter found... */
-	for(count = 0, i = 0; i < host_index; i++)
-	{
-		if(!sym53c416_test(hosts[i].base))
+	for(count = 0, i = 0; i < host_index; i++) {
+		if (!request_region(hosts[i].base, IO_RANGE, ID))
+			continue;
+		if (!sym53c416_test(hosts[i].base)) {
 			printk(KERN_WARNING "No sym53c416 found at address 0x%03x\n", hosts[i].base);
-		else
-		{
-			if(hosts[i].irq == 0)
-			/* We don't have an irq yet, so we should probe for one */
-				if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0)
-					printk(KERN_WARNING "IRQ autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base);
-			if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE))
-			{
-				shpnt = scsi_register(tpnt, 0);
-				if(shpnt==NULL)
-					continue;
-				spin_lock_irqsave(&sym53c416_lock, flags);
-				/* Request for specified IRQ */
-				if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt))
-				{
-					spin_unlock_irqrestore(&sym53c416_lock, flags);
-					printk(KERN_ERR "sym53c416: Unable to assign IRQ %d\n", hosts[i].irq);
-					scsi_unregister(shpnt);
-				}
-				else
-				{
-					/* Inform the kernel of our IO range */
-					request_region(hosts[i].base, IO_RANGE, ID);
-					shpnt->unique_id = hosts[i].base;
-					shpnt->io_port = hosts[i].base;
-					shpnt->n_io_port = IO_RANGE;
-					shpnt->irq = hosts[i].irq;
-					shpnt->this_id = hosts[i].scsi_id;
-					sym53c416_init(hosts[i].base, hosts[i].scsi_id);
-					count++;
-					spin_unlock_irqrestore(&sym53c416_lock, flags);
-				}
-			}
+			goto fail_release_region;
 		}
+
+		/* We don't have an irq yet, so we should probe for one */
+		if (!hosts[i].irq)
+			hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id);
+		if (!hosts[i].irq)
+			goto fail_release_region;
+	
+		shpnt = scsi_register(tpnt, 0);
+		if (!shpnt)
+			goto fail_release_region;
+		/* Request for specified IRQ */
+		if (request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt))
+			goto fail_free_host;
+
+		spin_lock_irqsave(&sym53c416_lock, flags);
+		shpnt->unique_id = hosts[i].base;
+		shpnt->io_port = hosts[i].base;
+		shpnt->n_io_port = IO_RANGE;
+		shpnt->irq = hosts[i].irq;
+		shpnt->this_id = hosts[i].scsi_id;
+		sym53c416_init(hosts[i].base, hosts[i].scsi_id);
+		count++;
+		spin_unlock_irqrestore(&sym53c416_lock, flags);
+		continue;
+
+ fail_free_host:
+		scsi_unregister(shpnt);
+ fail_release_region:
+		release_region(hosts[i].base, IO_RANGE);
 	}
 	return count;
 }
diff -puN drivers/scsi/t128.c~bk-scsi drivers/scsi/t128.c
--- 25/drivers/scsi/t128.c~bk-scsi	2004-06-14 00:10:34.650040696 -0700
+++ 25-akpm/drivers/scsi/t128.c	2004-06-14 00:10:36.128815888 -0700
@@ -118,7 +118,7 @@
 #include <linux/delay.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "t128.h"
 #define AUTOPROBE_IRQ
 #include "NCR5380.h"
diff -puN drivers/scsi/tmscsim.c~bk-scsi drivers/scsi/tmscsim.c
--- 25/drivers/scsi/tmscsim.c~bk-scsi	2004-06-14 00:10:34.652040392 -0700
+++ 25-akpm/drivers/scsi/tmscsim.c	2004-06-14 00:10:36.132815280 -0700
@@ -172,6 +172,11 @@
  *	2.1b1 04/01/31	GL	(applied 05.04) Remove internal		*
  *				command-queuing.			*
  *	2.1b2 04/02/01	CH	(applied 05.04) Fix error-handling	*
+ *	2.1c  04/05/23  GL	Update to use the new pci_driver API,	*
+ *				some scsi EH updates, more cleanup.	*
+ *	2.1d  04/05/27	GL	Moved setting of scan_devices to	*
+ *				slave_alloc/_configure/_destroy, as	*
+ *				suggested by CH.			*
  ***********************************************************************/
 
 /* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */
@@ -239,7 +244,7 @@
 #include <linux/interrupt.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <linux/stat.h>
 #include <scsi/scsicam.h>
 
@@ -267,7 +272,6 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 
-#if defined(MODULE)
 static struct pci_device_id tmscsim_pci_tbl[] = {
 	{
 		.vendor		= PCI_VENDOR_ID_AMD,
@@ -278,8 +282,7 @@ static struct pci_device_id tmscsim_pci_
 	{ }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);
-#endif
-	
+
 #define USE_SPINLOCKS 1
 
 #define DC390_IFLAGS unsigned long iflags
@@ -342,6 +345,8 @@ static void   dc390_updateDCB (PACB pACB
 
 static int DC390_release(struct Scsi_Host *host);
 static int dc390_shutdown (struct Scsi_Host *host);
+static int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start,
+			    off_t offset, int length, int inout);
 
 static PACB	dc390_pACB_start= NULL;
 static PACB	dc390_pACB_current = NULL;
@@ -351,16 +356,14 @@ static UCHAR	dc390_adapterCnt = 0;
 
 /* Startup values, to be overriden on the commandline */
 static int tmscsim[] = {-2, -2, -2, -2, -2, -2};
+static int tmscsim_paramnum = ARRAY_SIZE(tmscsim);
 
-#if defined(MODULE)
-MODULE_PARM(tmscsim, "1-6i");
+module_param_array(tmscsim, int, tmscsim_paramnum, 0);
 MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");
 MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
 MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
 MODULE_LICENSE("GPL");
-
 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
-#endif
 
 static PVOID dc390_phase0[]={
        dc390_DataOut_0,
@@ -1031,15 +1034,15 @@ static void dc390_BuildSRB (Scsi_Cmnd* p
  * 2.0.x: always return 0
  * 2.1.x: old model: (use_new_eh_code == 0): like 2.0.x
  *	  TO BE DONE:
- *	  new model: return 0 if successful
- *	  	     return 1 if command cannot be queued (queue full)
+ *	  new model: return 0 if successful, or must not be re-queued
+ *		     return 1 if command cannot be queued (queue full)
  *		     command will be inserted in midlevel queue then ...
  *
  ***********************************************************************/
 
 static int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
 {
-    PDCB   pDCB;
+    PDCB   pDCB = (PDCB) cmd->device->hostdata;
     PSRB   pSRB;
     PACB   pACB = (PACB) cmd->device->host->hostdata;
 
@@ -1050,42 +1053,19 @@ static int DC390_queue_command (Scsi_Cmn
     /* TODO: Change the policy: Always accept TEST_UNIT_READY or INQUIRY 
      * commands and alloc a DCB for the device if not yet there. DCB will
      * be removed in dc390_SRBdone if SEL_TIMEOUT */
-
-    if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) )
-	pACB->scan_devices = 0;
-
-    else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) )
-	pACB->scan_devices = 0;
-
-    if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) && 
-       !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
-    {
-        pACB->scan_devices = 1;
-
-	dc390_initDCB( pACB, &pDCB, cmd->device->id, cmd->device->lun );
-	if (!pDCB)
-	  {
-	    printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n", 
-		    cmd->device->id, cmd->device->lun);
-	    goto fail;
-	  }
-            
-    }
-    else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
-    {
+    if (!(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun))) {
 	printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n",
 		cmd->device->id, cmd->device->lun); 
 	goto fail;
     }
-    else
-    {
-	pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
-	if (!pDCB)
-	 {  /* should never happen */
-	    printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n", 
-		    cmd->device->id, cmd->device->lun);
-	    goto fail;
-	 }
+
+    /* Should it be: BUG_ON(!pDCB); ? */
+
+    if (!pDCB)
+    {  /* should never happen */
+	printk (KERN_ERR "DC390: no DCB found, target %02x lun %02x\n", 
+		cmd->device->id, cmd->device->lun);
+	goto fail;
     }
 
     pACB->Cmds++;
@@ -1304,7 +1284,7 @@ static void dc390_dumpinfo (PACB pACB, P
 
 static int DC390_abort (Scsi_Cmnd *cmd)
 {
-    PDCB  pDCB;
+    PDCB  pDCB = (PDCB) cmd->device->hostdata;
     PSRB  pSRB, psrb;
     UINT  count, i;
     int   status;
@@ -1314,7 +1294,6 @@ static int DC390_abort (Scsi_Cmnd *cmd)
     printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n",
 	    cmd->pid, cmd->device->id, cmd->device->lun);
 
-    pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
     if( !pDCB ) goto  NOT_RUN;
 
     /* Added 98/07/02 KG */
@@ -1746,7 +1725,6 @@ static void __init dc390_initACB (PSH ps
     pACB->AdapterIndex = index;
     pACB->status = 0;
     psh->this_id = dc390_eepromBuf[index][EE_ADAPT_SCSI_ID];
-    pACB->DeviceCnt = 0;
     pACB->DCBCnt = 0;
     pACB->TagMaxNum = 2 << dc390_eepromBuf[index][EE_TAG_CMD_NUM];
     pACB->ACBFlag = 0;
@@ -1856,7 +1834,7 @@ static int __init dc390_initAdapter (PSH
  *
  * Inputs : host - pointer to this host adapter's structure
  *	    io_port - IO ports mapped to this adapter
- *	    Irq - IRQ assigned to this adpater
+ *	    irq - IRQ assigned to this adpater
  *	    struct pci_dev - PCI access handle
  *	    index - Adapter index
  *
@@ -1865,10 +1843,8 @@ static int __init dc390_initAdapter (PSH
  * Note: written in capitals, because the locking is only done here,
  *	not in DC390_detect, called from outside 
  ***********************************************************************/
-
-static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, struct pci_dev *pdev, UCHAR index)
+static int __init dc390_init (PSH psh, unsigned long io_port, u8 irq, struct pci_dev *pdev, UCHAR index)
 {
-    PSH   psh;
     PACB  pACB;
 
     if (dc390_CheckEEpromCheckSum (PDEV, index))
@@ -1890,25 +1866,16 @@ static int __init DC390_init (PSHT psht,
 	dc390_check_for_safe_settings ();
 	dc390_EEprom_Override (index);
     }
-   
-    psh = scsi_register( psht, sizeof(DC390_ACB) );
-    if( !psh ) return( -1 );
-	
-    scsi_set_device(psh, &pdev->dev);
     pACB = (PACB) psh->hostdata;
 
     DEBUG0(printk(KERN_INFO "DC390: pSH = %8x, Index %02i\n", (UINT) psh, index));
 
-    dc390_initACB( psh, io_port, Irq, index );
+    dc390_initACB( psh, io_port, irq, index );
         
     PDEVSET;
 
-    if( !dc390_initAdapter( psh, io_port, Irq, index ) )
+    if( !dc390_initAdapter( psh, io_port, irq, index ) )
     {
-	DEBUG0(printk("DC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\
-		      (UINT) pACB, (UINT) pACB->DCBmap, (UINT) pACB->SRB_array));
-	DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\
-		      sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) ));
         return (0);
     }
     else
@@ -1927,42 +1894,131 @@ static void __init dc390_set_pci_cfg (PD
 	PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
 }
 
-int __init DC390_detect (Scsi_Host_Template *psht)
+/**
+ * dc390_slave_alloc - Called by the scsi mid layer to tell us about a new
+ * scsi device that we need to deal with.
+ *
+ * @scsi_device: The new scsi device that we need to handle.
+ */
+static int dc390_slave_alloc(struct scsi_device *scsi_device)
+{
+	PDCB pDCB;
+	PACB pACB = (PACB) scsi_device->host->hostdata;
+	dc390_initDCB(pACB, &pDCB, scsi_device->id, scsi_device->lun);
+	if (pDCB != NULL) {
+		scsi_device->hostdata = pDCB;
+		pACB->scan_devices = 1;
+		return 0;
+	}
+	return -ENOMEM;
+}
+
+/**
+ * dc390_slave_destroy - Called by the scsi mid layer to tell us about a
+ * device that is going away.
+ *
+ * @scsi_device: The scsi device that we need to remove.
+ */
+static void dc390_slave_destroy(struct scsi_device *scsi_device)
 {
-    struct pci_dev *pdev = NULL;
-    UCHAR   irq;
-    ULONG   io_port;
+	PACB pACB = (PACB) scsi_device->host->hostdata;
+	PDCB pDCB = (PDCB) scsi_device->hostdata;
+	pACB->scan_devices = 0;
+	if (pDCB != NULL)
+		dc390_remove_dev(pACB, pDCB);
+	else
+		printk(KERN_ERR"%s() called for non-existing device!\n", __FUNCTION__);
+}
 
-    dc390_pACB_start = NULL;
+static int dc390_slave_configure(struct scsi_device *scsi_device)
+{
+	PACB pACB = (PACB) scsi_device->host->hostdata;
+	pACB->scan_devices = 0;
+	return 0;
+}
 
-    if ( PCI_PRESENT )
-	    while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974, pdev)))
-	{
-	    if (pci_enable_device (pdev))
-		continue;
+static Scsi_Host_Template driver_template = {
+	.module			= THIS_MODULE,
+	.proc_name		= "tmscsim", 
+	.proc_info		= DC390_proc_info,
+	.name			= DC390_BANNER " V" DC390_VERSION,
+	.slave_alloc		= dc390_slave_alloc,
+	.slave_configure	= dc390_slave_configure,
+	.slave_destroy		= dc390_slave_destroy,
+	.queuecommand		= DC390_queue_command,
+	.eh_abort_handler	= DC390_abort,
+	.eh_bus_reset_handler	= DC390_reset,
+	.bios_param		= DC390_bios_param,
+	.can_queue		= 42,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 16,
+	.use_clustering		= DISABLE_CLUSTERING,
+};
 
-	    if (pci_set_dma_mask(pdev, 0xffffffff)) {
-		    printk(KERN_ERR "DC390(%i): No suitable DMA available.\n", dc390_adapterCnt);
-		    continue;
-	    }
-	    PCI_GET_IO_AND_IRQ;
-	    DEBUG0(printk(KERN_INFO "DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt, (UINT) io_port, irq));
+static int __devinit dc390_init_one(struct pci_dev *dev,
+				    const struct pci_device_id *id)
+{
+	struct Scsi_Host *scsi_host;
+	unsigned long io_port;
+	u8 irq;
+	PACB  pACB;
+	int ret = -ENOMEM;
+
+	if (pci_enable_device(dev))
+		return -ENODEV;
+
+	io_port = pci_resource_start(dev, 0);
+	irq = dev->irq;
+
+	/* allocate scsi host information (includes out adapter) */
+	scsi_host = scsi_host_alloc(&driver_template, sizeof(struct _ACB));
+	if (!scsi_host)
+		goto nomem;
+
+	pACB = (PACB) scsi_host->hostdata;
+
+	if (dc390_init(scsi_host, io_port, irq, dev, dc390_adapterCnt)) {
+		ret = -EBUSY;
+		goto busy;
+	}
 
-	    if( !DC390_init(psht, io_port, irq, PDEV, dc390_adapterCnt))
-	    {
-		pci_set_master(pdev);
-		dc390_set_pci_cfg (PDEV);
-		dc390_adapterCnt++;
-	    }
+	pci_set_master(dev);
+	dc390_set_pci_cfg(dev);
+	dc390_adapterCnt++;
+
+	/* get the scsi mid level to scan for new devices on the bus */
+	if (scsi_add_host(scsi_host, &dev->dev)) {
+		ret = -ENODEV;
+		goto nodev;
 	}
-    else
-	printk (KERN_ERR "DC390: No PCI BIOS found!\n");
-   
-    if (dc390_adapterCnt)
-	psht->proc_name = "tmscsim";
+	pci_set_drvdata(dev, scsi_host);
+	scsi_scan_host(scsi_host);
+
+	return 0;
+
+nodev:
+busy:
+	scsi_host_put(scsi_host);
+nomem:
+	pci_disable_device(dev);
+	return ret;
+}
+
+/**
+ * dc390_remove_one - Called to remove a single instance of the adapter.
+ *
+ * @dev: The PCI device to remove.
+ */
+static void __devexit dc390_remove_one(struct pci_dev *dev)
+{
+	struct Scsi_Host *scsi_host = pci_get_drvdata(dev);
 
-    printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt);
-    return( dc390_adapterCnt );
+	scsi_remove_host(scsi_host);
+	DC390_release(scsi_host);
+	pci_disable_device(dev);
+	scsi_host_put(scsi_host);
+	pci_set_drvdata(dev, NULL);
 }
 
 /********************************************************************
@@ -2035,7 +2091,7 @@ static int DC390_proc_info (struct Scsi_
   SPRINTF("            Lost arbitrations %i, Sel. connected %i, Connected: %s\n", 
 	  pACB->SelLost, pACB->SelConn, pACB->Connected? "Yes": "No");
    
-  SPRINTF("Nr of attached devices: %i, Nr of DCBs: %i\n", pACB->DeviceCnt, pACB->DCBCnt);
+  SPRINTF("Nr of DCBs: %i\n", pACB->DCBCnt);
   SPRINTF("Map of attached LUNs: %02x %02x %02x %02x %02x %02x %02x %02x\n",
 	  pACB->DCBmap[0], pACB->DCBmap[1], pACB->DCBmap[2], pACB->DCBmap[3], 
 	  pACB->DCBmap[4], pACB->DCBmap[5], pACB->DCBmap[6], pACB->DCBmap[7]);
@@ -2122,7 +2178,7 @@ static int DC390_proc_info (struct Scsi_
 static int dc390_shutdown (struct Scsi_Host *host)
 {
     UCHAR    bval;
-    PACB pACB = (PACB)(host->hostdata);
+    PACB pACB = (PACB) host->hostdata;
    
 /*  pACB->soft_reset(host); */
 
@@ -2142,7 +2198,7 @@ static int dc390_shutdown (struct Scsi_H
 static void dc390_freeDCBs (struct Scsi_Host *host)
 {
     PDCB pDCB, nDCB;
-    PACB pACB = (PACB)(host->hostdata);
+    PACB pACB = (PACB) host->hostdata;
     
     pDCB = pACB->pLinkDCB;
     if (!pDCB) return;
@@ -2161,7 +2217,7 @@ static void dc390_freeDCBs (struct Scsi_
 static int DC390_release (struct Scsi_Host *host)
 {
     DC390_IFLAGS;
-    PACB pACB = (PACB)(host->hostdata);
+    PACB pACB = (PACB) host->hostdata;
 
     DC390_LOCK_IO(host);
 
@@ -2177,24 +2233,25 @@ static int DC390_release (struct Scsi_Ho
     release_region(host->io_port,host->n_io_port);
     dc390_freeDCBs (host);
     DC390_UNLOCK_IO(host);
-    scsi_unregister(host);
     return( 1 );
 }
 
-static Scsi_Host_Template driver_template = {
-   .proc_name      = "tmscsim", 
-   .proc_info      = DC390_proc_info,
-   .name           = DC390_BANNER " V" DC390_VERSION,
-   .detect         = DC390_detect,
-   .release        = DC390_release,
-   .queuecommand   = DC390_queue_command,
-   .eh_abort_handler		= DC390_abort,
-   .eh_bus_reset_handler	= DC390_reset,
-   .bios_param     = DC390_bios_param,
-   .can_queue      = 42,
-   .this_id        = 7,
-   .sg_tablesize   = SG_ALL,
-   .cmd_per_lun    = 16,
-   .use_clustering = DISABLE_CLUSTERING,
+static struct pci_driver dc390_driver = {
+	.name           = "tmscsim",
+	.id_table       = tmscsim_pci_tbl,
+	.probe          = dc390_init_one,
+	.remove         = __devexit_p(dc390_remove_one),
 };
-#include "scsi_module.c"
+
+static int __init dc390_module_init(void)
+{
+	return pci_module_init(&dc390_driver);
+}
+
+static void __exit dc390_module_exit(void)
+{
+	pci_unregister_driver(&dc390_driver);
+}
+
+module_init(dc390_module_init);
+module_exit(dc390_module_exit);
diff -puN drivers/scsi/tmscsim.h~bk-scsi drivers/scsi/tmscsim.h
--- 25/drivers/scsi/tmscsim.h~bk-scsi	2004-06-14 00:10:34.653040240 -0700
+++ 25-akpm/drivers/scsi/tmscsim.h	2004-06-14 00:10:36.133815128 -0700
@@ -22,8 +22,6 @@
 
 #define SEL_TIMEOUT		153	/* 250 ms selection timeout (@ 40 MHz) */
 
-#define END_SCAN		2
-
 #define pci_dma_lo32(a)			(a & 0xffffffff)
 
 typedef u8		UCHAR;	/*  8 bits */
@@ -196,10 +194,8 @@ UCHAR		status;
 
 UCHAR		SRBCount;
 UCHAR		AdapterIndex;	/*; nth Adapter this driver */
-UCHAR		DeviceCnt;
 UCHAR		DCBCnt;
 
-/* 0x10: */
 UCHAR		TagMaxNum;
 UCHAR		ACBFlag;
 UCHAR		Gmode2;
@@ -213,13 +209,11 @@ PDCB		pActiveDCB;
 PSRB		pFreeSRB;
 PSRB		pTmpSRB;
 
-/* 0x2c: */
 UCHAR		msgin123[4];
 UCHAR		DCBmap[MAX_SCSI_ID];
 UCHAR		Connected;
 UCHAR		pad;
 
-/* 0x30: */
 #if defined(USE_SPINLOCKS) && USE_SPINLOCKS > 1 && (defined(CONFIG_SMP) || DEBUG_SPINLOCKS > 0)
 spinlock_t	lock;
 #endif
@@ -230,20 +224,17 @@ UCHAR		MsgLen;
 UCHAR		Ignore_IRQ;	/* Not used */
 
 PDEVDECL1;			/* Pointer to PCI cfg. space */
-/* 0x40/0x3c: */
+
 ULONG		Cmds;
 UINT		SelLost;
 UINT		SelConn;
 UINT		CmdInQ;
 UINT		CmdOutOfSRB;
 	
-/* 0x54/0x50: */
 struct timer_list	Waiting_Timer;
-/* 0x68/0x64: */
+
 DC390_SRB	TmpSRB;
-/* 0xcc/0xc8: */
 DC390_SRB	SRB_array[MAX_SRB_CNT]; 	/* 50 SRBs */
-/* 0xfa4/0xfa0: */
 };
 
 typedef  struct  _ACB	 DC390_ACB, *PACB;
diff -puN drivers/scsi/u14-34f.c~bk-scsi drivers/scsi/u14-34f.c
--- 25/drivers/scsi/u14-34f.c~bk-scsi	2004-06-14 00:10:34.655039936 -0700
+++ 25-akpm/drivers/scsi/u14-34f.c	2004-06-14 00:10:36.135814824 -0700
@@ -423,7 +423,7 @@
 #include <linux/spinlock.h>
 #include <scsi/scsicam.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <asm/dma.h>
 #include <asm/irq.h>
 
diff -puN drivers/scsi/ultrastor.c~bk-scsi drivers/scsi/ultrastor.c
--- 25/drivers/scsi/ultrastor.c~bk-scsi	2004-06-14 00:10:34.657039632 -0700
+++ 25-akpm/drivers/scsi/ultrastor.c	2004-06-14 00:10:36.136814672 -0700
@@ -145,7 +145,7 @@
 
 #define ULTRASTOR_PRIVATE	/* Get the private stuff from ultrastor.h */
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include "ultrastor.h"
 
 #define FALSE 0
diff -puN drivers/scsi/wd33c93.c~bk-scsi drivers/scsi/wd33c93.c
--- 25/drivers/scsi/wd33c93.c~bk-scsi	2004-06-14 00:10:34.658039480 -0700
+++ 25-akpm/drivers/scsi/wd33c93.c	2004-06-14 00:10:36.138814368 -0700
@@ -83,7 +83,7 @@
 #include <asm/irq.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "wd33c93.h"
 
diff -puN drivers/scsi/wd7000.c~bk-scsi drivers/scsi/wd7000.c
--- 25/drivers/scsi/wd7000.c~bk-scsi	2004-06-14 00:10:34.660039176 -0700
+++ 25-akpm/drivers/scsi/wd7000.c	2004-06-14 00:10:36.139814216 -0700
@@ -184,7 +184,7 @@
 #include <asm/io.h>
 
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <scsi/scsicam.h>
 
 
diff -puN drivers/scsi/zalon.c~bk-scsi drivers/scsi/zalon.c
--- 25/drivers/scsi/zalon.c~bk-scsi	2004-06-14 00:10:34.662038872 -0700
+++ 25-akpm/drivers/scsi/zalon.c	2004-06-14 00:10:36.140814064 -0700
@@ -24,7 +24,7 @@
 
 #include "../parisc/gsc.h"
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 
 #include "ncr53c8xx.h"
 
diff -puN drivers/usb/storage/scsiglue.c~bk-scsi drivers/usb/storage/scsiglue.c
--- 25/drivers/usb/storage/scsiglue.c~bk-scsi	2004-06-14 00:10:34.663038720 -0700
+++ 25-akpm/drivers/usb/storage/scsiglue.c	2004-06-14 00:10:36.140814064 -0700
@@ -409,6 +409,9 @@ struct scsi_host_template usb_stor_host_
 	/* emulated HBA */
 	.emulated =			TRUE,
 
+	/* we do our own delay after a device or bus reset */
+	.skip_settle_delay =		1,
+
 	/* sysfs device attributes */
 	.sdev_attrs =			sysfs_device_attr_list,
 
diff -puN include/linux/i2o.h~bk-scsi include/linux/i2o.h
--- 25/include/linux/i2o.h~bk-scsi	2004-06-14 00:10:34.665038416 -0700
+++ 25-akpm/include/linux/i2o.h	2004-06-14 00:10:36.141813912 -0700
@@ -99,6 +99,7 @@ struct i2o_controller
 	int		irq;
 	int		short_req:1;	/* Use small block sizes        */
 	int		dpt:1;		/* Don't quiesce                */
+	int		raptor:1;	/* split bar                    */
 	int		promise:1;	/* Promise controller		*/
 #ifdef CONFIG_MTRR
 	int		mtrr_reg0;
@@ -109,9 +110,9 @@ struct i2o_controller
 	atomic_t users;
 	struct i2o_device *devices;		/* I2O device chain */
 	struct i2o_controller *next;		/* Controller chain */
-	unsigned long post_port;		/* Inbout port address */
-	unsigned long reply_port;		/* Outbound port address */
-	unsigned long irq_mask;			/* Interrupt register address */
+	void *post_port;			/* Inbout port address */
+	void *reply_port;			/* Outbound port address */
+	void *irq_mask;				/* Interrupt register address */
 
 	/* Dynamic LCT related data */
 	struct semaphore lct_sem;
@@ -128,8 +129,11 @@ struct i2o_controller
 	dma_addr_t hrt_phys;
 	u32 hrt_len;
 
-	unsigned long mem_offset;		/* MFA offset */
-	unsigned long mem_phys;			/* MFA physical */
+	void *base_virt;			/* base virtual address */
+	unsigned long base_phys;		/* base physical address */
+
+	void *msg_virt;				/* messages virtual address */
+	unsigned long msg_phys;			/* messages physical address */
 
 	int battery:1;				/* Has a battery backup */
 	int io_alloc:1;				/* An I/O resource was allocated */
diff -puN include/linux/pci_ids.h~bk-scsi include/linux/pci_ids.h
--- 25/include/linux/pci_ids.h~bk-scsi	2004-06-14 00:10:34.666038264 -0700
+++ 25-akpm/include/linux/pci_ids.h	2004-06-14 00:10:36.143813608 -0700
@@ -1770,6 +1770,8 @@
 
 #define PCI_VENDOR_ID_3WARE		0x13C1
 #define PCI_DEVICE_ID_3WARE_1000	0x1000
+#define PCI_DEVICE_ID_3WARE_7000	0x1001
+#define PCI_DEVICE_ID_3WARE_9000	0x1002
 
 #define PCI_VENDOR_ID_IOMEGA		0x13ca
 #define PCI_DEVICE_ID_IOMEGA_BUZ	0x4231
diff -puN /dev/null include/scsi/scsi_dbg.h
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/include/scsi/scsi_dbg.h	2004-06-14 00:10:36.144813456 -0700
@@ -0,0 +1,18 @@
+#ifndef _SCSI_SCSI_DBG_H
+#define _SCSI_SCSI_DBG_H
+
+struct scsi_cmnd;
+struct scsi_request;
+
+extern void scsi_print_command(struct scsi_cmnd *);
+extern void __scsi_print_command(unsigned char *);
+extern void scsi_print_sense(const char *, struct scsi_cmnd *);
+extern void scsi_print_req_sense(const char *, struct scsi_request *);
+extern void scsi_print_driverbyte(int);
+extern void scsi_print_hostbyte(int);
+extern void scsi_print_status(unsigned char);
+extern int scsi_print_msg(const unsigned char *);
+extern const char *scsi_sense_key_string(unsigned char);
+extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
+
+#endif /* _SCSI_SCSI_DBG_H */
diff -puN include/scsi/scsi_eh.h~bk-scsi include/scsi/scsi_eh.h
--- 25/include/scsi/scsi_eh.h~bk-scsi	2004-06-14 00:10:34.671037504 -0700
+++ 25-akpm/include/scsi/scsi_eh.h	2004-06-14 00:10:36.144813456 -0700
@@ -1,6 +1,10 @@
 #ifndef _SCSI_SCSI_EH_H
 #define _SCSI_SCSI_EH_H
 
+struct scsi_cmnd;
+struct scsi_device;
+struct Scsi_Host;
+
 extern void scsi_add_timer(struct scsi_cmnd *, int,
 			   void (*)(struct scsi_cmnd *));
 extern int scsi_delete_timer(struct scsi_cmnd *);
diff -puN include/scsi/scsi_host.h~bk-scsi include/scsi/scsi_host.h
--- 25/include/scsi/scsi_host.h~bk-scsi	2004-06-14 00:10:34.673037200 -0700
+++ 25-akpm/include/scsi/scsi_host.h	2004-06-14 00:10:36.145813304 -0700
@@ -151,7 +151,7 @@ struct scsi_host_template {
 	 * here then you will get a call to slave_configure(), then the
 	 * device will be used for however long it is kept around, then when
 	 * the device is removed from the system (or * possibly at reboot
-	 * time), you will then get a call to slave_detach().  This is
+	 * time), you will then get a call to slave_destroy().  This is
 	 * assuming you implement slave_configure and slave_destroy.
 	 * However, if you allocate memory and hang it off the device struct,
 	 * then you must implement the slave_destroy() routine at a minimum
@@ -185,7 +185,7 @@ struct scsi_host_template {
 	 *     specific setup basis...
 	 * 6.  Return 0 on success, non-0 on error.  The device will be marked
 	 *     as offline on error so that no access will occur.  If you return
-	 *     non-0, your slave_detach routine will never get called for this
+	 *     non-0, your slave_destroy routine will never get called for this
 	 *     device, so don't leave any loose memory hanging around, clean
 	 *     up after yourself before returning non-0
 	 *
@@ -314,6 +314,11 @@ struct scsi_host_template {
 	unsigned emulated:1;
 
 	/*
+	 * True if the low-level driver performs its own reset-settle delays.
+	 */
+	unsigned skip_settle_delay:1;
+
+	/*
 	 * Countdown for host blocking with no commands outstanding
 	 */
 	unsigned int max_host_blocked;
diff -puN MAINTAINERS~bk-scsi MAINTAINERS
--- 25/MAINTAINERS~bk-scsi	2004-06-14 00:10:34.674037048 -0700
+++ 25-akpm/MAINTAINERS	2004-06-14 00:10:34.686035224 -0700
@@ -90,6 +90,20 @@ M:	dave@thedillows.org
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
+3W-XXXX ATA-RAID CONTROLLER DRIVER
+P:	Adam Radford
+M:	linuxraid@amcc.com
+L:	linux-scsi@vger.kernel.org
+W:	http://www.amcc.com
+S:	Supported
+
+3W-9XXX SATA-RAID CONTROLLER DRIVER
+P:	Adam Radford
+M:	linuxraid@amcc.com
+L:	linux-scsi@vger.kernel.org
+W:	http://www.amcc.com
+S:	Supported
+
 53C700 AND 53C700-66 SCSI DRIVER
 P:	James E.J. Bottomley
 M:	James.Bottomley@HansenPartnership.com
_