From: Jes Sorensen <jes@trained-monkey.org>

This one is a generic update for the qla1280 driver, basically a patch
submitted by Christoph which I tweaked to fit the style of the driver.



 25-akpm/drivers/scsi/qla1280.c | 1045 ++++++++++++++++-------------------------
 25-akpm/drivers/scsi/qla1280.h |   22 
 2 files changed, 424 insertions(+), 643 deletions(-)

diff -puN drivers/scsi/qla1280.c~qla1280-update drivers/scsi/qla1280.c
--- 25/drivers/scsi/qla1280.c~qla1280-update	Wed Dec 17 13:47:59 2003
+++ 25-akpm/drivers/scsi/qla1280.c	Wed Dec 17 13:48:36 2003
@@ -4,6 +4,7 @@
 * QLogic  QLA1280 (Ultra2)  and  QLA12160 (Ultra3) SCSI driver
 * Copyright (C) 2000 Qlogic Corporation (www.qlogic.com)
 * Copyright (C) 2001-2003 Jes Sorensen, Wild Open Source Inc.
+* Copyright (C) 2003 Christoph Hellwig
 *
 * 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
@@ -16,13 +17,17 @@
 * General Public License for more details.
 *
 ******************************************************************************/
-#define QLA1280_VERSION      "3.23.37.1"
+#define QLA1280_VERSION      "3.23.38.1"
 /*****************************************************************************
     Revision History:
     Rev  3.23.37.1 December 17, 2003, Jes Sorensen
 	- Delete completion queue from srb if mailbox command failed to
 	  to avoid qla1280_done completeting qla1280_error_action's
 	  obsolete context
+    Rev  3.23.38 October 18, 2003, Christoph Hellwig
+	- Convert to new-style hotplugable driver for 2.6
+	- Fix missing scsi_unregister/scsi_host_put on HBA removal
+	- Kill some of cruft
     Rev  3.23.37 October 1, 2003, Jes Sorensen
 	- Make MMIO depend on CONFIG_X86_VISWS instead of yet another
 	  random CONFIG option
@@ -341,9 +346,6 @@
  * Compile time Options:
  *            0 - Disable and 1 - Enable
  */
-#define  QL1280_LUN_SUPPORT	0
-#define  WATCHDOGTIMER		0
-
 #define  DEBUG_QLA1280_INTR	0
 #define  DEBUG_PRINT_NVRAM	0
 #define  DEBUG_QLA1280		0
@@ -423,6 +425,14 @@ scsi_adjust_queue_depth(Scsi_Device *dev
 	}
 	device->queue_depth = depth;
 }
+static inline struct Scsi_Host *scsi_host_alloc(Scsi_Host_Template *t, size_t s)
+{
+	return scsi_register(t, s);
+}
+static inline void scsi_host_put(struct Scsi_Host *h)
+{
+	scsi_unregister(h);
+}
 #else
 #define HOST_LOCK			ha->host->host_lock
 #endif
@@ -435,30 +445,23 @@ scsi_adjust_queue_depth(Scsi_Device *dev
 #define ia64_platform_is(foo)		(!strcmp(x, platform_name))
 #endif
 
+static int qla1280_probe_one(struct pci_dev *, const struct pci_device_id *);
+static void qla1280_remove_one(struct pci_dev *);
+
 /*
  *  QLogic Driver Support Function Prototypes.
  */
 static void qla1280_done(struct scsi_qla_host *, struct srb **, struct srb **);
-static void qla1280_done_q_put(struct srb *, struct srb **, struct srb **);
-static int qla1280_slave_configure(Scsi_Device *);
 #if LINUX_VERSION_CODE < 0x020545
-static void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
 static void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *);
 #endif
-
-static int qla1280_return_status(struct response * sts, Scsi_Cmnd * cp);
-static void qla1280_mem_free(struct scsi_qla_host *ha);
 static int qla1280_get_token(char *);
 static int qla1280_setup(char *s) __init;
-static inline void qla1280_enable_intrs(struct scsi_qla_host *);
-static inline void qla1280_disable_intrs(struct scsi_qla_host *);
 
 /*
  *  QLogic ISP1280 Hardware Support Function Prototypes.
  */
-static int qla1280_initialize_adapter(struct scsi_qla_host *ha);
 static int qla1280_isp_firmware(struct scsi_qla_host *);
-static int qla1280_pci_config(struct scsi_qla_host *);
 static int qla1280_chip_diag(struct scsi_qla_host *);
 static int qla1280_setup_chip(struct scsi_qla_host *);
 static int qla1280_init_rings(struct scsi_qla_host *);
@@ -477,7 +480,6 @@ static void qla1280_poll(struct scsi_qla
 static void qla1280_reset_adapter(struct scsi_qla_host *);
 static void qla1280_marker(struct scsi_qla_host *, int, int, int, u8);
 static void qla1280_isp_cmd(struct scsi_qla_host *);
-irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *);
 static void qla1280_isr(struct scsi_qla_host *, struct srb **, struct srb **);
 static void qla1280_rst_aen(struct scsi_qla_host *);
 static void qla1280_status_entry(struct scsi_qla_host *, struct response *,
@@ -490,11 +492,9 @@ static uint16_t qla1280_debounce_registe
 static request_t *qla1280_req_pkt(struct scsi_qla_host *);
 static int qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *,
 					   unsigned int);
