From: Eric Moore <emoore@lsil.com>

Here's an driver update for mpt fusion driver version 3.00.00.

If you find this inline patch malformed,
please kindly download this patch from this URL:

ftp://ftp.lsil.com/HostAdapterDrivers/linux/Fusion-MPT/2.6-patches/

3.00.00 changes
* added new PCI API support
* added ACPI support
* added CONFIG_LBA, READ16, WRITE16 support
* underun fix
* chain buffer free list not being init properly
* reduce task management
    (abort=2sec,reset bus=5sec, timeout=10sec)



 drivers/message/fusion/mptbase.c  |  386 ++++++++++++++++++++++++++++----------
 drivers/message/fusion/mptbase.h  |   10 
 drivers/message/fusion/mptscsih.c |  251 +++++++++++++++++-------
 drivers/message/fusion/mptscsih.h |   10 
 4 files changed, 472 insertions(+), 185 deletions(-)

diff -puN drivers/message/fusion/mptbase.c~mpt-fusion-update drivers/message/fusion/mptbase.c
--- 25/drivers/message/fusion/mptbase.c~mpt-fusion-update	2004-01-06 21:22:08.000000000 -0800
+++ 25-akpm/drivers/message/fusion/mptbase.c	2004-01-06 21:22:08.000000000 -0800
@@ -167,6 +167,7 @@ static int			 MptDriverClass[MPT_MAX_PRO
 static MPT_EVHANDLER		 MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 					/* Reset handler lookup table */
 static MPT_RESETHANDLER		 MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
+static MPT_DVHANDLER		 MptDvHandler[MPT_MAX_PROTOCOL_DRIVERS];
 
 static int	FusionInitCalled = 0;
 static int	mpt_base_index = -1;
@@ -183,7 +184,6 @@ static irqreturn_t mpt_interrupt(int irq
 static int	mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
 
 static int	mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
-static int	mpt_adapter_install(struct pci_dev *pdev);
 static void	mpt_detect_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
 static void	mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup);
 static void	mpt_adapter_dispose(MPT_ADAPTER *ioc);
@@ -232,8 +232,11 @@ static int	ProcessEventNotification(MPT_
 static void	mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
 static void	mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
 
-int		fusion_init(void);
-static void	fusion_exit(void);
+/* module entry point */
+static int  __devinit mptbase_probe (struct pci_dev *, const struct pci_device_id *);
+static void __devexit mptbase_remove(struct pci_dev *);
+static int  __init    fusion_init  (void);
+static void __exit    fusion_exit  (void);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -260,6 +263,80 @@ struct _mpt_ioc_proc_list {
 
 #endif
 
+/****************************************************************************
+ * Supported hardware
+ */
+#define	DEVT_INDEX_MPT		0x0000		/* Fusion MPT Interface */
+
+static struct pci_device_id mptbase_pci_table[] = {
+	{
+		.vendor		= PCI_VENDOR_ID_LSI_LOGIC,
+		.device		= PCI_DEVICE_ID_LSI_FC909,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.class		= PCI_CLASS_SERIAL_FIBER << 8,
+		.class_mask	= 0xFFFF00,
+		.driver_data	= DEVT_INDEX_MPT
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_LSI_LOGIC,
+		.device		= PCI_DEVICE_ID_LSI_FC929,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.class		= PCI_CLASS_SERIAL_FIBER << 8,
+		.class_mask	= 0xFFFF00,
+		.driver_data	= DEVT_INDEX_MPT
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_LSI_LOGIC,
+		.device		= PCI_DEVICE_ID_LSI_FC919,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.class		= PCI_CLASS_SERIAL_FIBER << 8,
+		.class_mask	= 0xFFFF00,
+		.driver_data	= DEVT_INDEX_MPT
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_LSI_LOGIC,
+		.device		= PCI_DEVICE_ID_LSI_FC929X,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.class		= PCI_CLASS_SERIAL_FIBER << 8,
+		.class_mask	= 0xFFFF00,
+		.driver_data	= DEVT_INDEX_MPT
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_LSI_LOGIC,
+		.device		= PCI_DEVICE_ID_LSI_FC919X,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.class		= PCI_CLASS_SERIAL_FIBER << 8,
+		.class_mask	= 0xFFFF00,
+		.driver_data	= DEVT_INDEX_MPT
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_LSI_LOGIC,
+		.device		= PCI_DEVICE_ID_LSI_53C1030,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.class		= PCI_CLASS_STORAGE_SCSI << 8,
+		.class_mask	= 0xFFFF00,
+		.driver_data	= DEVT_INDEX_MPT
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_LSI_LOGIC,
+		.device		= PCI_DEVICE_ID_LSI_1030_53C1035,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.class		= PCI_CLASS_STORAGE_SCSI << 8,
+		.class_mask	= 0xFFFF00,
+		.driver_data	= DEVT_INDEX_MPT
+	},
+	{0}	/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(pci, mptbase_pci_table);
+
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /* 20000207 -sralston
  *  GRRRRR...  IOSpace (port i/o) register access (for the 909) is back!
@@ -803,6 +880,36 @@ mpt_reset_deregister(int cb_idx)
 	MptResetHandlers[cb_idx] = NULL;
 }
 
+
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mpt_dv_register - Register protocol-specific domain validation handler.
+ */
+int mpt_dv_register(MPT_DVHANDLER dv_cbfunc, int cb_idx)
+{
+	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
+		return -1;
+
+	MptDvHandler[cb_idx] = dv_cbfunc;
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mpt_dv_deregister - Deregister protocol-specific domain validation handler.
+ */
+void
+mpt_dv_deregister(int cb_idx)
+{
+	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
+		return;
+
+	MptDvHandler[cb_idx] = NULL;
+}
+#endif
+
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
@@ -1142,88 +1249,6 @@ mpt_adapter_find_next(MPT_ADAPTER *prev)
 	return next;
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	mpt_pci_scan - Scan PCI devices for MPT adapters.
- *
- *	Returns count of MPT adapters found, keying off of PCI vendor and
- *	device_id's.
- */
-static int __init
-mpt_pci_scan(void)
-{
-	struct pci_dev *pdev = NULL;
-	struct pci_dev *pdev2;
-	int found = 0;
-	int count = 0;
-	int r;
-
-	dprintk((KERN_INFO MYNAM ": Checking for MPT adapters...\n"));
-
-	/*
-	 *  NOTE: The 929, 929X, 1030 and 1035 will appear as 2 separate PCI devices,
-	 *  one for each channel.
-	 */
-	while ((pdev = pci_find_device(PCI_VENDOR_ID_LSI_LOGIC, PCI_ANY_ID, pdev)) != NULL) {
-		pdev2 = NULL;
-		if ((pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC909) &&
-		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929) &&
-		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919) &&
-		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929X) &&
-		    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919X) &&
-		    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
-		    (pdev->device != MPI_MANUFACTPAGE_DEVID_1030_53C1035) &&
-		    1) {
-			dprintk((KERN_INFO MYNAM ": Skipping LSI device=%04xh\n", pdev->device));
-			continue;
-		}
-
-		/* GRRRRR
-		 * dual function devices (929, 929X, 1030, 1035) may be presented in Func 1,0 order,
-		 * but we'd really really rather have them in Func 0,1 order.
-		 * Do some kind of look ahead here...
-		 */
-		if (pdev->devfn & 1) {
-			pdev2 = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev);
-			if (pdev2 && (pdev2->vendor == 0x1000) &&
-			    (PCI_SLOT(pdev2->devfn) == PCI_SLOT(pdev->devfn)) &&
-			    (pdev2->device == pdev->device) &&
-			    (pdev2->bus->number == pdev->bus->number) &&
-			    !(pdev2->devfn & 1)) {
-				dprintk((KERN_INFO MYNAM ": MPT adapter found: PCI bus/dfn=%02x/%02xh, class=%08x, id=%xh\n",
-					pdev2->bus->number, pdev2->devfn, pdev2->class, pdev2->device));
-				found++;
-				if ((r = mpt_adapter_install(pdev2)) == 0)
-					count++;
-			} else {
-				pdev2 = NULL;
-			}
-		}
-
-		dprintk((KERN_INFO MYNAM ": MPT adapter found: PCI bus/dfn=%02x/%02xh, class=%08x, id=%xh\n",
-			 pdev->bus->number, pdev->devfn, pdev->class, pdev->device));
-		found++;
-		if ((r = mpt_adapter_install(pdev)) == 0)
-			count++;
-
-		if (pdev2)
-			pdev = pdev2;
-	}
-
-	printk(KERN_INFO MYNAM ": %d MPT adapter%s found, %d installed.\n",
-		 found, (found==1) ? "" : "s", count);
-
-	if (!found || !count) {
-		fusion_exit();
-		return -ENODEV;
-	}
-
-#ifdef CONFIG_PROC_FS
-	(void) procmpt_create();
-#endif
-
-	return count;
-}
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
@@ -1253,7 +1278,7 @@ mpt_verify_adapter(int iocid, MPT_ADAPTE
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mpt_adapter_install - Install a PCI intelligent MPT adapter.
+ *	mptbase_probe - Install a PCI intelligent MPT adapter.
  *	@pdev: Pointer to pci_dev structure
  *
  *	This routine performs all the steps necessary to bring the IOC of
@@ -1268,8 +1293,8 @@ mpt_verify_adapter(int iocid, MPT_ADAPTE
  *
  *	TODO: Add support for polled controllers
  */
-static int __init
-mpt_adapter_install(struct pci_dev *pdev)
+static int
+__devinit mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	MPT_ADAPTER	*ioc;
 	u8		*mem;
@@ -1292,6 +1317,13 @@ mpt_adapter_install(struct pci_dev *pdev
 		return r;
 	}
 
+	if (!pci_set_consistent_dma_mask(pdev, mask))
+		dprintk((KERN_INFO MYNAM
+			": Using 64 bit consistent mask\n"));
+	else
+		dprintk((KERN_INFO MYNAM
+			": Not using 64 bit consistent mask\n"));
+
 	ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
 	if (ioc == NULL) {
 		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
@@ -1500,6 +1532,7 @@ mpt_adapter_install(struct pci_dev *pdev
 		ioc->pci_irq = pdev->irq;
 
 		pci_set_master(pdev);			/* ?? */
+		pci_set_drvdata(pdev, ioc);
 
 #ifndef __sparc__
 		dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
@@ -1525,6 +1558,146 @@ mpt_adapter_install(struct pci_dev *pdev
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
+ *	mptbase_remove - Remove a PCI intelligent MPT adapter.
+ *	@pdev: Pointer to pci_dev structure
+ *
+ */
+
+static void
+__devexit mptbase_remove(struct pci_dev *pdev)
+{
+	mptscsih_sync_irq(pdev->irq);
+	pci_set_drvdata(pdev, NULL);
+}
+
+
+/**************************************************************************
+ * Power Management
+ */
+#ifdef CONFIG_PM
+#include <acpi/acpi_drivers.h>
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptbase_suspend - Fusion MPT base driver suspend routine.
+ *
+ *
+ */
+static int mptbase_suspend(struct pci_dev *pdev, u32 state)
+{
+	u32 device_state;
+	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+
+	switch(state)
+	{
+		case ACPI_STATE_S1:
+			device_state=ACPI_STATE_D1;
+			break;
+		case ACPI_STATE_S3:
+		case ACPI_STATE_S4:
+			device_state=ACPI_STATE_D3;
+			break;
+		default:
+			return -EAGAIN /*FIXME*/;
+			break;
+	}
+
+	printk(MYIOC_s_INFO_FMT
+	"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
+		ioc->name, pdev, pci_name(pdev), device_state);
+
+	pci_save_state(pdev, ioc->PciState);
+
+	/* put ioc into READY_STATE */
+	if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
+		printk(MYIOC_s_ERR_FMT
+		"pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
+	}
+
+	/* disable interrupts */
+	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+	ioc->active = 0;
+
+	/* Clear any lingering interrupt */
+	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, device_state);
+
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptbase_resume - Fusion MPT base driver resume routine.
+ *
+ *
+ */
+static int mptbase_resume(struct pci_dev *pdev)
+{
+	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+	u32 device_state = pdev->current_state;
+	int do_domain_validation_flag=0;
+	int recovery_state;
+
+	printk(MYIOC_s_INFO_FMT
+	"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
+		ioc->name, pdev, pci_name(pdev), device_state);
+
+	pci_set_power_state(pdev, ACPI_STATE_D0);
+	pci_restore_state(pdev, ioc->PciState);
+	pci_enable_device(pdev);
+
+	/* enable interrupts */
+	CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
+	ioc->active = 1;
+
+	/* F/W not running */
+	if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
+		do_domain_validation_flag=1;
+	}
+
+	printk(MYIOC_s_INFO_FMT
+		"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
+		ioc->name,
+		(mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
+		CHIPREG_READ32(&ioc->chip->Doorbell));
+
+	/* bring ioc to operational state */
+	if ((recovery_state = mpt_do_ioc_recovery(ioc,
+	    MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
+		printk(MYIOC_s_INFO_FMT
+			"pci-resume: Cannot recover, error:[%x]\n",
+			ioc->name, recovery_state);
+	} else {
+		printk(MYIOC_s_INFO_FMT
+			"pci-resume: success\n", ioc->name);
+	}
+
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+	if(do_domain_validation_flag) {
+		int ii;
+
+		for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
+			ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
+		}
+
+		for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
+			if(MptDvHandler[ii]) {
+				printk(MYIOC_s_INFO_FMT
+				"pci-resume: domain validation\n",ioc->name);
+				(*(MptDvHandler[ii]))(NULL);
+			}
+		}
+	}
+#endif
+	return 0;
+}
+
+#endif
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
  *	mpt_do_ioc_recovery - Initialize or recover MPT adapter.
  *	@ioc: Pointer to MPT adapter structure
  *	@reason: Event word / reason
@@ -5851,6 +6024,8 @@ EXPORT_SYMBOL(mpt_event_register);
 EXPORT_SYMBOL(mpt_event_deregister);
 EXPORT_SYMBOL(mpt_reset_register);
 EXPORT_SYMBOL(mpt_reset_deregister);
+EXPORT_SYMBOL(mpt_dv_register);
+EXPORT_SYMBOL(mpt_dv_deregister);
 EXPORT_SYMBOL(mpt_get_msg_frame);
 EXPORT_SYMBOL(mpt_put_msg_frame);
 EXPORT_SYMBOL(mpt_free_msg_frame);
@@ -5877,16 +6052,29 @@ EXPORT_SYMBOL(mpt_v_ASCQ_TablePtr);
 EXPORT_SYMBOL(mpt_ASCQ_TableSz);
 EXPORT_SYMBOL(mpt_ScsiOpcodesPtr);
 
+
+static struct pci_driver mptbase_driver = {
+	.name		= "mptbase",
+	.id_table	= mptbase_pci_table,
+	.probe		= mptbase_probe,
+	.remove		= __devexit_p(mptbase_remove),
+#ifdef CONFIG_PM
+	.suspend	= mptbase_suspend,
+	.resume		= mptbase_resume,
+#endif
+};
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	fusion_init - Fusion MPT base driver initialization routine.
  *
  *	Returns 0 for success, non-zero for failure.
  */
-int __init
-fusion_init(void)
+static int
+__init fusion_init(void)
 {
 	int i;
+	int r;
 
 	if (FusionInitCalled++) {
 		dprintk((KERN_INFO MYNAM ": INFO - Driver late-init entry point called\n"));
@@ -5920,10 +6108,13 @@ fusion_init(void)
 		/* FIXME! */
 	}
 
-	if ((i = mpt_pci_scan()) < 0)
-		return i;
+	r = pci_module_init(&mptbase_driver);
 
-	return 0;
+#ifdef CONFIG_PROC_FS
+	(void) procmpt_create();
+#endif
+
+	return r;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5934,13 +6125,14 @@ fusion_init(void)
  *	and removes all %MPT_PROCFS_MPTBASEDIR entries.
  */
 static void
-fusion_exit(void)
+__exit fusion_exit(void)
 {
 	MPT_ADAPTER *this;
-	struct pci_dev *pdev = NULL;
 
 	dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
 
+	pci_unregister_driver(&mptbase_driver);
+
 	/* Whups?  20010120 -sralston
 	 *  Moved this *above* removal of all MptAdapters!
 	 */
@@ -5956,9 +6148,6 @@ fusion_exit(void)
 
 		this->active = 0;
 
-		pdev = (struct pci_dev *)this->pcidev;
-		mptscsih_sync_irq(pdev->irq);
-
 		/* Clear any lingering interrupt */
 		CHIPREG_WRITE32(&this->chip->IntStatus, 0);
 
@@ -5971,7 +6160,6 @@ fusion_exit(void)
 	mpt_reset_deregister(mpt_base_index);
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
 module_init(fusion_init);
 module_exit(fusion_exit);
diff -puN drivers/message/fusion/mptbase.h~mpt-fusion-update drivers/message/fusion/mptbase.h
--- 25/drivers/message/fusion/mptbase.h~mpt-fusion-update	2004-01-06 21:22:08.000000000 -0800
+++ 25-akpm/drivers/message/fusion/mptbase.h	2004-01-06 21:22:08.000000000 -0800
@@ -80,8 +80,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2003 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"2.05.00.05"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-2.05.00.05"
+#define MPT_LINUX_VERSION_COMMON	"3.00.00"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.00.00"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -629,6 +629,9 @@ typedef struct _MPT_ADAPTER
 	FCPortPage0_t		 fc_port_page0[2];
 	LANPage0_t		 lan_cnfg_page0;
 	LANPage1_t		 lan_cnfg_page1;
+#ifdef CONFIG_PM
+	u32           		 PciState[64];     /* save PCI state to this area */
+#endif
 	u8			 FirstWhoInit;
 	u8			 upload_fw;	/* If set, do a fw upload */
 	u8			 reload_fw;	/* Force a FW Reload on next reset */
@@ -649,6 +652,7 @@ typedef struct _MPT_ADAPTER_TRACKER {
 typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
 typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply);
 typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
+typedef void (*MPT_DVHANDLER)(void *arg);
 /* reset_phase defs */
 #define MPT_IOC_PRE_RESET		0
 #define MPT_IOC_POST_RESET		1
@@ -1001,6 +1005,8 @@ extern int	 mpt_event_register(int cb_id
 extern void	 mpt_event_deregister(int cb_idx);
 extern int	 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
 extern void	 mpt_reset_deregister(int cb_idx);
+extern int	 mpt_dv_register(MPT_DVHANDLER dv_cbfunc, int cb_idx);
+extern void	 mpt_dv_deregister(int cb_idx);
 extern int	 mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable);
 extern void	 mpt_deregister_ascqops_strings(void);
 extern MPT_FRAME_HDR	*mpt_get_msg_frame(int handle, int iocid);
diff -puN drivers/message/fusion/mptscsih.c~mpt-fusion-update drivers/message/fusion/mptscsih.c
--- 25/drivers/message/fusion/mptscsih.c~mpt-fusion-update	2004-01-06 21:22:08.000000000 -0800
+++ 25-akpm/drivers/message/fusion/mptscsih.c	2004-01-06 21:22:08.000000000 -0800
@@ -164,8 +164,8 @@ static u32	SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd
 static MPT_FRAME_HDR *mptscsih_search_pendingQ(MPT_SCSI_HOST *hd, int scpnt_idx);
 static void	post_pendingQ_commands(MPT_SCSI_HOST *hd);
 
-static int	mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag);
-static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag);
+static int	mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
+static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag);
 
 static int	mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 static int	mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
@@ -196,6 +196,12 @@ static void	mptscsih_fillbuf(char *buffe
 static int	mptscsih_setup(char *str);
 static int	mptscsih_halt(struct notifier_block *nb, ulong event, void *buf);
 
+/* module entry point */
+static int  __init    mptscsih_init  (void);
+static void __exit    mptscsih_exit  (void);
+int mptscsih_release(struct Scsi_Host *host);
+
+
 /*
  *	Reboot Notification
  */
@@ -238,6 +244,34 @@ static struct mptscsih_driver_setup
 	driver_setup = MPTSCSIH_DRIVER_SETUP;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+/* see mptscsih.h */
+
+#ifdef MPT_SCSIHOST_NEED_ENTRY_EXIT_HOOKUPS
+static 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,
+};
+#endif
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Private inline routines...
  */
@@ -264,12 +298,14 @@ static inline int
 mptscsih_io_direction(Scsi_Cmnd *cmd)
 {
 	switch (cmd->cmnd[0]) {
-	case WRITE_6:		
-	case WRITE_10:		
+	case WRITE_6:
+	case WRITE_10:
+	case WRITE_16:
 		return SCSI_DATA_WRITE;
 		break;
-	case READ_6:		
-	case READ_10:		
+	case READ_6:
+	case READ_10:
+	case READ_16:
 		return SCSI_DATA_READ;
 		break;
 	}
@@ -280,6 +316,7 @@ mptscsih_io_direction(Scsi_Cmnd *cmd)
 	switch (cmd->cmnd[0]) {
 	/*  _DATA_OUT commands	*/
 	case WRITE_6:		case WRITE_10:		case WRITE_12:
+	case WRITE_16:
 	case WRITE_LONG:	case WRITE_SAME:	case WRITE_BUFFER:
 	case WRITE_VERIFY:	case WRITE_VERIFY_12:
 	case COMPARE:		case COPY:		case COPY_VERIFY:
@@ -826,6 +863,13 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 			sc->resid = sc->request_bufflen - xfer_cnt;
 			dprintk((KERN_NOTICE "  SET sc->resid=%02xh\n", sc->resid));
 
+			if(sc->underflow > xfer_cnt) {
+				printk(MYIOC_s_INFO_FMT
+				"SCSI data underrun: underflow=%02x, xfercnt=%02x\n",
+				ioc->name, sc->underflow, xfer_cnt);
+				sc->result = DID_SOFT_ERROR << 16;
+			}
+
 			/* Report Queue Full
 			 */
 			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
@@ -1231,8 +1275,9 @@ mptscsih_initChainBuffers (MPT_SCSI_HOST
 	} else {
 		mem = (u8 *) hd->ReqToChain;
 	}
-	memset(mem, 0xFF, sz);
-
+/*	memset(mem, 0xFF, sz); */
+	for(ii=0;ii<hd->ioc->req_depth;ii++)
+		hd->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
 
 	/* ChainToChain size must equal the total number
 	 * of chain buffers to be allocated.
@@ -1275,7 +1320,6 @@ mptscsih_initChainBuffers (MPT_SCSI_HOST
 		mem = (u8 *) hd->ChainToChain;
 	}
 	memset(mem, 0xFF, sz);
-
 	sz = num_chain * hd->ioc->req_sz;
 	if (hd->ChainBuffer == NULL) {
 		/* Allocate free chain buffer pool
@@ -1357,18 +1401,13 @@ static char *info_kbuf = NULL;
 /*  SCSI host fops start here...  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_detect - Register MPT adapter(s) as SCSI host(s) with
+ *	mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
  *	linux scsi mid-layer.
- *	@tpnt: Pointer to Scsi_Host_Template structure
  *
- *	(linux Scsi_Host_Template.detect routine)
- *
- *	Returns number of SCSI host adapters that were successfully
- *	registered with the linux scsi mid-layer via the scsi_register()
- *	API call.
+ *	Returns 0 for success, non-zero for failure.
  */
-int
-mptscsih_detect(Scsi_Host_Template *tpnt)
+static int
+__init mptscsih_init(void)
 {
 	struct Scsi_Host	*sh = NULL;
 	MPT_SCSI_HOST		*hd = NULL;
@@ -1387,6 +1426,12 @@ mptscsih_detect(Scsi_Host_Template *tpnt
 		ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
 		ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
 
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+		if(mpt_dv_register(mptscsih_domainValidation, MPTSCSIH_DRIVER) != 0 ) {
+			dprintk((KERN_INFO MYNAM
+			": failed to register dv callback\n"));
+		}
+#endif
 		if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
 			dprintk((KERN_INFO MYNAM ": Registered for IOC event notifications\n"));
 		} else {
@@ -1431,14 +1476,17 @@ mptscsih_detect(Scsi_Host_Template *tpnt
 				continue;
 			}
 
-			tpnt->proc_info = mptscsih_proc_info;
-			sh = scsi_register(tpnt, sizeof(MPT_SCSI_HOST));
+			sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
 			if (sh != NULL) {
 				spin_lock_irqsave(&this->FreeQlock, flags);
 				sh->io_port = 0;
 				sh->n_io_port = 0;
 				sh->irq = 0;
 
+				/* set 16 byte cdb's
+				*/
+				sh->max_cmd_len = 16;
+
 				/* Yikes!  This is important!
 				 * Otherwise, by default, linux
 				 * only scans target IDs 0-7!
@@ -1634,7 +1682,7 @@ mptscsih_detect(Scsi_Host_Template *tpnt
 					hd->ioc->spi_data.forceDv = 0;
 					for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
 						hd->ioc->spi_data.dvStatus[ii] = MPT_SCSICFG_NEGOTIATE;
-	
+
 					if (hd->negoNvram == 0) {
 						for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
 							hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_NOT_DONE;
@@ -1649,6 +1697,10 @@ mptscsih_detect(Scsi_Host_Template *tpnt
 				}
 
 				mpt_scsi_hosts++;
+
+				scsi_add_host (sh, &this->pcidev->dev);
+				scsi_scan_host(sh);
+
 			}
 
 		}	/* for each adapter port */
@@ -1657,24 +1709,62 @@ mptscsih_detect(Scsi_Host_Template *tpnt
 	}
 
 done:
-	if (mpt_scsi_hosts > 0)
+	if (mpt_scsi_hosts > 0) {
 		register_reboot_notifier(&mptscsih_notifier);
-	else {
+		return 0;
+	} else {
 		mpt_reset_deregister(ScsiDoneCtx);
 		dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
 
 		mpt_event_deregister(ScsiDoneCtx);
 		dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));
 
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+		mpt_dv_deregister(MPTSCSIH_DRIVER);
+#endif
 		mpt_deregister(ScsiScanDvCtx);
 		mpt_deregister(ScsiTaskCtx);
 		mpt_deregister(ScsiDoneCtx);
 
 		if (info_kbuf != NULL)
 			kfree(info_kbuf);
+
+		return -EBUSY;
 	}
 
-	return mpt_scsi_hosts;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_exit - Unregisters MPT adapter(s)
+ *
+ */
+static void
+__exit mptscsih_exit(void)
+{
+	MPT_ADAPTER		*this;
+	struct Scsi_Host	*sh = NULL;
+
+	this = mpt_adapter_find_first();
+	while (this != NULL) {
+
+		if (this->last_state != MPI_IOC_STATE_OPERATIONAL) {
+			this = mpt_adapter_find_next(this);
+			continue;
+		}
+
+		sh = this->sh;
+		if( sh == NULL ) {
+			continue;
+		}
+
+		scsi_remove_host(sh);
+		mptscsih_release(sh);
+		scsi_host_put(sh);
+		this->sh = NULL;
+		this = mpt_adapter_find_next(this);
+	}
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1801,7 +1891,6 @@ mptscsih_release(struct Scsi_Host *host)
 	/* NULL the Scsi_Host pointer
 	 */
 	hd->ioc->sh = NULL;
-	scsi_unregister(host);
 
 	if (mpt_scsi_hosts) {
 		if (--mpt_scsi_hosts == 0) {
@@ -1811,6 +1900,10 @@ mptscsih_release(struct Scsi_Host *host)
 			mpt_event_deregister(ScsiDoneCtx);
 			dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));
 
+#ifndef MPTSCSIH_DISABLE_DOMAIN_VALIDATION
+			mpt_dv_deregister(MPTSCSIH_DRIVER);
+#endif
+
 			mpt_deregister(ScsiScanDvCtx);
 			mpt_deregister(ScsiTaskCtx);
 			mpt_deregister(ScsiDoneCtx);
@@ -2606,7 +2699,7 @@ mptscsih_freeChainBuffers(MPT_SCSI_HOST 
  *	Returns 0 for SUCCESS or -1 if FAILED.
  */
 static int
-mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag)
+mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
 {
 	MPT_ADAPTER	*ioc = NULL;
 	int		 rc = -1;
@@ -2662,7 +2755,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8
 		 */
 		if (hd->hard_resets < -1)
 			hd->hard_resets++;
-		rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, sleepFlag);
+		rc = mptscsih_IssueTaskMgmt(hd, type, target, lun, ctx2abort, timeout, sleepFlag);
 		if (rc) {
 			printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
 		} else {
@@ -2708,7 +2801,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8
  *	else other non-zero value returned.
  */
 static int
-mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, int sleepFlag)
+mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag)
 {
 	MPT_FRAME_HDR	*mf;
 	SCSITaskMgmt_t	*pScsiTm;
@@ -2758,7 +2851,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd
 	*/
 	hd->tmPtr = mf;
 	hd->numTMrequests++;
-	hd->TMtimer.expires = jiffies + HZ*20;  /* 20 seconds */
+	hd->TMtimer.expires = jiffies + timeout;
 	add_timer(&hd->TMtimer);
 
 	if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
@@ -2868,7 +2961,8 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
 
 	spin_unlock_irq(host_lock);
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
-	                       SCpnt->device->id, SCpnt->device->lun, ctx2abort, CAN_SLEEP)
+		SCpnt->device->id, SCpnt->device->lun,
+		ctx2abort, (HZ*2) /* 2 second timeout */,CAN_SLEEP)
 		< 0) {
 
 		/* The TM request failed and the subsequent FW-reload failed!
@@ -2938,7 +3032,7 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
 	}
 
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-	                       SCpnt->device->id, 0, 0, CAN_SLEEP)
+		SCpnt->device->id, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
 		< 0){
 		/* The TM request failed and the subsequent FW-reload failed!
 		 * Fatal error case.
@@ -3002,7 +3096,7 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
 
 	/* We are now ready to execute the task management request. */
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-	                       0, 0, 0, CAN_SLEEP)
+		0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP)
 	    < 0){
 
 		/* The TM request failed and the subsequent FW-reload failed!
@@ -3085,7 +3179,7 @@ static int
 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
 {
 	unsigned long  flags;
-	int            loop_count = 60 * 4;  /* Wait 60 seconds */
+	int            loop_count = 10 * 4;  /* Wait 10 seconds */
 	int            status = FAILED;
 
 	do {
@@ -3225,18 +3319,50 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *
  */
 int
 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
-		sector_t capacity, int *ip)
+		sector_t capacity, int geom[])
 {
-	int size;
+	int		heads;
+	int		sectors;
+	sector_t	cylinders;
+#ifdef CONFIG_LBD
+	ulong 		dummy;
+#endif
 
-	size = capacity;
-	ip[0] = 64;				/* heads			*/
-	ip[1] = 32;				/* sectors			*/
-	if ((ip[2] = size >> 11) > 1024) {	/* cylinders, test for big disk */
-		ip[0] = 255;			/* heads			*/
-		ip[1] = 63;			/* sectors			*/
-		ip[2] = size / (255 * 63);	/* cylinders			*/
+	heads = 64;
+	sectors = 32;
+#ifdef CONFIG_LBD
+	dummy = heads * sectors;
+	cylinders = capacity;
+	do_div(cylinders,dummy);
+#else
+	cylinders = (ulong)capacity / (heads * sectors);
+#endif
+
+	/*
+	 * Handle extended translation size for logical drives
+	 * > 1Gb
+	 */
+	if ((ulong)capacity >= 0x200000) {
+		heads = 255;
+		sectors = 63;
+#ifdef CONFIG_LBD
+		dummy = heads * sectors;
+		cylinders = capacity;
+		do_div(cylinders,dummy);
+#else
+		cylinders = (ulong)capacity / (heads * sectors);
+#endif
 	}
+
+	/* return result */
+	geom[0] = heads;
+	geom[1] = sectors;
+	geom[2] = cylinders;
+
+	dprintk((KERN_NOTICE
+		": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
+		sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
+
 	return 0;
 }
 
@@ -3366,7 +3492,7 @@ mptscsih_slave_configure(Scsi_Device *de
 			vdev->raidVolume = 0;
 			if (hd->is_spi && (hd->ioc->spi_data.isRaid & (1 << (device->id)))) {
 				vdev->raidVolume = 1;
-				ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", target_id));
+				ddvtprintk((KERN_INFO "RAID Volume @ id %d\n", device->id));
 			}
 
 			mptscsih_target_settings(hd, vdev, device);
@@ -3648,36 +3774,6 @@ SCPNT_TO_LOOKUP_IDX(Scsi_Cmnd *sc)
 	return -1;
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/* see mptscsih.h */
-
-#ifdef MPT_SCSIHOST_NEED_ENTRY_EXIT_HOOKUPS
-static Scsi_Host_Template driver_template = {
-	.proc_name			= "mptscsih",
-	.proc_info			= x_scsi_proc_info,
-	.name				= "MPT SCSI Host",
-	.detect				= x_scsi_detect,
-	.release			= x_scsi_release,
-	.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,
-};
-#include "../../scsi/scsi_module.c"
-#endif
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /* Search the pendingQ for a command with specific index.
@@ -4318,6 +4414,8 @@ int mpt_ScsiHost_ErrorReport(IO_Info_t *
 	case WRITE_10:
 	case READ_12:
 	case WRITE_12:
+	case READ_16:
+	case WRITE_16:
 		break;
 	default:
 		return 0;
@@ -5413,7 +5511,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST
 				flags = hd->ioc->spi_data.noQas;
 				if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
 					data = hd->ioc->spi_data.nvram[id];
-	
+
 					if (data & MPT_NVRAM_WIDE_DISABLE)
 						flags |= MPT_TARGET_NO_NEGO_WIDE;
 
@@ -5518,7 +5616,7 @@ mptscsih_domainValidation(void *arg)
 			/* DV only to SCSI adapters */
 			if ((int)ioc->chip_type <= (int)FC929)
 				continue;
-			
+
 			/* Make sure everything looks ok */
 			if (ioc->sh == NULL)
 				continue;
@@ -7007,3 +7105,6 @@ mptscsih_setup(char *str)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
+
+module_init(mptscsih_init);
+module_exit(mptscsih_exit);
diff -puN drivers/message/fusion/mptscsih.h~mpt-fusion-update drivers/message/fusion/mptscsih.h
--- 25/drivers/message/fusion/mptscsih.h~mpt-fusion-update	2004-01-06 21:22:08.000000000 -0800
+++ 25-akpm/drivers/message/fusion/mptscsih.h	2004-01-06 21:22:08.000000000 -0800
@@ -160,8 +160,6 @@ struct mptscsih_driver_setup
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-#define x_scsi_detect		mptscsih_detect
-#define x_scsi_release		mptscsih_release
 #define x_scsi_info		mptscsih_info
 #define x_scsi_queuecommand	mptscsih_qcmd
 #define x_scsi_abort		mptscsih_abort
@@ -170,9 +168,6 @@ struct mptscsih_driver_setup
 #define x_scsi_host_reset	mptscsih_host_reset
 #define x_scsi_bios_param	mptscsih_bios_param
 
-#define x_scsi_taskmgmt_bh	mptscsih_taskmgmt_bh
-#define x_scsi_old_abort	mptscsih_old_abort
-#define x_scsi_old_reset	mptscsih_old_reset
 #define x_scsi_slave_alloc	mptscsih_slave_alloc
 #define x_scsi_slave_configure	mptscsih_slave_configure
 #define x_scsi_slave_destroy	mptscsih_slave_destroy
@@ -182,8 +177,6 @@ struct mptscsih_driver_setup
 /*
  *	MPT SCSI Host / Initiator decls...
  */
-extern	int		 x_scsi_detect(Scsi_Host_Template *);
-extern	int		 x_scsi_release(struct Scsi_Host *host);
 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 *);
@@ -191,8 +184,7 @@ 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 *ip);
-extern	void		 x_scsi_taskmgmt_bh(void *);
+				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 *);

_