-static int qla1280_mem_alloc(struct scsi_qla_host *ha);
-
-static void qla12160_get_target_parameters(struct scsi_qla_host *,
+static void qla1280_get_target_parameters(struct scsi_qla_host *,
 					   Scsi_Device *);
-static int qla12160_set_target_parameters(struct scsi_qla_host *, int, int);
+static int qla1280_set_target_parameters(struct scsi_qla_host *, int, int);
 
 
 static struct qla_driver_setup driver_setup __initdata;
@@ -529,10 +529,6 @@ qla1280_data_direction(struct scsi_cmnd 
 	return flags;
 }
 		
-#if QL1280_LUN_SUPPORT
-static void qla1280_enable_lun(struct scsi_qla_host *, int, int);
-#endif
-
 #if DEBUG_QLA1280
 static void __qla1280_print_scsi_cmd(Scsi_Cmnd * cmd);
 static void __qla1280_dump_buffer(char *, int);
@@ -551,8 +547,6 @@ MODULE_PARM(qla1280, "s");
 __setup("qla1280=", qla1280_setup);
 #endif
 
-MODULE_LICENSE("GPL");
-
 
 /* We use the Scsi_Pointer structure that's included with each command
  * SCSI_Cmnd as a scratchpad for our SRB.
@@ -576,28 +570,23 @@ MODULE_LICENSE("GPL");
 #define	CMD_RESULT(Cmnd)	Cmnd->result
 #define	CMD_HANDLE(Cmnd)	Cmnd->host_scribble
 #if LINUX_VERSION_CODE < 0x020545
-#define	CMD_HOST(Cmnd)		Cmnd->host
 #define CMD_REQUEST(Cmnd)	Cmnd->request.cmd
-#define SCSI_BUS_32(Cmnd)	Cmnd->channel
-#define SCSI_TCN_32(Cmnd)	Cmnd->target
-#define SCSI_LUN_32(Cmnd)	Cmnd->lun
 #else
-#define	CMD_HOST(Cmnd)		Cmnd->device->host
 #define CMD_REQUEST(Cmnd)	Cmnd->request->cmd
+#endif
+
+#define CMD_HOST(Cmnd)		Cmnd->device->host
 #define SCSI_BUS_32(Cmnd)	Cmnd->device->channel
 #define SCSI_TCN_32(Cmnd)	Cmnd->device->id
 #define SCSI_LUN_32(Cmnd)	Cmnd->device->lun
-#endif
+
 
 /*****************************************/
 /*   ISP Boards supported by this driver */
 /*****************************************/
 
-#define NUM_OF_ISP_DEVICES	6
-
 struct qla_boards {
 	unsigned char name[9];	/* Board ID String */
-	unsigned long device_id;	/* Device PCI ID   */
 	int numPorts;		/* Number of SCSI ports */
 	unsigned short *fwcode;	/* pointer to FW array         */
 	unsigned short *fwlen;	/* number of words in array    */
@@ -605,28 +594,38 @@ struct qla_boards {
 	unsigned char *fwver;	/* Ptr to F/W version array    */
 };
 
-struct qla_boards ql1280_board_tbl[NUM_OF_ISP_DEVICES] = {
-	/* Name ,  Board PCI Device ID,         Number of ports */
-	{"QLA12160", PCI_DEVICE_ID_QLOGIC_ISP12160, 2,
-	 &fw12160i_code01[0], &fw12160i_length01,
+/* NOTE: qla1280_pci_tbl and ql1280_board_tbl must be in the same order */
+static struct pci_device_id qla1280_pci_tbl[] = {
+	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP12160,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+	{PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+	{0,}
+};
+MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
+
+static struct qla_boards ql1280_board_tbl[] = {
+	/* Name ,  Number of ports, FW details */
+	{"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01,
 	 &fw12160i_addr01, &fw12160i_version_str[0]},
-	{"QLA1080", PCI_DEVICE_ID_QLOGIC_ISP1080, 1,
-	 &fw1280ei_code01[0], &fw1280ei_length01,
+	{"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01,
 	 &fw1280ei_addr01, &fw1280ei_version_str[0]},
-	{"QLA1240", PCI_DEVICE_ID_QLOGIC_ISP1240, 2,
-	 &fw1280ei_code01[0], &fw1280ei_length01,
+	{"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01,
 	 &fw1280ei_addr01, &fw1280ei_version_str[0]},
-	{"QLA1280", PCI_DEVICE_ID_QLOGIC_ISP1280, 2,
-	 &fw1280ei_code01[0], &fw1280ei_length01,
+	{"QLA1280", 2, &fw1280ei_code01[0], &fw1280ei_length01,
 	 &fw1280ei_addr01, &fw1280ei_version_str[0]},
-	{"QLA10160", PCI_DEVICE_ID_QLOGIC_ISP10160, 1,
-	 &fw12160i_code01[0], &fw12160i_length01,
+	{"QLA10160", 1, &fw12160i_code01[0], &fw12160i_length01,
 	 &fw12160i_addr01, &fw12160i_version_str[0]},
-	{"        ", 0, 0}
+	{"        ", 0}
 };
 
 static int qla1280_verbose = 1;
-static struct scsi_qla_host *qla1280_hostlist;
 static int qla1280_buffer_size;
 static char *qla1280_buffer;
 
@@ -675,31 +674,19 @@ static int qla1280_proc_info(struct Scsi
 	int size = 0;
 	int len = 0;
 	struct qla_boards *bdp;
-#ifdef BOGUS_QUEUE
-	struct scsi_lu *up;
-	uint32_t b, t, l;
-#endif
-#if LINUX_VERSION_CODE >= 0x020600
-	ha = (struct scsi_qla_host *)host->hostdata;
-#else
+#if LINUX_VERSION_CODE < 0x020600
 	struct Scsi_Host *host;
-	/* Find the host that was specified */
-	for (ha = qla1280_hostlist; (ha != NULL)
-		     && ha->host->host_no != hostno; ha = ha->next) ;
-
-	/* if host wasn't found then exit */
-	if (!ha) {
-		size =  sprintf(buffer, "Can't find adapter for host "
-				"number %d\n", hostno);
-		if (size > length) {
-			return size;
-		} else {
-			return 0;
-		}
+
+	for (host = scsi_hostlist; host; host = host->next) {
+		if (host->host_no == hostno)
+			goto found;
 	}
 
-	host = ha->host;
+	return -ESRCH;
+
+ found:
 #endif
+	ha = (struct scsi_qla_host *)host->hostdata;
 
 	if (inout)
 		return -ENOSYS;
@@ -753,51 +740,6 @@ static int qla1280_proc_info(struct Scsi
 	size = sprintf(PROC_BUF, "\n");	/* 1       */
 	len += size;
 
-	size = sprintf(PROC_BUF, "SCSI device Information:\n");
-	len += size;
-#ifdef BOGUS_QUEUE
-	/* scan for all equipment stats */
-	for (b = 0; b < MAX_BUSES; b++)
-		for (t = 0; t < MAX_TARGETS; t++) {
-			for (l = 0; l < MAX_LUNS; l++) {
-				up = LU_Q(ha, b, t, l);
-				if (up == NULL)
-					continue;
-				/* unused device/lun */
-				if (up->io_cnt == 0 || up->io_cnt < 2)
-					continue;
-				/* total reads since boot */
-				/* total writes since boot */
-				/* total requests since boot  */
-				size = sprintf (PROC_BUF,
-						"(%2d:%2d:%2d): Total reqs %ld,",
-						b, t, l, up->io_cnt);
-				len += size;
-				/* current number of pending requests */
-				size =	sprintf(PROC_BUF, " Pend reqs %d,",
-						up->q_outcnt);
-				len += size;
-#if 0
-				/* avg response time */
-				size = sprintf(PROC_BUF, " Avg resp time %ld%%,",
-					       (up->resp_time / up->io_cnt) *
-					       100);
-				len += size;
-
-				/* avg active time */
-				size = sprintf(PROC_BUF,
-					       " Avg active time %ld%%\n",
-					       (up->act_time / up->io_cnt) * 100);
-#else
-				size = sprintf(PROC_BUF, "\n");
-#endif
-				len += size;
-			}
-			if (len >= qla1280_buffer_size)
-				break;
-		}
-#endif
-
 	if (len >= qla1280_buffer_size) {
 		printk(KERN_WARNING
 		       "qla1280: Overflow buffer in qla1280_proc.c\n");
@@ -875,312 +817,6 @@ static int qla1280_read_nvram(struct scs
 	return chksum;
 }
 
-
-/**************************************************************************
- * qla1280_do_device_init
- *    This routine will register the device with the SCSI subsystem,
- *    initialize the host adapter structure and call the device init
- *    routines.
- *
- * Input:
- *     pdev      - pointer to struct pci_dev for adapter
- *     template  - pointer to SCSI template
- *     devnum    - the device number
- *     bdp       - pointer to struct _qlaboards
- *     num_hosts - the host number
- *
- * Returns:
- *  host - pointer to SCSI host structure
- **************************************************************************/
-struct Scsi_Host *
-qla1280_do_device_init(struct pci_dev *pdev, Scsi_Host_Template * template,
-		       int devnum, struct qla_boards *bdp, int num_hosts)
-{
-	struct Scsi_Host *host;
-	struct scsi_qla_host *ha;
-
-	printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n",
-	       bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn));
-
-	host = scsi_register(template, sizeof(struct scsi_qla_host));
-	if (!host) {
-		printk(KERN_WARNING
-		       "qla1280: Failed to register host, aborting.\n");
-		goto error;
-	}
-
-#if LINUX_VERSION_CODE < 0x020545
-	scsi_set_pci_device(host, pdev);
-#else
-	scsi_set_device(host, &pdev->dev);
-#endif
-	ha = (struct scsi_qla_host *)host->hostdata;
-	/* Clear our data area */
-	memset(ha, 0, sizeof(struct scsi_qla_host));
-	/* Sanitize the information from PCI BIOS.  */
-	host->irq = pdev->irq;
-	ha->pci_bus = pdev->bus->number;
-	ha->pci_device_fn = pdev->devfn;
-	ha->pdev = pdev;
-	ha->device_id = bdp->device_id;
-	ha->devnum = devnum;	/* specifies microcode load address */
-
-	if (qla1280_mem_alloc(ha)) {
-		printk(KERN_INFO "qla1x160: Failed to get memory\n");
-		goto error_scsi_unregister;
-	}
-
-	ha->ports = bdp->numPorts;
-	/* following needed for all cases of OS versions */
-	ha->host = host;
-	ha->host_no = host->host_no;
-
-	host->can_queue = 0xfffff;	/* unlimited  */
-	host->cmd_per_lun = 1;
-	host->base = (unsigned long)ha->mmpbase;
-	host->max_channel = bdp->numPorts - 1;
-	host->max_lun = MAX_LUNS - 1;
-	host->max_id = MAX_TARGETS;
-	host->max_sectors = 1024;
-#if LINUX_VERSION_CODE < 0x020545
-	host->select_queue_depths = qla1280_select_queue_depth;
-#endif
-
-	ha->instance = num_hosts;
-	host->unique_id = ha->instance;
-
-	if (qla1280_pci_config(ha)) {
-		printk(KERN_INFO "qla1x160: Unable to configure PCI\n");
-		goto error_mem_alloced;
-	}
-
-	/* Disable ISP interrupts. */
-	qla1280_disable_intrs(ha);
-
-	/* Register the IRQ with Linux (sharable) */
-	if (request_irq(host->irq, qla1280_intr_handler, SA_SHIRQ,
-			"qla1280", ha)) {
-		printk("qla1280 : Failed to reserve interrupt %d already "
-		       "in use\n", host->irq);
-		goto error_iounmap;
-	}
-#if !MEMORY_MAPPED_IO
-	/* Register the I/O space with Linux */
-	if (!request_region(host->io_port, 0xff, "qla1280")) {
-		printk("qla1280: Failed to reserve i/o region 0x%04lx-0x%04lx"
-		       " already in use\n",
-		       host->io_port, host->io_port + 0xff);
-		goto error_free_irq;
-	}
-#endif
-
-	/* load the F/W, read paramaters, and init the H/W */
-	if (qla1280_initialize_adapter(ha)) {
-		printk(KERN_INFO "qla1x160: Failed to initialize adapter\n");
-		goto error_release_region;
-	}
-
-	/* set our host ID  (need to do something about our two IDs) */
-	host->this_id = ha->bus_settings[0].id;
-
-	return host;
-
- error_release_region:
-#if !MEMORY_MAPPED_IO
-	release_region(host->io_port, 0xff);
- error_free_irq:
-#endif
-	free_irq(host->irq, ha);
- error_iounmap:
-#if MEMORY_MAPPED_IO
-	if (ha->mmpbase)
-		iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
-#endif
- error_mem_alloced:
-	qla1280_mem_free(ha);
- error_scsi_unregister:
-	scsi_unregister(host);
- error:
-	return NULL;
-}
-
-/**************************************************************************
- * qla1280_detect
- *    This routine will probe for Qlogic 1280 SCSI host adapters.
- *    It returns the number of host adapters of a particular
- *    type that were found.	 It also initialize all data necessary for
- *    the driver.  It is passed-in the host number, so that it
- *    knows where its first entry is in the scsi_hosts[] array.
- *
- * Input:
- *     template - pointer to SCSI template
- *
- * Returns:
- *  num - number of host adapters found.
- **************************************************************************/
-static int
-qla1280_detect(Scsi_Host_Template * template)
-{
-	struct pci_dev *pdev = NULL;
-	struct Scsi_Host *host;
-	struct scsi_qla_host *ha, *cur_ha;
-	struct qla_boards *bdp;
-	uint16_t subsys_vendor, subsys_device;
-	int num_hosts = 0;
-	int devnum = 0;
-
-	ENTER("qla1280_detect");
-
-	if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {
-		printk(KERN_WARNING
-		       "qla1280_detect: [WARNING] struct srb too big\n");
-		return 0;
-	}
-#ifdef MODULE
-	/*
-	 * If we are called as a module, the qla1280 pointer may not be null
-	 * and it would point to our bootup string, just like on the lilo
-	 * command line.  IF not NULL, then process this config string with
-	 * qla1280_setup
-	 *
-	 * Boot time Options
-	 * To add options at boot time add a line to your lilo.conf file like:
-	 * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
-	 * which will result in the first four devices on the first two
-	 * controllers being set to a tagged queue depth of 32.
-	 */
-	if (qla1280)
-		qla1280_setup(qla1280);
-#endif
-
-	bdp = &ql1280_board_tbl[0];
-	qla1280_hostlist = NULL;
-	template->proc_name = "qla1280";
-
-	/* First Initialize QLA12160 on PCI Bus 1 Dev 2 */
-	while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, bdp->device_id,
-				       PCI_ANY_ID, PCI_ANY_ID, pdev))) {
-
-		/* find QLA12160 device on PCI bus=1 slot=2 */
-		if ((pdev->bus->number != 1) || (PCI_SLOT(pdev->devfn) != 2))
-			continue;
-
-		/* Bypass all AMI SUBSYS VENDOR IDs */
-		if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) {
-			printk(KERN_INFO
-			       "qla1x160: Skip AMI SubSys Vendor ID Chip\n");
-			continue;
-		}
-
-		if (pci_enable_device(pdev))
-			goto find_devices;
-
-		host = qla1280_do_device_init(pdev, template, devnum,
-					      bdp, num_hosts);
-		if (!host)
-			continue;
-		ha = (struct scsi_qla_host *)host->hostdata;
-
-		/* this preferred device will always be the first one found */
-		cur_ha = qla1280_hostlist = ha;
-		num_hosts++;
-	}
-
- find_devices:
-
-	pdev = NULL;
-	/* Try and find each different type of adapter we support */
-	for (devnum = 0; bdp->device_id != 0 && devnum < NUM_OF_ISP_DEVICES;
-	     devnum++, bdp++) {
-		/* PCI_SUBSYSTEM_IDS supported */
-		while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC,
-					       bdp->device_id, PCI_ANY_ID,
-					       PCI_ANY_ID, pdev))) {
-			if (pci_enable_device(pdev))
-				continue;
-			/* found an adapter */
-			subsys_vendor = pdev->subsystem_vendor;
-			subsys_device = pdev->subsystem_device;
-
-			/*
-			 * skip QLA12160 already initialized on
-			 * PCI Bus 1 Dev 2 since we already initialized
-			 * and presented it
-			 */
-			if ((bdp->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160)&&
-			    (pdev->bus->number == 1) &&
-			    (PCI_SLOT(pdev->devfn) == 2))
-				continue;
-
-			/* Bypass all AMI SUBSYS VENDOR IDs */
-			if (subsys_vendor == PCI_VENDOR_ID_AMI) {
-				printk(KERN_INFO
-				       "qla1x160: Skip AMI SubSys Vendor ID Chip\n");
-				continue;
-			}
-			dprintk(1, "qla1x160: Supported Device Found VID=%x "
-			       "DID=%x SSVID=%x SSDID=%x\n", pdev->vendor,
-			       pdev->device, subsys_vendor, subsys_device);
-
-			host = qla1280_do_device_init(pdev, template,
-						      devnum, bdp, num_hosts);
-			if (!host)
-				continue;
-			ha = (struct scsi_qla_host *)host->hostdata;
-
-			if (qla1280_hostlist == NULL) {
-				cur_ha = qla1280_hostlist = ha;
-			} else {
-				cur_ha = qla1280_hostlist;
-				while (cur_ha->next != NULL)
-					cur_ha = cur_ha->next;
-				cur_ha->next = ha;
-			}
-			num_hosts++;
-		}		/* end of WHILE */
-	}			/* end of FOR */
-
-	LEAVE("qla1280_detect");
-	return num_hosts;
-}
-
-/**************************************************************************
- *   qla1280_release
- *   Free the passed in Scsi_Host memory structures prior to unloading the
- *   module.
- **************************************************************************/
-static int
-qla1280_release(struct Scsi_Host *host)
-{
-	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
-
-	ENTER("qla1280_release");
-
-	if (!ha->flags.online)
-		return 0;
-
-	/* turn-off interrupts on the card */
-	WRT_REG_WORD(&ha->iobase->ictrl, 0);
-
-	/* Detach interrupts */
-	if (host->irq)
-		free_irq(host->irq, ha);
-
-#if MEMORY_MAPPED_IO
-	if (ha->mmpbase)
-		iounmap(ha->mmpbase);
-#else
-	/* release io space registers  */
-	if (host->io_port)
-		release_region(host->io_port, 0xff);
-#endif				/* MEMORY_MAPPED_IO */
-
-	qla1280_mem_free(ha);
-
-	ENTER("qla1280_release");
-	return 0;
-}
-
 /**************************************************************************
  *   qla1280_info
  *     Return a string describing the driver.
@@ -1197,11 +833,11 @@ qla1280_info(struct Scsi_Host *host)
 	ha = (struct scsi_qla_host *)host->hostdata;
 	bdp = &ql1280_board_tbl[ha->devnum];
 	memset(bp, 0, sizeof(qla1280_scsi_name_buffer));
+
 	sprintf (bp,
-		 "QLogic %s PCI to SCSI Host Adapter: bus %d device %d irq %d\n"
+		 "QLogic %s PCI to SCSI Host Adapter\n"
 		 "       Firmware version: %2d.%02d.%02d, Driver version %s",
-		 &bdp->name[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3,
-		 host->irq, bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
+		 &bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
 		 QLA1280_VERSION);
 	return bp;
 }
@@ -1220,38 +856,19 @@ qla1280_info(struct Scsi_Host *host)
 static int
 qla1280_queuecommand(Scsi_Cmnd * cmd, void (*fn) (Scsi_Cmnd *))
 {
-	struct scsi_qla_host *ha;
-	struct srb *sp;
-	struct Scsi_Host *host;
-	int bus, target, lun;
-	int status;
-
-	/*ENTER("qla1280_queuecommand");
-	 */
-	dprintk(2, "qla1280_queuecommand(): jiffies %li\n", jiffies);
-
-	host = CMD_HOST(cmd);
-	ha = (struct scsi_qla_host *)host->hostdata;
+	struct Scsi_Host *host = cmd->device->host;
+	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
+	struct srb *sp = (struct srb *)&cmd->SCp;
 
-	/* send command to adapter */
-	sp = (struct srb *)CMD_SP(cmd);
-	sp->cmd = cmd;
 	cmd->scsi_done = fn;
+	sp->cmd = cmd;
 	sp->flags = 0;
 
 	qla1280_print_scsi_cmd(5, cmd);
 
-	/* Generate LU queue on bus, target, LUN */
-	bus = SCSI_BUS_32(cmd);
-	target = SCSI_TCN_32(cmd);
-	lun = SCSI_LUN_32(cmd);
 	if (ha->flags.enable_64bit_addressing)
-		status = qla1280_64bit_start_scsi(ha, sp);
-	else
-		status = qla1280_32bit_start_scsi(ha, sp);
-
-	/*LEAVE("qla1280_queuecommand"); */
-	return status;
+		return qla1280_64bit_start_scsi(ha, sp);
+	return qla1280_32bit_start_scsi(ha, sp);
 }
 
 enum action {
@@ -1564,29 +1181,105 @@ qla1280_biosparam(struct scsi_device *sd
 	unsigned long capacity = disk->capacity;
 #endif
 
-	heads = 64;
-	sectors = 32;
-	cylinders = (unsigned long)capacity / (heads * sectors);
-	if (cylinders > 1024) {
-		heads = 255;
-		sectors = 63;
-		cylinders = (unsigned long)capacity / (heads * sectors);
-		/* if (cylinders > 1023)
-		   cylinders = 1023; */
+	heads = 64;
+	sectors = 32;
+	cylinders = (unsigned long)capacity / (heads * sectors);
+	if (cylinders > 1024) {
+		heads = 255;
+		sectors = 63;
+		cylinders = (unsigned long)capacity / (heads * sectors);
+		/* if (cylinders > 1023)
+		   cylinders = 1023; */
+	}
+
+	geom[0] = heads;
+	geom[1] = sectors;
+	geom[2] = cylinders;
+
+	return 0;
+}
+
+#if LINUX_VERSION_CODE < 0x020600
+static int
+qla1280_detect(Scsi_Host_Template *template)
+{
+	struct pci_device_id *id = &qla1280_pci_tbl[0];
+	struct pci_dev *pdev = NULL;
+	int num_hosts = 0;
+
+	if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {
+		printk(KERN_WARNING
+		       "qla1280: struct srb too big, aborting\n");
+		return 0;
+	}
+
+#ifdef MODULE
+	/*
+	 * If we are called as a module, the qla1280 pointer may not be null
+	 * and it would point to our bootup string, just like on the lilo
+	 * command line.  IF not NULL, then process this config string with
+	 * qla1280_setup
+	 *
+	 * Boot time Options
+	 * To add options at boot time add a line to your lilo.conf file like:
+	 * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
+	 * which will result in the first four devices on the first two
+	 * controllers being set to a tagged queue depth of 32.
+	 */
+	if (qla1280)
+		qla1280_setup(qla1280);
+#endif
+
+	/* First Initialize QLA12160 on PCI Bus 1 Dev 2 */
+	while ((pdev = pci_find_device(id->vendor, id->device, pdev))) {
+		if (pdev->bus->number == 1 && PCI_SLOT(pdev->devfn) == 2) {
+			if (!qla1280_probe_one(pdev, id))
+				num_hosts++;
+		}
+	}
+
+	pdev = NULL;
+	/* Try and find each different type of adapter we support */
+	for (id = &qla1280_pci_tbl[0]; id->device; id++) {
+		while ((pdev = pci_find_device(id->vendor, id->device, pdev))) {
+			/*
+			 * skip QLA12160 already initialized on
+			 * PCI Bus 1 Dev 2 since we already initialized
+			 * and presented it
+			 */
+			if (id->device == PCI_DEVICE_ID_QLOGIC_ISP12160 &&
+			    pdev->bus->number == 1 &&
+			    PCI_SLOT(pdev->devfn) == 2)
+				continue;
+
+			if (!qla1280_probe_one(pdev, id))
+				num_hosts++;
+		}
 	}
 
-	geom[0] = heads;
-	geom[1] = sectors;
-	geom[2] = cylinders;
+	return num_hosts;
+}
+
+/*
+ * This looks a bit ugly as we could just pass down host to
+ * qla1280_remove_one, but I want to keep qla1280_release purely a wrapper
+ * around pci_driver::remove as used from 2.6 onwards.
+ */
+static int
+qla1280_release(struct Scsi_Host *host)
+{
+	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
 
+	qla1280_remove_one(ha->pdev);
 	return 0;
 }
+#endif
 
 /**************************************************************************
  * qla1280_intr_handler
  *   Handles the H/W interrupt
  **************************************************************************/
-irqreturn_t
+static irqreturn_t
 qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct scsi_qla_host *ha;
@@ -1624,7 +1317,7 @@ qla1280_intr_handler(int irq, void *dev_
 
 
 static int
-qla12160_set_target_parameters(struct scsi_qla_host *ha, int bus, int target)
+qla1280_set_target_parameters(struct scsi_qla_host *ha, int bus, int target)
 {
 	uint8_t mr;
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
@@ -1633,8 +1326,8 @@ qla12160_set_target_parameters(struct sc
 
 	nv = &ha->nvram;
 
-	if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
-	    ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160)
+	if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+	    ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160)
 		is1x160 = 1;
 	else
 		is1x160 = 0;
@@ -1721,8 +1414,8 @@ qla1280_slave_configure(Scsi_Device *dev
 	    (driver_setup.wide_mask &&
 	     (~driver_setup.wide_mask & (1 << target))))
 		nv->bus[bus].target[target].parameter.f.enable_wide = 0;
-	if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
-	    ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) {
+	if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+	    ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160) {
 		if (driver_setup.no_ppr ||
 		    (driver_setup.ppr_mask &&
 		     (~driver_setup.ppr_mask & (1 << target))))
@@ -1730,11 +1423,9 @@ qla1280_slave_configure(Scsi_Device *dev
 	}
 
 	spin_lock_irqsave(HOST_LOCK, flags);
-	if (nv->bus[bus].target[target].parameter.f.enable_sync) {
-		status = qla12160_set_target_parameters(ha, bus, target);
-	}
-
-	qla12160_get_target_parameters(ha, device);
+	if (nv->bus[bus].target[target].parameter.f.enable_sync)
+		status = qla1280_set_target_parameters(ha, bus, target);
+	qla1280_get_target_parameters(ha, device);
 	spin_unlock_irqrestore(HOST_LOCK, flags);
 	return status;
 }
@@ -1761,16 +1452,11 @@ qla1280_select_queue_depth(struct Scsi_H
 
 	if (scsi_devs)
 		qla1280_check_for_dead_scsi_bus(ha, scsi_devs->channel);
-
 	LEAVE("qla1280_select_queue_depth");
 }
 #endif
 
 /*
- * Driver Support Routines
- */
-
-/*
  * qla1280_done
  *      Process completed commands.
  *
@@ -1972,100 +1658,19 @@ qla1280_done_q_put(struct srb * sp, stru
 	LEAVE("qla1280_put_done_q");
 }
 
-
-/*
-* qla1280_mem_alloc
-*      Allocates adapter memory.
-*
-* Returns:
-*      0  = success.
-*      1  = failure.
-*/
-static int
-qla1280_mem_alloc(struct scsi_qla_host *ha)
-{
-	int status = 1;
-	dma_addr_t dma_handle;
-
-	ENTER("qla1280_mem_alloc");
-
-	/* get consistent memory allocated for request and response rings */
-	ha->request_ring = pci_alloc_consistent(ha->pdev,
-						((REQUEST_ENTRY_CNT + 1) *
-						 (sizeof(request_t))),
-						&dma_handle);
-	if (!ha->request_ring)
-		goto error;
-	ha->request_dma = dma_handle;
-	ha->response_ring = pci_alloc_consistent(ha->pdev,
-						 ((RESPONSE_ENTRY_CNT + 1) *
-						  (sizeof(struct response))),
-						 &dma_handle);
-	if (!ha->response_ring)
-		goto error;
-	ha->response_dma = dma_handle;
-	status = 0;
-	goto finish;
-
- error:
-	if (status)
-		dprintk(2, "qla1280_mem_alloc: **** FAILED ****\n");
-
-	if (ha->request_ring)
-		pci_free_consistent(ha->pdev,
-                                    ((REQUEST_ENTRY_CNT + 1) *
-				     (sizeof(request_t))),
-                                    ha->request_ring, ha->request_dma);
- finish:
-	LEAVE("qla1280_mem_alloc");
-	return status;
-}
-
-/*
- * qla1280_mem_free
- *      Frees adapter allocated memory.
- *
- * Input:
- *      ha = adapter block pointer.
- */
-static void
-qla1280_mem_free(struct scsi_qla_host *ha)
-{
-	ENTER("qlc1280_mem_free");
-	/* free consistent memory allocated for request and response rings */
-	if (ha->request_ring)
-		pci_free_consistent(ha->pdev,
-				    ((REQUEST_ENTRY_CNT + 1) *
-				     (sizeof(request_t))),
-				    ha->request_ring, ha->request_dma);
-
-	if (ha->response_ring)
-		pci_free_consistent(ha->pdev,
-				    ((RESPONSE_ENTRY_CNT + 1) *
-				     (sizeof(struct response))),
-				    ha->response_ring, ha->response_dma);
-
-	if (qla1280_buffer) {
-		free_page((unsigned long) qla1280_buffer);
-		qla1280_buffer = NULL;
-	}
-
-	LEAVE("qlc1280_mem_free");
-}
-
 /****************************************************************************/
 /*                QLogic ISP1280 Hardware Support Functions.                */
 /****************************************************************************/
 
  /*
-    * qla2100_enable_intrs
-    * qla2100_disable_intrs
-    *
-    * Input:
-    *      ha = adapter block pointer.
-    *
-    * Returns:
-    *      None
+  * qla2100_enable_intrs
+  * qla2100_disable_intrs
+  *
+  * Input:
+  *      ha = adapter block pointer.
+  *
+  * Returns:
+  *      None
   */
 static inline void
 qla1280_enable_intrs(struct scsi_qla_host *ha)
@@ -2101,7 +1706,7 @@ qla1280_disable_intrs(struct scsi_qla_ho
  * Returns:
  *      0 = success
  */
-static int
+static int __devinit
 qla1280_initialize_adapter(struct scsi_qla_host *ha)
 {
 	struct device_reg *reg;
@@ -2297,7 +1902,7 @@ qla1280_isp_firmware(struct scsi_qla_hos
  * Returns:
  *      0 = success.
  */
-static int
+static int __devinit
 qla1280_pci_config(struct scsi_qla_host *ha)
 {
 #if MEMORY_MAPPED_IO
@@ -2724,8 +2329,8 @@ qla1280_nvram_config(struct scsi_qla_hos
 
 	ENTER("qla1280_nvram_config");
 
-	if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
-	    ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160)
+	if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+	    ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160)
 		is1x160 = 1;
 	else
 		is1x160 = 0;
@@ -4207,48 +3812,6 @@ qla1280_isp_cmd(struct scsi_qla_host *ha
 	LEAVE("qla1280_isp_cmd");
 }
 
-#if QL1280_LUN_SUPPORT
-/*
- * qla1280_enable_lun
- *      Issue enable LUN entry IOCB.
- *
- * Input:
- *      ha  = adapter block pointer.
- *      bus = SCSI BUS number.
- *      lun  = LUN number.
- */
-static void
-qla1280_enable_lun(struct scsi_qla_host *ha, int bus, int lun)
-{
-	struct elun_entry *pkt;
-
-	ENTER("qla1280_enable_lun");
-
-	/* Get request packet. */
-	/*
-	  if (pkt = (struct elun_entry *)qla1280_req_pkt(ha))
-	  {
-	  pkt->entry_type = ENABLE_LUN_TYPE;
-	  pkt->lun = cpu_to_le16(bus ? lun | BIT_15 : lun);
-	  pkt->command_count = 32;
-	  pkt->immed_notify_count = 1;
-	  pkt->group_6_length = MAX_CMDSZ;
-	  pkt->group_7_length = MAX_CMDSZ;
-	  pkt->timeout = cpu_to_le16(0x30);
-
-	  qla1280_isp_cmd(ha);
-	  }
-	*/
-	pkt = (struct elun_entry *) 1;
-
-	if (!pkt)
-		dprintk(2, "qla1280_enable_lun: **** FAILED ****\n");
-	else
-		dprintk(3, "qla1280_enable_lun: exiting normally\n");
-}
-#endif
-
-
 /****************************************************************************/
 /*                        Interrupt Service Routine.                        */
 /****************************************************************************/
@@ -4894,7 +4457,7 @@ qla1280_check_for_dead_scsi_bus(struct s
 }
 
 static void
-qla12160_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device)
+qla1280_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device)
 {
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
 	int bus, target, lun;
@@ -5136,34 +4699,274 @@ qla1280_get_token(char *str)
 	return ret;
 }
 
-
-static Scsi_Host_Template driver_template = {
-	.proc_info		= qla1280_proc_info,
+static Scsi_Host_Template qla1280_driver_template = {
+	.proc_name		= "qla1280",
 	.name			= "Qlogic ISP 1280/12160",
+#if LINUX_VERSION_CODE >= 0x020545
+	.slave_configure	= qla1280_slave_configure,
+#else
 	.detect			= qla1280_detect,
 	.release		= qla1280_release,
+#endif
 	.info			= qla1280_info,
 	.queuecommand		= qla1280_queuecommand,
-#if LINUX_VERSION_CODE >= 0x020545
-	.slave_configure	= qla1280_slave_configure,
-#endif
 	.eh_abort_handler	= qla1280_eh_abort,
 	.eh_device_reset_handler= qla1280_eh_device_reset,
 	.eh_bus_reset_handler	= qla1280_eh_bus_reset,
 	.eh_host_reset_handler	= qla1280_eh_adapter_reset,
 	.bios_param		= qla1280_biosparam,
-	.can_queue		= 255,
+	.proc_info		= qla1280_proc_info,
+	.can_queue		= 0xfffff,
 	.this_id		= -1,
 	.sg_tablesize		= SG_ALL,
-	.cmd_per_lun		= 3,
+	.cmd_per_lun		= 1,
 	.use_clustering		= ENABLE_CLUSTERING,
 #if LINUX_VERSION_CODE < 0x020545
 	.use_new_eh_code	= 1,
 #endif
 };
 
-#include "scsi_module.c"
+static int __devinit
+qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	int devnum = id->driver_data;
+	struct qla_boards *bdp = &ql1280_board_tbl[devnum];
+	struct Scsi_Host *host;
+	struct scsi_qla_host *ha;
+	int error = -ENODEV;
+
+	/* Bypass all AMI SUBSYS VENDOR IDs */
+	if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) {
+		printk(KERN_INFO
+		       "qla1280: Skipping AMI SubSys Vendor ID Chip\n");
+		goto error;
+	}
+
+	printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n",
+	       bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn));
+
+	if (pci_enable_device(pdev)) {
+		printk(KERN_WARNING
+		       "qla1280: Failed to enabled pci device, aborting.\n");
+		goto error;
+	}
+
+	error = -ENOMEM;
+	host = scsi_host_alloc(&qla1280_driver_template, sizeof(*ha));
+	if (!host) {
+		printk(KERN_WARNING
+		       "qla1280: Failed to register host, aborting.\n");
+		goto error;
+	}
+
+	ha = (struct scsi_qla_host *)host->hostdata;
+	memset(ha, 0, sizeof(struct scsi_qla_host));
+
+	ha->pdev = pdev;
+	ha->devnum = devnum;	/* specifies microcode load address */
+
+	ha->request_ring = pci_alloc_consistent(ha->pdev,
+			((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))),
+			&ha->request_dma);
+	if (!ha->request_ring) {
+		printk(KERN_INFO "qla1280: Failed to get request memory\n");
+		goto error_put_host;
+	}
+
+	ha->response_ring = pci_alloc_consistent(ha->pdev,
+			((RESPONSE_ENTRY_CNT + 1) * (sizeof(struct response))),
+			&ha->response_dma);
+	if (!ha->response_ring) {
+		printk(KERN_INFO "qla1280: Failed to get response memory\n");
+		goto error_free_request_ring;
+	}
+
+	ha->ports = bdp->numPorts;
+
+	ha->host = host;
+	ha->host_no = host->host_no;
+
+	host->irq = pdev->irq;
+	host->base = (unsigned long)ha->mmpbase;
+	host->max_channel = bdp->numPorts - 1;
+	host->max_lun = MAX_LUNS - 1;
+	host->max_id = MAX_TARGETS;
+	host->max_sectors = 1024;
+	host->unique_id = host->host_no;
+
+#if LINUX_VERSION_CODE < 0x020545
+	host->select_queue_depths = qla1280_select_queue_depth;
+#endif
+
+	error = -ENODEV;
+	if (qla1280_pci_config(ha)) {
+		printk(KERN_INFO "qla1280: Unable to configure PCI\n");
+		goto error_free_response_ring;
+	}
+
+	/* Disable ISP interrupts. */
+	qla1280_disable_intrs(ha);
+
+	/* Register the IRQ with Linux (sharable) */
+	if (request_irq(pdev->irq, qla1280_intr_handler, SA_SHIRQ,
+				"qla1280", ha)) {
+		printk("qla1280 : Failed to reserve interrupt %d already "
+		       "in use\n", pdev->irq);
+		goto error_iounmap;
+	}
+
+#if !MEMORY_MAPPED_IO
+	/* Register the I/O space with Linux */
+	if (!request_region(host->io_port, 0xff, "qla1280")) {
+		printk("qla1280: Failed to reserve i/o region 0x%04lx-0x%04lx"
+		       " already in use\n",
+		       host->io_port, host->io_port + 0xff);
+		goto error_free_irq;
+	}
+#endif
+
+	/* load the F/W, read paramaters, and init the H/W */
+	if (qla1280_initialize_adapter(ha)) {
+		printk(KERN_INFO "qla1x160: Failed to initialize adapter\n");
+		goto error_release_region;
+	}
+
+	/* set our host ID  (need to do something about our two IDs) */
+	host->this_id = ha->bus_settings[0].id;
+
+	pci_set_drvdata(pdev, host);
+
+#if LINUX_VERSION_CODE >= 0x020600
+	error = scsi_add_host(host, &pdev->dev);
+	if (error)
+		goto error_disable_adapter;
+	scsi_scan_host(host);
+#else
+	scsi_set_pci_device(host, pdev);
+#endif
+
+	return 0;
+
+#if LINUX_VERSION_CODE >= 0x020600
+ error_disable_adapter:
+	WRT_REG_WORD(&ha->iobase->ictrl, 0);
+#endif
+ error_release_region:
+#if !MEMORY_MAPPED_IO
+	release_region(host->io_port, 0xff);
+ error_free_irq:
+#endif
+	free_irq(pdev->irq, ha);
+ error_iounmap:
+#if MEMORY_MAPPED_IO
+	iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
+#endif
+ error_free_response_ring:
+	pci_free_consistent(ha->pdev,
+			((RESPONSE_ENTRY_CNT + 1) * (sizeof(struct response))),
+			ha->response_ring, ha->response_dma);
+ error_free_request_ring:
+	pci_free_consistent(ha->pdev,
+			((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))),
+			ha->request_ring, ha->request_dma);
+ error_put_host:
+	scsi_host_put(host);
+ error:
+	return error;
+}
+
+/*
+ * Older ia64 toolchains have problems with relative links when this
+ * goes into the .exit.text section
+ */
+#if !defined(CONFIG_QLA1280_MODULE) && defined(__ia64__) && (__GNUC__ == 2)
+static void
+#else
+static void __devexit
+#endif
+qla1280_remove_one(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
+
+#if LINUX_VERSION_CODE >= 0x020600
+	scsi_remove_host(host);
+#endif
+
+	WRT_REG_WORD(&ha->iobase->ictrl, 0);
+
+	free_irq(pdev->irq, ha);
+
+#if MEMORY_MAPPED_IO
+	iounmap(ha->mmpbase);
+#else
+	release_region(host->io_port, 0xff);
+#endif
+
+	pci_free_consistent(ha->pdev,
+			((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))),
+			ha->request_ring, ha->request_dma);
+	pci_free_consistent(ha->pdev,
+			((RESPONSE_ENTRY_CNT + 1) * (sizeof(struct response))),
+			ha->response_ring, ha->response_dma);
+
+	scsi_host_put(host);
+}
+
+#if LINUX_VERSION_CODE >= 0x020600
+static struct pci_driver qla1280_pci_driver = {
+	.name		= "qla1280",
+	.id_table	= qla1280_pci_tbl,
+	.probe		= qla1280_probe_one,
+	.remove		= __devexit_p(qla1280_remove_one),
+};
+
+static int __init
+qla1280_init(void)
+{
+	if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {
+		printk(KERN_WARNING
+		       "qla1280: struct srb too big, aborting\n");
+		return -EINVAL;
+	}
+
+#ifdef MODULE
+	/*
+	 * If we are called as a module, the qla1280 pointer may not be null
+	 * and it would point to our bootup string, just like on the lilo
+	 * command line.  IF not NULL, then process this config string with
+	 * qla1280_setup
+	 *
+	 * Boot time Options
+	 * To add options at boot time add a line to your lilo.conf file like:
+	 * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
+	 * which will result in the first four devices on the first two
+	 * controllers being set to a tagged queue depth of 32.
+	 */
+	if (qla1280)
+		qla1280_setup(qla1280);
+#endif
+
+	return pci_module_init(&qla1280_pci_driver);
+}
 
+static void __exit
+qla1280_exit(void)
+{
+	pci_unregister_driver(&qla1280_pci_driver);
+}
+
+module_init(qla1280_init);
+module_exit(qla1280_exit);
+
+#else
+# define driver_template qla1280_driver_template
+# include "scsi_module.c"
+#endif
+
+MODULE_AUTHOR("Qlogic & Jes Sorensen");
+MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver");
+MODULE_LICENSE("GPL");
 
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
diff -puN drivers/scsi/qla1280.h~qla1280-update drivers/scsi/qla1280.h
--- 25/drivers/scsi/qla1280.h~qla1280-update	Wed Dec 17 13:47:59 2003
+++ 25-akpm/drivers/scsi/qla1280.h	Wed Dec 17 13:47:59 2003
@@ -1021,11 +1021,7 @@ struct scsi_qla_host {
 
 	unsigned char *mmpbase;	/* memory mapped address */
 	unsigned long host_no;
-	unsigned long instance;
 	struct pci_dev *pdev;
-	uint32_t device_id;
-	uint8_t pci_bus;
-	uint8_t pci_device_fn;
 	uint8_t devnum;
 	uint8_t revision;
 	uint8_t ports;
@@ -1040,18 +1036,9 @@ struct scsi_qla_host {
 	/* BUS configuration data */
 	struct bus_param bus_settings[MAX_BUSES];
 
-#if 0
-	/* bottom half run queue */
-	struct tq_struct run_qla_bh;
-#endif
-
 	/* Received ISP mailbox data. */
 	volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
 
-#ifdef UNUSED
-	struct timer_list dev_timer[MAX_TARGETS];
-#endif
-
 	dma_addr_t request_dma;		/* Physical Address */
 	request_t *request_ring;	/* Base virtual address */
 	request_t *request_ring_ptr;	/* Current address. */
@@ -1063,15 +1050,6 @@ struct scsi_qla_host {
 	struct response *response_ring_ptr;	/* Current address. */
 	uint16_t rsp_ring_index;	/* Current index. */
 
-#if WATCHDOGTIMER
-	/* Watchdog queue, lock and total timer */
-	uint8_t watchdog_q_lock;	/* Lock for watchdog queue */
-	struct srb *wdg_q_first;	/* First job on watchdog queue */
-	struct srb *wdg_q_last;	/* Last job on watchdog queue */
-	uint32_t total_timeout;	/* Total timeout (quantum count) */
-	uint32_t watchdogactive;
-#endif
-
 	struct srb *done_q_first;	/* First job on done queue */
 	struct srb *done_q_last;	/* Last job on done queue */
 

_