r2198 - trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches
Norbert Tretkowski
nobse@costa.debian.org
Sat, 08 Jan 2005 16:00:55 +0100
Author: nobse
Date: 2005-01-08 16:00:51 +0100 (Sat, 08 Jan 2005)
New Revision: 2198
Modified:
trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/qla1280-isp1040.dpatch
Log:
CONFIG_SCSI_QLOGIC_1280_1040 now depends on CONFIG_SCSI_QLOGIC_1280
Modified: trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/qla1280-isp1040.dpatch
===================================================================
--- trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/qla1280-isp1040.dpatch 2005-01-08 14:27:26 UTC (rev 2197)
+++ trunk/kernel/source/kernel-source-2.6.8-2.6.8/debian/patches/qla1280-isp1040.dpatch 2005-01-08 15:00:51 UTC (rev 2198)
@@ -1,1432 +1,53 @@
---- a/drivers/scsi/qla1280.c 11 Mar 2004 16:46:53 -0000 1.37
-+++ b/drivers/scsi/qla1280.c 20 Mar 2004 22:13:24 -0000
-@@ -4,7 +4,7 @@
- * QLogic QLA1280 (Ultra2) and QLA12160 (Ultra3) SCSI driver
- * Copyright (C) 2000 Qlogic Corporation (www.qlogic.com)
- * Copyright (C) 2001-2004 Jes Sorensen, Wild Open Source Inc.
--* Copyright (C) 2003 Christoph Hellwig
-+* Copyright (C) 2003-2004 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
-@@ -17,9 +17,12 @@
- * General Public License for more details.
- *
- ******************************************************************************/
--#define QLA1280_VERSION "3.24.3"
-+#define QLA1280_VERSION "3.25"
- /*****************************************************************************
- Revision History:
-+ Rev 3.25 March 21, 2004, Christoph Hellwig
-+ - Add support for ISP1020/1040.
-+ - Lots of cleanups.
- Rev 3.24.3 January 19, 2004, Jes Sorensen
- - Handle PCI DMA mask settings correctly
- - Correct order of error handling in probe_one, free_irq should not
-@@ -376,8 +379,10 @@
+diff -Nur kernel-source-2.6.8-2.6.8.orig/drivers/scsi/Kconfig kernel-source-2.6.8-2.6.8/drivers/scsi/Kconfig
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/Kconfig 2004-08-14 05:37:41.000000000 +0000
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/Kconfig 2005-01-08 14:40:16.000000000 +0000
+@@ -1221,7 +1221,7 @@
+ module will be called qlogicfas.
- /*
- * The SGI VISWS is broken and doesn't support MMIO ;-(
-+ *
-+ * The Origin PCI subsystem isn't ready for MMIO yet, later..
- */
--#ifdef CONFIG_X86_VISWS
-+#if defined(CONFIG_X86_VISWS) || defined(CONFIG_SGI_IP27)
- #define MEMORY_MAPPED_IO 0
- #else
- #define MEMORY_MAPPED_IO 1
-@@ -387,6 +392,7 @@
- #include "qla1280.h"
- #include "ql12160_fw.h" /* ISP RISC codes */
- #include "ql1280_fw.h"
-+#include "ql1040_fw.h"
+ config SCSI_QLOGIC_ISP
+- tristate "Qlogic ISP SCSI support"
++ tristate "Qlogic ISP SCSI support (old driver)"
+ depends on PCI && SCSI
+ ---help---
+ This driver works for all QLogic PCI SCSI host adapters (IQ-PCI,
+@@ -1238,6 +1238,9 @@
+ To compile this driver as a module, choose M here: the
+ module will be called qlogicisp.
-
- /*
-@@ -485,6 +491,13 @@ static inline void scsi_host_put(struct
- #define ia64_platform_is(foo) (!strcmp(x, platform_name))
- #endif
-
-+#define IS_ISP1040(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1020)
-+#define IS_ISP1x40(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1020 || \
-+ ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1240)
-+#define IS_ISP1x160(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160 || \
-+ ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160)
++ These days the hardware is also supported by the more modern qla1280
++ driver. In doubt use that one instead of qlogicisp.
+
-+
- static int qla1280_probe_one(struct pci_dev *, const struct pci_device_id *);
- static void qla1280_remove_one(struct pci_dev *);
+ config SCSI_QLOGIC_FC
+ tristate "Qlogic ISP FC SCSI support"
+ depends on PCI && SCSI
+@@ -1256,14 +1259,22 @@
+ qlogicfc driver. This is required on some platforms.
-@@ -501,9 +514,7 @@ static int qla1280_setup(char *s) __init
- /*
- * QLogic ISP1280 Hardware Support Function Prototypes.
- */
--static int qla1280_isp_firmware(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_load_firmware(struct scsi_qla_host *);
- static int qla1280_init_rings(struct scsi_qla_host *);
- static int qla1280_nvram_config(struct scsi_qla_host *);
- static int qla1280_mailbox_command(struct scsi_qla_host *,
-@@ -627,14 +638,16 @@ struct qla_boards {
- 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_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,
-+ {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
-- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280,
-+ {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
-- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160,
-+ {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
-+ {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
- {0,}
- };
- MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
-@@ -643,6 +656,8 @@ static struct qla_boards ql1280_board_tb
- /* Name , Number of ports, FW details */
- {"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01,
- &fw12160i_addr01, &fw12160i_version_str[0]},
-+ {"QLA1040", 1, &risc_code01[0], &risc_code_length01,
-+ &risc_code_addr01, &firmware_version[0]},
- {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01,
- &fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01,
-@@ -1381,48 +1396,37 @@ qla1280_intr_handler(int irq, void *dev_
- static int
- qla1280_set_target_parameters(struct scsi_qla_host *ha, int bus, int target)
- {
-- uint8_t mr;
- uint16_t mb[MAILBOX_REGISTER_COUNT];
-- struct nvram *nv;
-- int is1x160, status;
--
-- nv = &ha->nvram;
--
-- if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
-- ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160)
-- is1x160 = 1;
-- else
-- is1x160 = 0;
--
-- mr = BIT_3 | BIT_2 | BIT_1 | BIT_0;
-+ uint8_t mr = BIT_3 | BIT_2 | BIT_1 | BIT_0;
-+ struct nvram *nv = &ha->nvram;
-+ int err;
+ config SCSI_QLOGIC_1280
+- tristate "Qlogic QLA 1280 SCSI support"
++ tristate "Qlogic QLA 1240/1x80/1x160 SCSI support"
+ depends on PCI && SCSI
+ help
+- Say Y if you have a QLogic ISP1x80/1x160 SCSI host adapter.
++ Say Y if you have a QLogic ISP1240/1x80/1x160 SCSI host adapter.
- /* Set Target Parameters. */
- mb[0] = MBC_SET_TARGET_PARAMETERS;
- mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
- mb[1] <<= 8;
+ To compile this driver as a module, choose M here: the
+ module will be called qla1280.
-- mb[2] = (nv->bus[bus].target[target].parameter.c << 8);
--
-- if (is1x160)
-- mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
-- else
-- mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
-- mb[3] |= nv->bus[bus].target[target].sync_period;
--
-- if (is1x160) {
-- mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
-- mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8;
-- mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
-+ if (IS_ISP1x160(ha)) {
-+ mb[2] = nv->bus[bus].target[target].parameter.c << 8 |
-+ nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
-+ mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8 |
-+ nv->bus[bus].target[target].sync_period;
-+ mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8 |
-+ nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
- mr |= BIT_6;
-+ } else {
-+ mb[2] = nv->bus[bus].target[target].parameter.c << 8;
-+ mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8 |
-+ nv->bus[bus].target[target].sync_period;
- }
-
-- status = qla1280_mailbox_command(ha, mr, &mb[0]);
--
-- if (status)
-+ err = qla1280_mailbox_command(ha, mr, &mb[0]);
-+ if (err) {
- printk(KERN_WARNING "scsi(%ld:%i:%i): "
- "qla1280_set_target_parameters() failed\n",
- ha->host_no, bus, target);
-- return status;
-+ }
-+ return err;
- }
-
-
-@@ -1476,8 +1480,7 @@ qla1280_slave_configure(struct scsi_devi
- (driver_setup.wide_mask &&
- (~driver_setup.wide_mask & (1 << target))))
- nv->bus[bus].target[target].parameter.f.enable_wide = 0;
-- if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
-- ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160) {
-+ if (IS_ISP1x160(ha)) {
- if (driver_setup.no_ppr ||
- (driver_setup.ppr_mask &&
- (~driver_setup.ppr_mask & (1 << target))))
-@@ -1777,6 +1780,16 @@ qla1280_initialize_adapter(struct scsi_q
- driver_setup.no_nvram = 1;
- }
- #endif
-+#if defined(CONFIG_SGI_IP27)
-+ /*
-+ * No support for Option ROMs on Origins.
-+ */
-+ driver_setup.no_nvram = 1;
-+#endif
++config SCSI_QLOGIC_1280_1040
++ bool "Qlogic QLA 1020/1040 SCSI support"
++ depends on SCSI_QLOGIC_1280
++ help
++ Say Y here if you have a QLogic ISP1020/1040 SCSI host adapter and
++ do not want to use the old driver. This option enables support in
++ the qla1280 driver for those host adapters.
+
-+ /* TODO: implement support for the 1040 nvram format */
-+ if (IS_ISP1040(ha))
-+ driver_setup.no_nvram = 1;
-
- dprintk(1, "Configure PCI space for adapter...\n");
-
-@@ -1802,17 +1815,8 @@ qla1280_initialize_adapter(struct scsi_q
- */
- spin_lock_irqsave(HOST_LOCK, flags);
- #endif
-- /* If firmware needs to be loaded */
-- if (qla1280_isp_firmware(ha)) {
-- if (!(status = qla1280_chip_diag(ha))) {
-- status = qla1280_setup_chip(ha);
-- }
-- } else {
-- printk(KERN_ERR "scsi(%li): isp_firmware() failed!\n",
-- ha->host_no);
-- status = 1;
-- }
-
-+ status = qla1280_load_firmware(ha);
- if (status) {
- printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n",
- ha->host_no);
-@@ -1823,36 +1827,24 @@ qla1280_initialize_adapter(struct scsi_q
- dprintk(1, "scsi(%ld): Configure NVRAM parameters\n", ha->host_no);
- qla1280_nvram_config(ha);
-
-- if (!ha->flags.disable_host_adapter && !qla1280_init_rings(ha)) {
-- /* Issue SCSI reset. */
-- /* dg 03/13 if we can't reset twice then bus is dead */
-- for (bus = 0; bus < ha->ports; bus++) {
-- if (!ha->bus_settings[bus].disable_scsi_reset){
-- if (qla1280_bus_reset(ha, bus)) {
-- if (qla1280_bus_reset(ha, bus)) {
-- ha->bus_settings[bus].scsi_bus_dead = 1;
-- }
-- }
-- }
-- }
-+ if (ha->flags.disable_host_adapter) {
-+ status = 1;
-+ goto out;
-+ }
-
-- /*
-- * qla1280_bus_reset() will take care of issueing markers,
-- * no need to do that here as well!
-- */
--#if 0
-- /* Issue marker command. */
-- ha->flags.reset_marker = 0;
-- for (bus = 0; bus < ha->ports; bus++) {
-- ha->bus_settings[bus].reset_marker = 0;
-- qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL);
-- }
--#endif
-+ status = qla1280_init_rings(ha);
-+ if (status)
-+ goto out;
-
-- ha->flags.online = 1;
-- } else
-- status = 1;
-+ /* Issue SCSI reset, if we can't reset twice then bus is dead */
-+ for (bus = 0; bus < ha->ports; bus++) {
-+ if (!ha->bus_settings[bus].disable_scsi_reset &&
-+ qla1280_bus_reset(ha, bus) &&
-+ qla1280_bus_reset(ha, bus))
-+ ha->bus_settings[bus].scsi_bus_dead = 1;
-+ }
-
-+ ha->flags.online = 1;
- out:
- #if LINUX_VERSION_CODE >= 0x020500
- spin_unlock_irqrestore(HOST_LOCK, flags);
-@@ -1945,13 +1937,13 @@ qla1280_chip_diag(struct scsi_qla_host *
- int status = 0;
- int cnt;
- uint16_t data;
--
- dprintk(3, "qla1280_chip_diag: testing device at 0x%p \n", ®->id_l);
-
- dprintk(1, "scsi(%ld): Verifying chip\n", ha->host_no);
-
- /* Soft reset chip and wait for it to finish. */
- WRT_REG_WORD(®->ictrl, ISP_RESET);
-+
- /*
- * We can't do a traditional PCI write flush here by reading
- * back the register. The card will not respond once the reset
-@@ -1969,145 +1961,138 @@ qla1280_chip_diag(struct scsi_qla_host *
- data = RD_REG_WORD(®->ictrl);
- }
-
-- if (cnt) {
-- /* Reset register cleared by chip reset. */
-- dprintk(3, "qla1280_chip_diag: reset register cleared by "
-- "chip reset\n");
-+ if (!cnt)
-+ goto fail;
-
-- WRT_REG_WORD(®->cfg_1, 0);
-+ /* Reset register cleared by chip reset. */
-+ dprintk(3, "qla1280_chip_diag: reset register cleared by chip reset\n");
-
-- /* Reset RISC and disable BIOS which
-- allows RISC to execute out of RAM. */
--#if 0
-- WRT_REG_WORD(®->host_cmd, HC_RESET_RISC);
-- RD_REG_WORD(®->id_l); /* Flush PCI write */
-- WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC);
-- RD_REG_WORD(®->id_l); /* Flush PCI write */
-- WRT_REG_WORD(®->host_cmd, HC_DISABLE_BIOS);
--#else
-- WRT_REG_WORD(®->host_cmd, HC_RESET_RISC |
-- HC_RELEASE_RISC | HC_DISABLE_BIOS);
--#endif
-- RD_REG_WORD(®->id_l); /* Flush PCI write */
-- data = qla1280_debounce_register(®->mailbox0);
-- /*
-- * I *LOVE* this code!
-- */
-- for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) {
-- udelay(5);
-- data = RD_REG_WORD(®->mailbox0);
-- }
-+ WRT_REG_WORD(®->cfg_1, 0);
-
-- if (cnt) {
-- /* Check product ID of chip */
-- dprintk(3, "qla1280_chip_diag: Checking product "
-- "ID of chip\n");
--
-- if (RD_REG_WORD(®->mailbox1) != PROD_ID_1 ||
-- (RD_REG_WORD(®->mailbox2) != PROD_ID_2 &&
-- RD_REG_WORD(®->mailbox2) != PROD_ID_2a) ||
-- RD_REG_WORD(®->mailbox3) != PROD_ID_3 ||
-- RD_REG_WORD(®->mailbox4) != PROD_ID_4) {
-- printk(KERN_INFO "qla1280: Wrong product ID = "
-- "0x%x,0x%x,0x%x,0x%x\n",
-- RD_REG_WORD(®->mailbox1),
-- RD_REG_WORD(®->mailbox2),
-- RD_REG_WORD(®->mailbox3),
-- RD_REG_WORD(®->mailbox4));
-- status = 1;
-- } else {
-- /*
-- * Enable ints early!!!
-- */
-- qla1280_enable_intrs(ha);
--
-- dprintk(1, "qla1280_chip_diag: Checking "
-- "mailboxes of chip\n");
-- /* Wrap Incoming Mailboxes Test. */
-- mb[0] = MBC_MAILBOX_REGISTER_TEST;
-- mb[1] = 0xAAAA;
-- mb[2] = 0x5555;
-- mb[3] = 0xAA55;
-- mb[4] = 0x55AA;
-- mb[5] = 0xA5A5;
-- mb[6] = 0x5A5A;
-- mb[7] = 0x2525;
-- if (!(status = qla1280_mailbox_command(ha,
-- 0xff,
-- &mb
-- [0]))) {
-- if (mb[1] != 0xAAAA ||
-- mb[2] != 0x5555 ||
-- mb[3] != 0xAA55 ||
-- mb[4] != 0x55AA ||
-- mb[5] != 0xA5A5 ||
-- mb[6] != 0x5A5A ||
-- mb[7] != 0x2525) {
-- status = 1;
-- printk(KERN_INFO "qla1280: "
-- "Failed mbox check\n");
-- }
-- }
-- }
-- } else
-- status = 1;
-- } else
-- status = 1;
-+ /* Reset RISC and disable BIOS which
-+ allows RISC to execute out of RAM. */
-+ WRT_REG_WORD(®->host_cmd, HC_RESET_RISC |
-+ HC_RELEASE_RISC | HC_DISABLE_BIOS);
-
-+ RD_REG_WORD(®->id_l); /* Flush PCI write */
-+ data = qla1280_debounce_register(®->mailbox0);
-+
-+ /*
-+ * I *LOVE* this code!
-+ */
-+ for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) {
-+ udelay(5);
-+ data = RD_REG_WORD(®->mailbox0);
-+ }
-+
-+ if (!cnt)
-+ goto fail;
-+
-+ /* Check product ID of chip */
-+ dprintk(3, "qla1280_chip_diag: Checking product ID of chip\n");
-+
-+ if (RD_REG_WORD(®->mailbox1) != PROD_ID_1 ||
-+ (RD_REG_WORD(®->mailbox2) != PROD_ID_2 &&
-+ RD_REG_WORD(®->mailbox2) != PROD_ID_2a) ||
-+ RD_REG_WORD(®->mailbox3) != PROD_ID_3 ||
-+ RD_REG_WORD(®->mailbox4) != PROD_ID_4) {
-+ printk(KERN_INFO "qla1280: Wrong product ID = "
-+ "0x%x,0x%x,0x%x,0x%x\n",
-+ RD_REG_WORD(®->mailbox1),
-+ RD_REG_WORD(®->mailbox2),
-+ RD_REG_WORD(®->mailbox3),
-+ RD_REG_WORD(®->mailbox4));
-+ goto fail;
-+ }
-+
-+ /*
-+ * Enable ints early!!!
-+ */
-+ qla1280_enable_intrs(ha);
-+
-+ dprintk(1, "qla1280_chip_diag: Checking mailboxes of chip\n");
-+ /* Wrap Incoming Mailboxes Test. */
-+ mb[0] = MBC_MAILBOX_REGISTER_TEST;
-+ mb[1] = 0xAAAA;
-+ mb[2] = 0x5555;
-+ mb[3] = 0xAA55;
-+ mb[4] = 0x55AA;
-+ mb[5] = 0xA5A5;
-+ mb[6] = 0x5A5A;
-+ mb[7] = 0x2525;
-+
-+ status = qla1280_mailbox_command(ha, 0xff, mb);
- if (status)
-- dprintk(2, "qla1280_chip_diag: **** FAILED ****\n");
-- else
-- dprintk(3, "qla1280_chip_diag: exiting normally\n");
-+ goto fail;
-
-+ if (mb[1] != 0xAAAA || mb[2] != 0x5555 || mb[3] != 0xAA55 ||
-+ mb[4] != 0x55AA || mb[5] != 0xA5A5 || mb[6] != 0x5A5A ||
-+ mb[7] != 0x2525) {
-+ printk(KERN_INFO "qla1280: Failed mbox check\n");
-+ goto fail;
-+ }
-+
-+ dprintk(3, "qla1280_chip_diag: exiting normally\n");
-+ return 0;
-+ fail:
-+ dprintk(2, "qla1280_chip_diag: **** FAILED ****\n");
- return status;
- }
-
--/*
-- * Setup chip
-- * Load and start RISC firmware.
-- *
-- * Input:
-- * ha = adapter block pointer.
-- *
-- * Returns:
-- * 0 = success.
-- */
--#define DUMP_IT_BACK 0 /* for debug of RISC loading */
- static int
--qla1280_setup_chip(struct scsi_qla_host *ha)
-+qla1280_load_firmware_pio(struct scsi_qla_host *ha)
- {
-- int status = 0;
-- uint16_t risc_address;
-- uint16_t *risc_code_address;
-- int risc_code_size;
-- uint16_t mb[MAILBOX_REGISTER_COUNT];
-- uint16_t cnt;
-- int num, i;
--#if DUMP_IT_BACK
-- uint8_t *sp;
-- uint8_t *tbuf;
-- dma_addr_t p_tbuf;
--#endif
-+ uint16_t risc_address, *risc_code_address, risc_code_size;
-+ uint16_t mb[MAILBOX_REGISTER_COUNT], i;
-+ int err;
-
-- ENTER("qla1280_setup_chip");
-+ /* Load RISC code. */
-+ risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
-+ risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
-+ risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
-
-- dprintk(1, "scsi(%ld): Setup chip\n", ha->host_no);
-+ for (i = 0; i < risc_code_size; i++) {
-+ mb[0] = MBC_WRITE_RAM_WORD;
-+ mb[1] = risc_address + i;
-+ mb[2] = risc_code_address[i];
-+
-+ err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb);
-+ if (err) {
-+ printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
-+ ha->host_no);
-+ return err;
-+ }
-+ }
-+
-+ return 0;
-+}
-
-+#define DUMP_IT_BACK 0 /* for debug of RISC loading */
-+static int
-+qla1280_load_firmware_dma(struct scsi_qla_host *ha)
-+{
-+ uint16_t risc_address, *risc_code_address, risc_code_size;
-+ uint16_t mb[MAILBOX_REGISTER_COUNT], cnt;
-+ int err = 0, num, i;
- #if DUMP_IT_BACK
-- /* get consistent memory allocated for setup_chip */
-+ uint8_t *sp, *tbuf;
-+ dma_addr_t p_tbuf;
-+
- tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf);
-+ if (!tbuf)
-+ return -ENOMEM;
- #endif
-
- /* Load RISC code. */
- risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
- risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
-- risc_code_size = (int) *ql1280_board_tbl[ha->devnum].fwlen;
-+ risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
-
-- dprintk(1, "qla1280_setup_chip: DMA RISC code (%i) words\n",
-- risc_code_size);
-+ dprintk(1, "%s: DMA RISC code (%i) words\n",
-+ __FUNCTION__, risc_code_size);
-
- num = 0;
-- while (risc_code_size > 0 && !status) {
-+ while (risc_code_size > 0) {
- int warn __attribute__((unused)) = 0;
-
- cnt = 2000 >> 1;
-@@ -2129,15 +2114,16 @@ qla1280_setup_chip(struct scsi_qla_host
- mb[2] = (ha->request_dma >> 16) & 0xffff;
- mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff;
- mb[6] = pci_dma_hi32(ha->request_dma) >> 16;
-- dprintk(2, "qla1280_setup_chip: op=%d 0x%p = 0x%4x,0x%4x,"
-- "0x%4x,0x%4x\n", mb[0], (void *)(long)ha->request_dma,
-- mb[6], mb[7], mb[2], mb[3]);
-- if ((status = qla1280_mailbox_command(ha, BIT_4 | BIT_3 |
-- BIT_2 | BIT_1 | BIT_0,
-- &mb[0]))) {
-+ dprintk(2, "%s: op=%d 0x%p = 0x%4x,0x%4x,0x%4x,0x%4x\n",
-+ __FUNCTION__, mb[0],
-+ (void *)(long)ha->request_dma,
-+ mb[6], mb[7], mb[2], mb[3]);
-+ err = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | BIT_2 |
-+ BIT_1 | BIT_0, mb);
-+ if (err) {
- printk(KERN_ERR "scsi(%li): Failed to load partial "
- "segment of f\n", ha->host_no);
-- break;
-+ goto out;
- }
-
- #if DUMP_IT_BACK
-@@ -2149,22 +2135,22 @@ qla1280_setup_chip(struct scsi_qla_host
- mb[7] = pci_dma_hi32(p_tbuf) & 0xffff;
- mb[6] = pci_dma_hi32(p_tbuf) >> 16;
-
-- if ((status = qla1280_mailbox_command(ha,
-- BIT_4 | BIT_3 | BIT_2 |
-- BIT_1 | BIT_0,
-- &mb[0]))) {
-+ err = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | BIT_2 |
-+ BIT_1 | BIT_0, mb);
-+ if (err) {
- printk(KERN_ERR
- "Failed to dump partial segment of f/w\n");
-- break;
-+ goto out;
- }
- sp = (uint8_t *)ha->request_ring;
- for (i = 0; i < (cnt << 1); i++) {
- if (tbuf[i] != sp[i] && warn++ < 10) {
-- printk(KERN_ERR "qla1280_setup_chip: FW "
-- "compare error @ byte(0x%x) loop#=%x\n",
-- i, num);
-- printk(KERN_ERR "setup_chip: FWbyte=%x "
-- "FWfromChip=%x\n", sp[i], tbuf[i]);
-+ printk(KERN_ERR "%s: FW compare error @ "
-+ "byte(0x%x) loop#=%x\n",
-+ __FUNCTION__, i, num);
-+ printk(KERN_ERR "%s: FWbyte=%x "
-+ "FWfromChip=%x\n",
-+ __FUNCTION__, sp[i], tbuf[i]);
- /*break; */
- }
- }
-@@ -2175,37 +2161,69 @@ qla1280_setup_chip(struct scsi_qla_host
- num++;
- }
-
-- /* Verify checksum of loaded RISC code. */
-- if (!status) {
-- dprintk(1, "qla1280_setup_chip: Verifying checksum of "
-- "loaded RISC code.\n");
-- mb[0] = MBC_VERIFY_CHECKSUM;
-- /* mb[1] = ql12_risc_code_addr01; */
-- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
--
-- if (!(status =
-- qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) {
-- /* Start firmware execution. */
-- dprintk(1,
-- "qla1280_setup_chip: start firmware running.\n");
-- mb[0] = MBC_EXECUTE_FIRMWARE;
-- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
-- qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
-- } else
-- printk(KERN_ERR "scsi(%li): qla1280_setup_chip: "
-- "Failed checksum\n", ha->host_no);
-- }
--
-+ out:
- #if DUMP_IT_BACK
-- /* free consistent memory allocated for setup_chip */
- pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
- #endif
-+ return err;
-+}
-
-- if (status)
-- dprintk(2, "qla1280_setup_chip: **** FAILED ****\n");
-+static int
-+qla1280_start_firmware(struct scsi_qla_host *ha)
-+{
-+ uint16_t mb[MAILBOX_REGISTER_COUNT];
-+ int err;
-
-- LEAVE("qla1280_setup_chip");
-- return status;
-+ dprintk(1, "%s: Verifying checksum of loaded RISC code.\n",
-+ __FUNCTION__);
-+
-+ /* Verify checksum of loaded RISC code. */
-+ mb[0] = MBC_VERIFY_CHECKSUM;
-+ /* mb[1] = ql12_risc_code_addr01; */
-+ mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
-+ err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb);
-+ if (err) {
-+ printk(KERN_ERR "scsi(%li): Failed checksum\n", ha->host_no);
-+ return err;
-+ }
-+
-+ /* Start firmware execution. */
-+ dprintk(1, "%s: start firmware running.\n", __FUNCTION__);
-+ mb[0] = MBC_EXECUTE_FIRMWARE;
-+ mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
-+ err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
-+ if (err) {
-+ printk(KERN_ERR "scsi(%li): Failed to start firmware\n",
-+ ha->host_no);
-+ }
-+
-+ return err;
-+}
-+
-+static int
-+qla1280_load_firmware(struct scsi_qla_host *ha)
-+{
-+ int err = -ENODEV;
-+
-+ /* If firmware needs to be loaded */
-+ if (!qla1280_isp_firmware(ha)) {
-+ printk(KERN_ERR "scsi(%li): isp_firmware() failed!\n",
-+ ha->host_no);
-+ goto out;
-+ }
-+
-+ err = qla1280_chip_diag(ha);
-+ if (err)
-+ goto out;
-+ if (IS_ISP1040(ha))
-+ err = qla1280_load_firmware_pio(ha);
-+ else
-+ err = qla1280_load_firmware_dma(ha);
-+ if (err)
-+ goto out;
-+ err = qla1280_start_firmware(ha);
-+ out:
-+ return err;
- }
-
- /*
-@@ -2271,123 +2289,9 @@ qla1280_init_rings(struct scsi_qla_host
- return status;
- }
-
--/*
-- * NVRAM configuration.
-- *
-- * Input:
-- * ha = adapter block pointer.
-- * ha->request_ring = request ring virtual address
-- *
-- * Output:
-- * host adapters parameters in host adapter block
-- *
-- * Returns:
-- * 0 = success.
-- */
--static int
--qla1280_nvram_config(struct scsi_qla_host *ha)
-+static void
-+qla1280_print_settings(struct nvram *nv)
- {
-- struct device_reg *reg = ha->iobase;
-- struct nvram *nv;
-- int is1x160, status = 0;
-- int bus, target, lun;
-- uint16_t mb[MAILBOX_REGISTER_COUNT];
-- uint16_t mask;
--
-- ENTER("qla1280_nvram_config");
--
-- if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
-- ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160)
-- is1x160 = 1;
-- else
-- is1x160 = 0;
--
-- nv = &ha->nvram;
-- if (!ha->nvram_valid) {
-- dprintk(1, "Using defaults for NVRAM: \n");
-- memset(nv, 0, sizeof(struct nvram));
--
-- /* nv->cntr_flags_1.disable_loading_risc_code = 1; */
-- nv->firmware_feature.f.enable_fast_posting = 1;
-- nv->firmware_feature.f.disable_synchronous_backoff = 1;
--
-- nv->termination.f.scsi_bus_0_control = 3;
-- nv->termination.f.scsi_bus_1_control = 3;
-- nv->termination.f.auto_term_support = 1;
--
-- /*
-- * Set default FIFO magic - What appropriate values
-- * would be here is unknown. This is what I have found
-- * testing with 12160s.
-- * Now, I would love the magic decoder ring for this one,
-- * the header file provided by QLogic seems to be bogus
-- * or incomplete at best.
-- */
-- nv->isp_config.c = 0x44;
--
-- if (is1x160)
-- nv->isp_parameter = 0x01;
--
-- for (bus = 0; bus < MAX_BUSES; bus++) {
-- nv->bus[bus].config_1.initiator_id = 7;
-- nv->bus[bus].bus_reset_delay = 5;
-- /* 8 = 5.0 clocks */
-- nv->bus[bus].config_2.async_data_setup_time = 8;
-- nv->bus[bus].config_2.req_ack_active_negation = 1;
-- nv->bus[bus].config_2.data_line_active_negation = 1;
-- nv->bus[bus].selection_timeout = 250;
-- nv->bus[bus].max_queue_depth = 256;
--
-- for (target = 0; target < MAX_TARGETS; target++) {
-- nv->bus[bus].target[target].parameter.f.
-- renegotiate_on_error = 1;
-- nv->bus[bus].target[target].parameter.f.
-- auto_request_sense = 1;
-- nv->bus[bus].target[target].parameter.f.
-- tag_queuing = 1;
-- nv->bus[bus].target[target].parameter.f.
-- enable_sync = 1;
--#if 1 /* Some SCSI Processors do not seem to like this */
-- nv->bus[bus].target[target].parameter.f.
-- enable_wide = 1;
--#endif
-- nv->bus[bus].target[target].parameter.f.
-- parity_checking = 1;
-- nv->bus[bus].target[target].parameter.f.
-- disconnect_allowed = 1;
-- nv->bus[bus].target[target].execution_throttle=
-- nv->bus[bus].max_queue_depth - 1;
-- if (is1x160) {
-- nv->bus[bus].target[target].flags.
-- flags1x160.device_enable = 1;
-- nv->bus[bus].target[target].flags.
-- flags1x160.sync_offset = 0x0e;
-- nv->bus[bus].target[target].
-- sync_period = 9;
-- nv->bus[bus].target[target].
-- ppr_1x160.flags.enable_ppr = 1;
-- nv->bus[bus].target[target].ppr_1x160.
-- flags.ppr_options = 2;
-- nv->bus[bus].target[target].ppr_1x160.
-- flags.ppr_bus_width = 1;
-- } else {
-- nv->bus[bus].target[target].flags.
-- flags1x80.device_enable = 1;
-- nv->bus[bus].target[target].flags.
-- flags1x80.sync_offset = 0x8;
-- nv->bus[bus].target[target].
-- sync_period = 10;
-- }
-- }
-- }
-- } else {
-- /* Always force AUTO sense for LINUX SCSI */
-- for (bus = 0; bus < MAX_BUSES; bus++)
-- for (target = 0; target < MAX_TARGETS; target++) {
-- nv->bus[bus].target[target].parameter.f.
-- auto_request_sense = 1;
-- }
-- }
- dprintk(1, "qla1280 : initiator scsi id bus[0]=%d\n",
- nv->bus[0].config_1.initiator_id);
- dprintk(1, "qla1280 : initiator scsi id bus[1]=%d\n",
-@@ -2433,36 +2337,264 @@ qla1280_nvram_config(struct scsi_qla_hos
- nv->bus[0].max_queue_depth);
- dprintk(1, "qla1280 : max queue depth[1]=%d\n",
- nv->bus[1].max_queue_depth);
-+}
-+
-+static void
-+qla1280_set_target_defaults(struct scsi_qla_host *ha, int bus, int target)
-+{
-+ struct nvram *nv = &ha->nvram;
-+
-+ nv->bus[bus].target[target].parameter.f.renegotiate_on_error = 1;
-+ nv->bus[bus].target[target].parameter.f.auto_request_sense = 1;
-+ nv->bus[bus].target[target].parameter.f.tag_queuing = 1;
-+ nv->bus[bus].target[target].parameter.f.enable_sync = 1;
-+#if 1 /* Some SCSI Processors do not seem to like this */
-+ nv->bus[bus].target[target].parameter.f.enable_wide = 1;
-+#endif
-+ if (!IS_ISP1040(ha))
-+ nv->bus[bus].target[target].parameter.f.parity_checking = 1;
-+
-+ nv->bus[bus].target[target].parameter.f.disconnect_allowed = 1;
-+ nv->bus[bus].target[target].execution_throttle =
-+ nv->bus[bus].max_queue_depth - 1;
-+
-+ if (IS_ISP1x160(ha)) {
-+ nv->bus[bus].target[target].flags.flags1x160.device_enable = 1;
-+ nv->bus[bus].target[target].flags.flags1x160.sync_offset = 0x0e;
-+ nv->bus[bus].target[target].sync_period = 9;
-+ nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 1;
-+ nv->bus[bus].target[target].ppr_1x160.flags.ppr_options = 2;
-+ nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width = 1;
-+ } else {
-+ nv->bus[bus].target[target].flags.flags1x80.device_enable = 1;
-+ nv->bus[bus].target[target].flags.flags1x80.sync_offset = 12;
-+ nv->bus[bus].target[target].sync_period = 10;
-+ }
-+}
-+
-+static void
-+qla1280_set_defaults(struct scsi_qla_host *ha)
-+{
-+ struct nvram *nv = &ha->nvram;
-+ int bus, target;
-+
-+ dprintk(1, "Using defaults for NVRAM: \n");
-+ memset(nv, 0, sizeof(struct nvram));
-+
-+ /* nv->cntr_flags_1.disable_loading_risc_code = 1; */
-+ nv->firmware_feature.f.enable_fast_posting = 1;
-+ nv->firmware_feature.f.disable_synchronous_backoff = 1;
-+ nv->termination.f.scsi_bus_0_control = 3;
-+ nv->termination.f.scsi_bus_1_control = 3;
-+ nv->termination.f.auto_term_support = 1;
-+
-+ /*
-+ * Set default FIFO magic - What appropriate values would be here
-+ * is unknown. This is what I have found testing with 12160s.
-+ *
-+ * Now, I would love the magic decoder ring for this one, the
-+ * header file provided by QLogic seems to be bogus or incomplete
-+ * at best.
-+ */
-+ nv->isp_config.c = ISP_CFG1_BENAB|ISP_CFG1_F128;
-+ if (IS_ISP1x160(ha))
-+ nv->isp_parameter = 0x01; /* fast memory enable */
-+
-+ for (bus = 0; bus < MAX_BUSES; bus++) {
-+ nv->bus[bus].config_1.initiator_id = 7;
-+ nv->bus[bus].config_2.req_ack_active_negation = 1;
-+ nv->bus[bus].config_2.data_line_active_negation = 1;
-+ nv->bus[bus].selection_timeout = 250;
-+ nv->bus[bus].max_queue_depth = 256;
-+
-+ if (IS_ISP1040(ha)) {
-+ nv->bus[bus].bus_reset_delay = 3;
-+ nv->bus[bus].config_2.async_data_setup_time = 6;
-+ nv->bus[bus].retry_delay = 1;
-+ } else {
-+ nv->bus[bus].bus_reset_delay = 5;
-+ nv->bus[bus].config_2.async_data_setup_time = 8;
-+ }
-+
-+ for (target = 0; target < MAX_TARGETS; target++)
-+ qla1280_set_target_defaults(ha, bus, target);
-+ }
-+}
-+
-+static int
-+qla1280_config_target(struct scsi_qla_host *ha, int bus, int target)
-+{
-+ struct nvram *nv = &ha->nvram;
-+ uint16_t mb[MAILBOX_REGISTER_COUNT];
-+ int status, lun;
-+
-+ /* Set Target Parameters. */
-+ mb[0] = MBC_SET_TARGET_PARAMETERS;
-+ mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
-+ mb[1] <<= 8;
-+
-+ /*
-+ * Do not enable wide, sync, and ppr for the initial
-+ * INQUIRY run. We enable this later if we determine
-+ * the target actually supports it.
-+ */
-+ nv->bus[bus].target[target].parameter.f.
-+ auto_request_sense = 1;
-+ nv->bus[bus].target[target].parameter.f.
-+ stop_queue_on_check = 0;
-+
-+ if (IS_ISP1x160(ha))
-+ nv->bus[bus].target[target].ppr_1x160.
-+ flags.enable_ppr = 0;
-+
-+ /*
-+ * No sync, wide, etc. while probing
-+ */
-+ mb[2] = (nv->bus[bus].target[target].parameter.c << 8) &
-+ ~(TP_SYNC /*| TP_WIDE | TP_PPR*/);
-+
-+ if (IS_ISP1x160(ha))
-+ mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
-+ else
-+ mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
-+ mb[3] |= nv->bus[bus].target[target].sync_period;
-+
-+ status = qla1280_mailbox_command(ha, BIT_3 | BIT_2 | BIT_1 | BIT_0, &mb[0]);
-+
-+ /* Save Tag queuing enable flag. */
-+ mb[0] = BIT_0 << target;
-+ if (nv->bus[bus].target[target].parameter.f.tag_queuing)
-+ ha->bus_settings[bus].qtag_enables |= mb[0];
-+
-+ /* Save Device enable flag. */
-+ if (IS_ISP1x160(ha)) {
-+ if (nv->bus[bus].target[target].flags.flags1x160.device_enable)
-+ ha->bus_settings[bus].device_enables |= mb[0];
-+ ha->bus_settings[bus].lun_disables |= 0;
-+ } else {
-+ if (nv->bus[bus].target[target].flags.flags1x80.device_enable)
-+ ha->bus_settings[bus].device_enables |= mb[0];
-+ /* Save LUN disable flag. */
-+ if (nv->bus[bus].target[target].flags.flags1x80.lun_disable)
-+ ha->bus_settings[bus].lun_disables |= mb[0];
-+ }
-+
-+ /* Set Device Queue Parameters. */
-+ for (lun = 0; lun < MAX_LUNS; lun++) {
-+ mb[0] = MBC_SET_DEVICE_QUEUE;
-+ mb[1] = (uint16_t)(bus ? target | BIT_7 : target);
-+ mb[1] = mb[1] << 8 | lun;
-+ mb[2] = nv->bus[bus].max_queue_depth;
-+ mb[3] = nv->bus[bus].target[target].execution_throttle;
-+ status |= qla1280_mailbox_command(ha, 0x0f, &mb[0]);
-+ }
-+
-+ return status;
-+}
-+
-+static int
-+qla1280_config_bus(struct scsi_qla_host *ha, int bus)
-+{
-+ struct nvram *nv = &ha->nvram;
-+ uint16_t mb[MAILBOX_REGISTER_COUNT];
-+ int target, status;
-+
-+ /* SCSI Reset Disable. */
-+ ha->bus_settings[bus].disable_scsi_reset =
-+ nv->bus[bus].config_1.scsi_reset_disable;
-+
-+ /* Initiator ID. */
-+ ha->bus_settings[bus].id = nv->bus[bus].config_1.initiator_id;
-+ mb[0] = MBC_SET_INITIATOR_ID;
-+ mb[1] = bus ? ha->bus_settings[bus].id | BIT_7 :
-+ ha->bus_settings[bus].id;
-+ status = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
-+
-+ /* Reset Delay. */
-+ ha->bus_settings[bus].bus_reset_delay =
-+ nv->bus[bus].bus_reset_delay;
-+
-+ /* Command queue depth per device. */
-+ ha->bus_settings[bus].hiwat = nv->bus[bus].max_queue_depth - 1;
-+
-+ /* Set target parameters. */
-+ for (target = 0; target < MAX_TARGETS; target++)
-+ status |= qla1280_config_target(ha, bus, target);
-+
-+ return status;
-+}
-+
-+static int
-+qla1280_nvram_config(struct scsi_qla_host *ha)
-+{
-+ struct device_reg *reg = ha->iobase;
-+ struct nvram *nv = &ha->nvram;
-+ int bus, target, status = 0;
-+ uint16_t mb[MAILBOX_REGISTER_COUNT];
-+ uint16_t mask;
-+
-+ ENTER("qla1280_nvram_config");
-+
-+ if (ha->nvram_valid) {
-+ /* Always force AUTO sense for LINUX SCSI */
-+ for (bus = 0; bus < MAX_BUSES; bus++)
-+ for (target = 0; target < MAX_TARGETS; target++) {
-+ nv->bus[bus].target[target].parameter.f.
-+ auto_request_sense = 1;
-+ }
-+ } else {
-+ qla1280_set_defaults(ha);
-+ }
-+
-+ qla1280_print_settings(nv);
-
- /* Disable RISC load of firmware. */
- ha->flags.disable_risc_code_load =
- nv->cntr_flags_1.disable_loading_risc_code;
-
-- /* Set ISP hardware DMA burst */
-- mb[0] = nv->isp_config.c;
-- /* Enable DMA arbitration on dual channel controllers */
-- if (ha->ports > 1)
-- mb[0] |= BIT_13;
-- WRT_REG_WORD(®->cfg_1, mb[0]);
--
--#if 1 /* Is this safe? */
-- /* Set SCSI termination. */
-- WRT_REG_WORD(®->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0));
-- mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0);
-- WRT_REG_WORD(®->gpio_data, mb[0]);
--#endif
-+ if (IS_ISP1040(ha)) {
-+ uint16_t hwrev, cfg1, cdma_conf, ddma_conf;
-+
-+ hwrev = RD_REG_WORD(®->cfg_0) & ISP_CFG0_HWMSK;
-+
-+ cfg1 = RD_REG_WORD(®->cfg_1);
-+ cdma_conf = RD_REG_WORD(®->cdma_cfg);
-+ ddma_conf = RD_REG_WORD(®->ddma_cfg);
-+
-+ /* Busted fifo, says mjacob. */
-+ if (hwrev == ISP_CFG0_1040A)
-+ WRT_REG_WORD(®->cfg_1, cfg1 | ISP_CFG1_F64);
-+ else
-+ WRT_REG_WORD(®->cfg_1, cfg1 | ISP_CFG1_F64 | ISP_CFG1_BENAB);
-+
-+ WRT_REG_WORD(®->cdma_cfg, cdma_conf | CDMA_CONF_BENAB);
-+ WRT_REG_WORD(®->ddma_cfg, cdma_conf | DDMA_CONF_BENAB);
-+ } else {
-+ /* Set ISP hardware DMA burst */
-+ mb[0] = nv->isp_config.c;
-+ /* Enable DMA arbitration on dual channel controllers */
-+ if (ha->ports > 1)
-+ mb[0] |= BIT_13;
-+ WRT_REG_WORD(®->cfg_1, mb[0]);
-+
-+ /* Set SCSI termination. */
-+ WRT_REG_WORD(®->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0));
-+ mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0);
-+ WRT_REG_WORD(®->gpio_data, mb[0]);
-+ }
-
- /* ISP parameter word. */
- mb[0] = MBC_SET_SYSTEM_PARAMETER;
- mb[1] = nv->isp_parameter;
- status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
-
--#if 0
-- /* clock rate - for qla1240 and older, only */
-- mb[0] = MBC_SET_CLOCK_RATE;
-- mb[1] = 0x50;
-- status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
--#endif
-+ if (IS_ISP1x40(ha)) {
-+ /* clock rate - for qla1240 and older, only */
-+ mb[0] = MBC_SET_CLOCK_RATE;
-+ mb[1] = 40;
-+ status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb);
-+ }
-+
- /* Firmware feature word. */
- mb[0] = MBC_SET_FIRMWARE_FEATURES;
- mask = BIT_5 | BIT_1 | BIT_0;
-@@ -2515,112 +2647,18 @@ qla1280_nvram_config(struct scsi_qla_hos
- mb[2] = 2; /* Command DMA Channel Burst Enable */
- status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
-
-+ mb[0] = MBC_SET_TAG_AGE_LIMIT;
-+ mb[1] = 8;
-+ status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
-+
- /* Selection timeout. */
- mb[0] = MBC_SET_SELECTION_TIMEOUT;
- mb[1] = nv->bus[0].selection_timeout;
- mb[2] = nv->bus[1].selection_timeout;
- status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
-
-- for (bus = 0; bus < ha->ports; bus++) {
-- /* SCSI Reset Disable. */
-- ha->bus_settings[bus].disable_scsi_reset =
-- nv->bus[bus].config_1.scsi_reset_disable;
--
-- /* Initiator ID. */
-- ha->bus_settings[bus].id = nv->bus[bus].config_1.initiator_id;
-- mb[0] = MBC_SET_INITIATOR_ID;
-- mb[1] = bus ? ha->bus_settings[bus].id | BIT_7 :
-- ha->bus_settings[bus].id;
-- status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
--
-- /* Reset Delay. */
-- ha->bus_settings[bus].bus_reset_delay =
-- nv->bus[bus].bus_reset_delay;
--
-- /* Command queue depth per device. */
-- ha->bus_settings[bus].hiwat = nv->bus[bus].max_queue_depth - 1;
--
-- /* Set target parameters. */
-- for (target = 0; target < MAX_TARGETS; target++) {
-- uint8_t mr = BIT_2 | BIT_1 | BIT_0;
--
-- /* Set Target Parameters. */
-- mb[0] = MBC_SET_TARGET_PARAMETERS;
-- mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
-- mb[1] <<= 8;
-- /*
-- * Do not enable wide, sync, and ppr for the initial
-- * INQUIRY run. We enable this later if we determine
-- * the target actually supports it.
-- */
-- nv->bus[bus].target[target].parameter.f.
-- auto_request_sense = 1;
-- nv->bus[bus].target[target].parameter.f.
-- stop_queue_on_check = 0;
--
-- if (is1x160)
-- nv->bus[bus].target[target].ppr_1x160.
-- flags.enable_ppr = 0;
-- /*
-- * No sync, wide, etc. while probing
-- */
-- mb[2] = (nv->bus[bus].target[target].parameter.c << 8)&
-- ~(TP_SYNC /*| TP_WIDE | TP_PPR*/);
--
-- if (is1x160)
-- mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
-- else
-- mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
-- mb[3] |= nv->bus[bus].target[target].sync_period;
-- mr |= BIT_3;
--
-- /*
-- * We don't want to enable ppr etc. before we have
-- * determined that the target actually supports it
-- */
--#if 0
-- if (is1x160) {
-- mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
--
-- mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8;
-- mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
-- mr |= BIT_6;
-- }
--#endif
--
-- status = qla1280_mailbox_command(ha, mr, &mb[0]);
--
-- /* Save Tag queuing enable flag. */
-- mb[0] = BIT_0 << target;
-- if (nv->bus[bus].target[target].parameter.f.tag_queuing)
-- ha->bus_settings[bus].qtag_enables |= mb[0];
--
-- /* Save Device enable flag. */
-- if (is1x160) {
-- if (nv->bus[bus].target[target].flags.flags1x160.device_enable)
-- ha->bus_settings[bus].device_enables |= mb[0];
-- ha->bus_settings[bus].lun_disables |= 0;
-- } else {
-- if (nv->bus[bus].target[target].flags.flags1x80.device_enable)
-- ha->bus_settings[bus].device_enables |= mb[0];
-- /* Save LUN disable flag. */
-- if (nv->bus[bus].target[target].flags.flags1x80.lun_disable)
-- ha->bus_settings[bus].lun_disables |= mb[0];
-- }
--
--
-- /* Set Device Queue Parameters. */
-- for (lun = 0; lun < MAX_LUNS; lun++) {
-- mb[0] = MBC_SET_DEVICE_QUEUE;
-- mb[1] = (uint16_t)(bus ? target | BIT_7 : target);
-- mb[1] = mb[1] << 8 | lun;
-- mb[2] = nv->bus[bus].max_queue_depth;
-- mb[3] = nv->bus[bus].target[target].execution_throttle;
-- status |= qla1280_mailbox_command(ha, 0x0f,
-- &mb[0]);
-- }
-- }
-- }
-+ for (bus = 0; bus < ha->ports; bus++)
-+ status |= qla1280_config_bus(ha, bus);
-
- if (status)
- dprintk(2, "qla1280_nvram_config: **** FAILED ****\n");
-@@ -4228,6 +4266,7 @@ qla1280_error_entry(struct scsi_qla_host
- static int
- qla1280_abort_isp(struct scsi_qla_host *ha)
- {
-+ struct device_reg *reg = ha->iobase;
- struct srb *sp;
- int status = 0;
- int cnt;
-@@ -4235,69 +4274,53 @@ qla1280_abort_isp(struct scsi_qla_host *
-
- ENTER("qla1280_abort_isp");
-
-- if (!ha->flags.abort_isp_active && ha->flags.online) {
-- struct device_reg *reg = ha->iobase;
-- ha->flags.abort_isp_active = 1;
--
-- /* Disable ISP interrupts. */
-- qla1280_disable_intrs(ha);
-- WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC);
-- RD_REG_WORD(®->id_l);
--
-- printk(KERN_INFO "scsi(%li): dequeuing outstanding commands\n",
-- ha->host_no);
-- /* Dequeue all commands in outstanding command list. */
-- for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-- struct scsi_cmnd *cmd;
-- sp = ha->outstanding_cmds[cnt];
-- if (sp) {
-+ if (ha->flags.abort_isp_active || !ha->flags.online)
-+ goto out;
-+
-+ ha->flags.abort_isp_active = 1;
-
-- cmd = sp->cmd;
-- CMD_RESULT(cmd) = DID_RESET << 16;
-+ /* Disable ISP interrupts. */
-+ qla1280_disable_intrs(ha);
-+ WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC);
-+ RD_REG_WORD(®->id_l);
-+
-+ printk(KERN_INFO "scsi(%li): dequeuing outstanding commands\n",
-+ ha->host_no);
-+ /* Dequeue all commands in outstanding command list. */
-+ for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-+ struct scsi_cmnd *cmd;
-+ sp = ha->outstanding_cmds[cnt];
-+ if (sp) {
-+
-+ cmd = sp->cmd;
-+ CMD_RESULT(cmd) = DID_RESET << 16;
-
-- sp->cmd = NULL;
-- ha->outstanding_cmds[cnt] = NULL;
-+ sp->cmd = NULL;
-+ ha->outstanding_cmds[cnt] = NULL;
-
-- (*cmd->scsi_done)(cmd);
-+ (*cmd->scsi_done)(cmd);
-
-- sp->flags = 0;
-- }
-+ sp->flags = 0;
- }
-+ }
-
-- /* If firmware needs to be loaded */
-- if (qla1280_isp_firmware (ha)) {
-- if (!(status = qla1280_chip_diag(ha)))
-- status = qla1280_setup_chip(ha);
-- }
-+ status = qla1280_load_firmware(ha);
-+ if (status)
-+ goto out;
-
-- if (!status) {
-- /* Setup adapter based on NVRAM parameters. */
-- qla1280_nvram_config (ha);
--
-- if (!(status = qla1280_init_rings(ha))) {
-- /* Issue SCSI reset. */
-- for (bus = 0; bus < ha->ports; bus++) {
-- qla1280_bus_reset(ha, bus);
-- }
-- /*
-- * qla1280_bus_reset() will do the marker
-- * dance - no reason to repeat here!
-- */
--#if 0
-- /* Issue marker command. */
-- ha->flags.reset_marker = 0;
-- for (bus = 0; bus < ha->ports; bus++) {
-- ha->bus_settings[bus].
-- reset_marker = 0;
-- qla1280_marker(ha, bus, 0, 0,
-- MK_SYNC_ALL);
-- }
--#endif
-- ha->flags.abort_isp_active = 0;
-- }
-- }
-- }
-+ /* Setup adapter based on NVRAM parameters. */
-+ qla1280_nvram_config (ha);
-
-+ status = qla1280_init_rings(ha);
-+ if (status)
-+ goto out;
-+
-+ /* Issue SCSI reset. */
-+ for (bus = 0; bus < ha->ports; bus++)
-+ qla1280_bus_reset(ha, bus);
-+
-+ ha->flags.abort_isp_active = 0;
-+ out:
- if (status) {
- printk(KERN_WARNING
- "qla1280: ISP error recovery failed, board disabled");
-Index: drivers/scsi/qla1280.h
-===================================================================
-RCS file: /home/cvs/linux/drivers/scsi/qla1280.h,v
-retrieving revision 1.17
-diff -u -p -r1.17 qla1280.h
---- a/drivers/scsi/qla1280.h 5 Feb 2004 02:40:03 -0000 1.17
-+++ b/drivers/scsi/qla1280.h 20 Mar 2004 22:13:24 -0000
-@@ -125,7 +125,20 @@ struct device_reg {
- uint16_t id_l; /* ID low */
- uint16_t id_h; /* ID high */
- uint16_t cfg_0; /* Configuration 0 */
-+#define ISP_CFG0_HWMSK 0x000f /* Hardware revision mask */
-+#define ISP_CFG0_1020 BIT_0 /* ISP1020 */
-+#define ISP_CFG0_1020A BIT_1 /* ISP1020A */
-+#define ISP_CFG0_1040 BIT_2 /* ISP1040 */
-+#define ISP_CFG0_1040A BIT_3 /* ISP1040A */
-+#define ISP_CFG0_1040B BIT_4 /* ISP1040B */
-+#define ISP_CFG0_1040C BIT_5 /* ISP1040C */
- uint16_t cfg_1; /* Configuration 1 */
-+#define ISP_CFG1_F128 BIT_6 /* 128-byte FIFO threshold */
-+#define ISP_CFG1_F64 BIT_4|BIT_5 /* 128-byte FIFO threshold */
-+#define ISP_CFG1_F32 BIT_5 /* 128-byte FIFO threshold */
-+#define ISP_CFG1_F16 BIT_4 /* 128-byte FIFO threshold */
-+#define ISP_CFG1_BENAB BIT_2 /* Global Bus burst enable */
-+#define ISP_CFG1_SXP BIT_0 /* SXP register select */
- uint16_t ictrl; /* Interface control */
- #define ISP_RESET BIT_0 /* ISP soft reset */
- #define ISP_EN_INT BIT_1 /* ISP enable interrupts. */
-@@ -146,7 +159,42 @@ struct device_reg {
- uint16_t flash_data; /* Flash BIOS data */
- uint16_t flash_address; /* Flash BIOS address */
-
-- uint16_t unused_1[0x2e]; /* 0x14-0x6f Gap */
-+ uint16_t unused_1[0x06];
-+
-+ /* cdma_* and ddma_* are 1040 only */
-+ uint16_t cdma_cfg;
-+#define CDMA_CONF_SENAB BIT_3 /* SXP to DMA Data enable */
-+#define CDMA_CONF_RIRQ BIT_2 /* RISC interrupt enable */
-+#define CDMA_CONF_BENAB BIT_1 /* Bus burst enable */
-+#define CDMA_CONF_DIR BIT_0 /* DMA direction (0=fifo->host 1=host->fifo) */
-+ uint16_t cdma_ctrl;
-+ uint16_t cdma_status;
-+ uint16_t cdma_fifo_status;
-+ uint16_t cdma_count;
-+ uint16_t cdma_reserved;
-+ uint16_t cdma_address_count_0;
-+ uint16_t cdma_address_count_1;
-+ uint16_t cdma_address_count_2;
-+ uint16_t cdma_address_count_3;
-+
-+ uint16_t unused_2[0x06];
-+
-+ uint16_t ddma_cfg;
-+#define DDMA_CONF_SENAB BIT_3 /* SXP to DMA Data enable */
-+#define DDMA_CONF_RIRQ BIT_2 /* RISC interrupt enable */
-+#define DDMA_CONF_BENAB BIT_1 /* Bus burst enable */
-+#define DDMA_CONF_DIR BIT_0 /* DMA direction (0=fifo->host 1=host->fifo) */
-+ uint16_t ddma_ctrl;
-+ uint16_t ddma_status;
-+ uint16_t ddma_fifo_status;
-+ uint16_t ddma_xfer_count_low;
-+ uint16_t ddma_xfer_count_high;
-+ uint16_t ddma_addr_count_0;
-+ uint16_t ddma_addr_count_1;
-+ uint16_t ddma_addr_count_2;
-+ uint16_t ddma_addr_count_3;
-+
-+ uint16_t unused_3[0x0e];
-
- uint16_t mailbox0; /* Mailbox 0 */
- uint16_t mailbox1; /* Mailbox 1 */
-@@ -157,18 +205,18 @@ struct device_reg {
- uint16_t mailbox6; /* Mailbox 6 */
- uint16_t mailbox7; /* Mailbox 7 */
-
-- uint16_t unused_2[0x20];/* 0x80-0xbf Gap */
-+ uint16_t unused_4[0x20];/* 0x80-0xbf Gap */
-
- uint16_t host_cmd; /* Host command and control */
- #define HOST_INT BIT_7 /* host interrupt bit */
- #define BIOS_ENABLE BIT_0
-
-- uint16_t unused_6[0x5]; /* 0xc2-0xcb Gap */
-+ uint16_t unused_5[0x5]; /* 0xc2-0xcb Gap */
-
- uint16_t gpio_data;
- uint16_t gpio_enable;
-
-- uint16_t unused_7[0x11]; /* d0-f0 */
-+ uint16_t unused_6[0x11]; /* d0-f0 */
- uint16_t scsiControlPins; /* f2 */
- };
-
---- /dev/null 2004-03-11 09:00:08.000000000 -0800
-+++ b/drivers/scsi/ql1040_fw.h 2004-02-10 12:42:37.000000000 -0800
+ config SCSI_QLOGICPTI
+ tristate "PTI Qlogic, ISP Driver"
+ depends on SBUS && SCSI
+diff -Nur kernel-source-2.6.8-2.6.8.orig/drivers/scsi/ql1040_fw.h kernel-source-2.6.8-2.6.8/drivers/scsi/ql1040_fw.h
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/ql1040_fw.h 1970-01-01 00:00:00.000000000 +0000
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/ql1040_fw.h 2005-01-08 14:39:38.000000000 +0000
@@ -0,0 +1,2101 @@
+/**************************************************************************
+ * QLOGIC LINUX SOFTWARE
@@ -3529,3 +2150,1435 @@
+};
+unsigned short risc_code_length01 = 0x4057;
+
+diff -Nur kernel-source-2.6.8-2.6.8.orig/drivers/scsi/qla1280.c kernel-source-2.6.8-2.6.8/drivers/scsi/qla1280.c
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/qla1280.c 2004-08-14 05:38:10.000000000 +0000
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/qla1280.c 2005-01-08 14:39:38.000000000 +0000
+@@ -4,7 +4,7 @@
+ * QLogic QLA1280 (Ultra2) and QLA12160 (Ultra3) SCSI driver
+ * Copyright (C) 2000 Qlogic Corporation (www.qlogic.com)
+ * Copyright (C) 2001-2004 Jes Sorensen, Wild Open Source Inc.
+-* Copyright (C) 2003 Christoph Hellwig
++* Copyright (C) 2003-2004 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
+@@ -17,9 +17,12 @@
+ * General Public License for more details.
+ *
+ ******************************************************************************/
+-#define QLA1280_VERSION "3.24.3"
++#define QLA1280_VERSION "3.25"
+ /*****************************************************************************
+ Revision History:
++ Rev 3.25 March 21, 2004, Christoph Hellwig
++ - Add support for ISP1020/1040.
++ - Lots of cleanups.
+ Rev 3.24.3 January 19, 2004, Jes Sorensen
+ - Handle PCI DMA mask settings correctly
+ - Correct order of error handling in probe_one, free_irq should not
+@@ -353,7 +356,6 @@
+ #include <scsi/scsi_device.h>
+ #include <scsi/scsi_host.h>
+ #include <scsi/scsi_tcq.h>
+-#include "scsi.h"
+ #else
+ #include <linux/blk.h>
+ #include "scsi.h"
+@@ -376,8 +378,10 @@
+
+ /*
+ * The SGI VISWS is broken and doesn't support MMIO ;-(
++ *
++ * The Origin PCI subsystem isn't ready for MMIO yet, later..
+ */
+-#ifdef CONFIG_X86_VISWS
++#if defined(CONFIG_X86_VISWS) || defined(CONFIG_SGI_IP27)
+ #define MEMORY_MAPPED_IO 0
+ #else
+ #define MEMORY_MAPPED_IO 1
+@@ -387,6 +391,7 @@
+ #include "qla1280.h"
+ #include "ql12160_fw.h" /* ISP RISC codes */
+ #include "ql1280_fw.h"
++#include "ql1040_fw.h"
+
+
+ /*
+@@ -485,6 +490,13 @@
+ #define ia64_platform_is(foo) (!strcmp(x, platform_name))
+ #endif
+
++#define IS_ISP1040(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1020)
++#define IS_ISP1x40(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1020 || \
++ ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1240)
++#define IS_ISP1x160(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160 || \
++ ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160)
++
++
+ static int qla1280_probe_one(struct pci_dev *, const struct pci_device_id *);
+ static void qla1280_remove_one(struct pci_dev *);
+
+@@ -501,9 +513,7 @@
+ /*
+ * QLogic ISP1280 Hardware Support Function Prototypes.
+ */
+-static int qla1280_isp_firmware(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_load_firmware(struct scsi_qla_host *);
+ static int qla1280_init_rings(struct scsi_qla_host *);
+ static int qla1280_nvram_config(struct scsi_qla_host *);
+ static int qla1280_mailbox_command(struct scsi_qla_host *,
+@@ -627,14 +637,16 @@
+ 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_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,
++ {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280,
++ {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+- {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160,
++ {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
++ {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160,
++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+ {0,}
+ };
+ MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
+@@ -643,6 +655,8 @@
+ /* Name , Number of ports, FW details */
+ {"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01,
+ &fw12160i_addr01, &fw12160i_version_str[0]},
++ {"QLA1040", 1, &risc_code01[0], &risc_code_length01,
++ &risc_code_addr01, &firmware_version[0]},
+ {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01,
+ &fw1280ei_addr01, &fw1280ei_version_str[0]},
+ {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01,
+@@ -1381,48 +1395,37 @@
+ static int
+ qla1280_set_target_parameters(struct scsi_qla_host *ha, int bus, int target)
+ {
+- uint8_t mr;
+ uint16_t mb[MAILBOX_REGISTER_COUNT];
+- struct nvram *nv;
+- int is1x160, status;
+-
+- nv = &ha->nvram;
+-
+- if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+- ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160)
+- is1x160 = 1;
+- else
+- is1x160 = 0;
+-
+- mr = BIT_3 | BIT_2 | BIT_1 | BIT_0;
++ uint8_t mr = BIT_3 | BIT_2 | BIT_1 | BIT_0;
++ struct nvram *nv = &ha->nvram;
++ int err;
+
+ /* Set Target Parameters. */
+ mb[0] = MBC_SET_TARGET_PARAMETERS;
+ mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
+ mb[1] <<= 8;
+
+- mb[2] = (nv->bus[bus].target[target].parameter.c << 8);
+-
+- if (is1x160)
+- mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
+- else
+- mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
+- mb[3] |= nv->bus[bus].target[target].sync_period;
+-
+- if (is1x160) {
+- mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
+- mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8;
+- mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
++ if (IS_ISP1x160(ha)) {
++ mb[2] = nv->bus[bus].target[target].parameter.c << 8 |
++ nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
++ mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8 |
++ nv->bus[bus].target[target].sync_period;
++ mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8 |
++ nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
+ mr |= BIT_6;
++ } else {
++ mb[2] = nv->bus[bus].target[target].parameter.c << 8;
++ mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8 |
++ nv->bus[bus].target[target].sync_period;
+ }
+
+- status = qla1280_mailbox_command(ha, mr, &mb[0]);
+-
+- if (status)
++ err = qla1280_mailbox_command(ha, mr, &mb[0]);
++ if (err) {
+ printk(KERN_WARNING "scsi(%ld:%i:%i): "
+ "qla1280_set_target_parameters() failed\n",
+ ha->host_no, bus, target);
+- return status;
++ }
++ return err;
+ }
+
+
+@@ -1476,8 +1479,7 @@
+ (driver_setup.wide_mask &&
+ (~driver_setup.wide_mask & (1 << target))))
+ nv->bus[bus].target[target].parameter.f.enable_wide = 0;
+- if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+- ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160) {
++ if (IS_ISP1x160(ha)) {
+ if (driver_setup.no_ppr ||
+ (driver_setup.ppr_mask &&
+ (~driver_setup.ppr_mask & (1 << target))))
+@@ -1777,6 +1779,20 @@
+ driver_setup.no_nvram = 1;
+ }
+ #endif
++#if defined(CONFIG_SGI_IP27)
++ /*
++ * No support for Option ROMs on Origins.
++ */
++ driver_setup.no_nvram = 1;
++#endif
++
++ /* TODO: implement support for the 1040 nvram format */
++ if (IS_ISP1040(ha))
++ driver_setup.no_nvram = 1;
++
++ /* TODO: implement support for the 1040 nvram format */
++ if (IS_ISP1040(ha))
++ driver_setup.no_nvram = 1;
+
+ dprintk(1, "Configure PCI space for adapter...\n");
+
+@@ -1802,17 +1818,8 @@
+ */
+ spin_lock_irqsave(HOST_LOCK, flags);
+ #endif
+- /* If firmware needs to be loaded */
+- if (qla1280_isp_firmware(ha)) {
+- if (!(status = qla1280_chip_diag(ha))) {
+- status = qla1280_setup_chip(ha);
+- }
+- } else {
+- printk(KERN_ERR "scsi(%li): isp_firmware() failed!\n",
+- ha->host_no);
+- status = 1;
+- }
+
++ status = qla1280_load_firmware(ha);
+ if (status) {
+ printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n",
+ ha->host_no);
+@@ -1823,36 +1830,24 @@
+ dprintk(1, "scsi(%ld): Configure NVRAM parameters\n", ha->host_no);
+ qla1280_nvram_config(ha);
+
+- if (!ha->flags.disable_host_adapter && !qla1280_init_rings(ha)) {
+- /* Issue SCSI reset. */
+- /* dg 03/13 if we can't reset twice then bus is dead */
+- for (bus = 0; bus < ha->ports; bus++) {
+- if (!ha->bus_settings[bus].disable_scsi_reset){
+- if (qla1280_bus_reset(ha, bus)) {
+- if (qla1280_bus_reset(ha, bus)) {
+- ha->bus_settings[bus].scsi_bus_dead = 1;
+- }
+- }
+- }
+- }
++ if (ha->flags.disable_host_adapter) {
++ status = 1;
++ goto out;
++ }
+
+- /*
+- * qla1280_bus_reset() will take care of issueing markers,
+- * no need to do that here as well!
+- */
+-#if 0
+- /* Issue marker command. */
+- ha->flags.reset_marker = 0;
+- for (bus = 0; bus < ha->ports; bus++) {
+- ha->bus_settings[bus].reset_marker = 0;
+- qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL);
+- }
+-#endif
++ status = qla1280_init_rings(ha);
++ if (status)
++ goto out;
+
+- ha->flags.online = 1;
+- } else
+- status = 1;
++ /* Issue SCSI reset, if we can't reset twice then bus is dead */
++ for (bus = 0; bus < ha->ports; bus++) {
++ if (!ha->bus_settings[bus].disable_scsi_reset &&
++ qla1280_bus_reset(ha, bus) &&
++ qla1280_bus_reset(ha, bus))
++ ha->bus_settings[bus].scsi_bus_dead = 1;
++ }
+
++ ha->flags.online = 1;
+ out:
+ #if LINUX_VERSION_CODE >= 0x020500
+ spin_unlock_irqrestore(HOST_LOCK, flags);
+@@ -1945,13 +1940,13 @@
+ int status = 0;
+ int cnt;
+ uint16_t data;
+-
+ dprintk(3, "qla1280_chip_diag: testing device at 0x%p \n", ®->id_l);
+
+ dprintk(1, "scsi(%ld): Verifying chip\n", ha->host_no);
+
+ /* Soft reset chip and wait for it to finish. */
+ WRT_REG_WORD(®->ictrl, ISP_RESET);
++
+ /*
+ * We can't do a traditional PCI write flush here by reading
+ * back the register. The card will not respond once the reset
+@@ -1969,145 +1964,138 @@
+ data = RD_REG_WORD(®->ictrl);
+ }
+
+- if (cnt) {
+- /* Reset register cleared by chip reset. */
+- dprintk(3, "qla1280_chip_diag: reset register cleared by "
+- "chip reset\n");
++ if (!cnt)
++ goto fail;
+
+- WRT_REG_WORD(®->cfg_1, 0);
++ /* Reset register cleared by chip reset. */
++ dprintk(3, "qla1280_chip_diag: reset register cleared by chip reset\n");
+
+- /* Reset RISC and disable BIOS which
+- allows RISC to execute out of RAM. */
+-#if 0
+- WRT_REG_WORD(®->host_cmd, HC_RESET_RISC);
+- RD_REG_WORD(®->id_l); /* Flush PCI write */
+- WRT_REG_WORD(®->host_cmd, HC_RELEASE_RISC);
+- RD_REG_WORD(®->id_l); /* Flush PCI write */
+- WRT_REG_WORD(®->host_cmd, HC_DISABLE_BIOS);
+-#else
+- WRT_REG_WORD(®->host_cmd, HC_RESET_RISC |
+- HC_RELEASE_RISC | HC_DISABLE_BIOS);
+-#endif
+- RD_REG_WORD(®->id_l); /* Flush PCI write */
+- data = qla1280_debounce_register(®->mailbox0);
+- /*
+- * I *LOVE* this code!
+- */
+- for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) {
+- udelay(5);
+- data = RD_REG_WORD(®->mailbox0);
+- }
++ WRT_REG_WORD(®->cfg_1, 0);
+
+- if (cnt) {
+- /* Check product ID of chip */
+- dprintk(3, "qla1280_chip_diag: Checking product "
+- "ID of chip\n");
+-
+- if (RD_REG_WORD(®->mailbox1) != PROD_ID_1 ||
+- (RD_REG_WORD(®->mailbox2) != PROD_ID_2 &&
+- RD_REG_WORD(®->mailbox2) != PROD_ID_2a) ||
+- RD_REG_WORD(®->mailbox3) != PROD_ID_3 ||
+- RD_REG_WORD(®->mailbox4) != PROD_ID_4) {
+- printk(KERN_INFO "qla1280: Wrong product ID = "
+- "0x%x,0x%x,0x%x,0x%x\n",
+- RD_REG_WORD(®->mailbox1),
+- RD_REG_WORD(®->mailbox2),
+- RD_REG_WORD(®->mailbox3),
+- RD_REG_WORD(®->mailbox4));
+- status = 1;
+- } else {
+- /*
+- * Enable ints early!!!
+- */
+- qla1280_enable_intrs(ha);
+-
+- dprintk(1, "qla1280_chip_diag: Checking "
+- "mailboxes of chip\n");
+- /* Wrap Incoming Mailboxes Test. */
+- mb[0] = MBC_MAILBOX_REGISTER_TEST;
+- mb[1] = 0xAAAA;
+- mb[2] = 0x5555;
+- mb[3] = 0xAA55;
+- mb[4] = 0x55AA;
+- mb[5] = 0xA5A5;
+- mb[6] = 0x5A5A;
+- mb[7] = 0x2525;
+- if (!(status = qla1280_mailbox_command(ha,
+- 0xff,
+- &mb
+- [0]))) {
+- if (mb[1] != 0xAAAA ||
+- mb[2] != 0x5555 ||
+- mb[3] != 0xAA55 ||
+- mb[4] != 0x55AA ||
+- mb[5] != 0xA5A5 ||
+- mb[6] != 0x5A5A ||
+- mb[7] != 0x2525) {
+- status = 1;
+- printk(KERN_INFO "qla1280: "
+- "Failed mbox check\n");
+- }
+- }
+- }
+- } else
+- status = 1;
+- } else
+- status = 1;
++ /* Reset RISC and disable BIOS which
++ allows RISC to execute out of RAM. */
++ WRT_REG_WORD(®->host_cmd, HC_RESET_RISC |
++ HC_RELEASE_RISC | HC_DISABLE_BIOS);
++
++ RD_REG_WORD(®->id_l); /* Flush PCI write */
++ data = qla1280_debounce_register(®->mailbox0);
++
++ /*
++ * I *LOVE* this code!
++ */
++ for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) {
++ udelay(5);
++ data = RD_REG_WORD(®->mailbox0);
++ }
++
++ if (!cnt)
++ goto fail;
++
++ /* Check product ID of chip */
++ dprintk(3, "qla1280_chip_diag: Checking product ID of chip\n");
++
++ if (RD_REG_WORD(®->mailbox1) != PROD_ID_1 ||
++ (RD_REG_WORD(®->mailbox2) != PROD_ID_2 &&
++ RD_REG_WORD(®->mailbox2) != PROD_ID_2a) ||
++ RD_REG_WORD(®->mailbox3) != PROD_ID_3 ||
++ RD_REG_WORD(®->mailbox4) != PROD_ID_4) {
++ printk(KERN_INFO "qla1280: Wrong product ID = "
++ "0x%x,0x%x,0x%x,0x%x\n",
++ RD_REG_WORD(®->mailbox1),
++ RD_REG_WORD(®->mailbox2),
++ RD_REG_WORD(®->mailbox3),
++ RD_REG_WORD(®->mailbox4));
++ goto fail;
++ }
++
++ /*
++ * Enable ints early!!!
++ */
++ qla1280_enable_intrs(ha);
+
++ dprintk(1, "qla1280_chip_diag: Checking mailboxes of chip\n");
++ /* Wrap Incoming Mailboxes Test. */
++ mb[0] = MBC_MAILBOX_REGISTER_TEST;
++ mb[1] = 0xAAAA;
++ mb[2] = 0x5555;
++ mb[3] = 0xAA55;
++ mb[4] = 0x55AA;
++ mb[5] = 0xA5A5;
++ mb[6] = 0x5A5A;
++ mb[7] = 0x2525;
++
++ status = qla1280_mailbox_command(ha, 0xff, mb);
+ if (status)
+- dprintk(2, "qla1280_chip_diag: **** FAILED ****\n");
+- else
+- dprintk(3, "qla1280_chip_diag: exiting normally\n");
++ goto fail;
++
++ if (mb[1] != 0xAAAA || mb[2] != 0x5555 || mb[3] != 0xAA55 ||
++ mb[4] != 0x55AA || mb[5] != 0xA5A5 || mb[6] != 0x5A5A ||
++ mb[7] != 0x2525) {
++ printk(KERN_INFO "qla1280: Failed mbox check\n");
++ goto fail;
++ }
+
++ dprintk(3, "qla1280_chip_diag: exiting normally\n");
++ return 0;
++ fail:
++ dprintk(2, "qla1280_chip_diag: **** FAILED ****\n");
+ return status;
+ }
+
+-/*
+- * Setup chip
+- * Load and start RISC firmware.
+- *
+- * Input:
+- * ha = adapter block pointer.
+- *
+- * Returns:
+- * 0 = success.
+- */
+-#define DUMP_IT_BACK 0 /* for debug of RISC loading */
+ static int
+-qla1280_setup_chip(struct scsi_qla_host *ha)
++qla1280_load_firmware_pio(struct scsi_qla_host *ha)
+ {
+- int status = 0;
+- uint16_t risc_address;
+- uint16_t *risc_code_address;
+- int risc_code_size;
+- uint16_t mb[MAILBOX_REGISTER_COUNT];
+- uint16_t cnt;
+- int num, i;
+-#if DUMP_IT_BACK
+- uint8_t *sp;
+- uint8_t *tbuf;
+- dma_addr_t p_tbuf;
+-#endif
++ uint16_t risc_address, *risc_code_address, risc_code_size;
++ uint16_t mb[MAILBOX_REGISTER_COUNT], i;
++ int err;
++
++ /* Load RISC code. */
++ risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
++ risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
++ risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
+
+- ENTER("qla1280_setup_chip");
++ for (i = 0; i < risc_code_size; i++) {
++ mb[0] = MBC_WRITE_RAM_WORD;
++ mb[1] = risc_address + i;
++ mb[2] = risc_code_address[i];
++
++ err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb);
++ if (err) {
++ printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
++ ha->host_no);
++ return err;
++ }
++ }
+
+- dprintk(1, "scsi(%ld): Setup chip\n", ha->host_no);
++ return 0;
++}
+
++#define DUMP_IT_BACK 0 /* for debug of RISC loading */
++static int
++qla1280_load_firmware_dma(struct scsi_qla_host *ha)
++{
++ uint16_t risc_address, *risc_code_address, risc_code_size;
++ uint16_t mb[MAILBOX_REGISTER_COUNT], cnt;
++ int err = 0, num, i;
+ #if DUMP_IT_BACK
+- /* get consistent memory allocated for setup_chip */
++ uint8_t *sp, *tbuf;
++ dma_addr_t p_tbuf;
++
+ tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf);
++ if (!tbuf)
++ return -ENOMEM;
+ #endif
+
+ /* Load RISC code. */
+ risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
+ risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
+- risc_code_size = (int) *ql1280_board_tbl[ha->devnum].fwlen;
++ risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
+
+- dprintk(1, "qla1280_setup_chip: DMA RISC code (%i) words\n",
+- risc_code_size);
++ dprintk(1, "%s: DMA RISC code (%i) words\n",
++ __FUNCTION__, risc_code_size);
+
+ num = 0;
+- while (risc_code_size > 0 && !status) {
++ while (risc_code_size > 0) {
+ int warn __attribute__((unused)) = 0;
+
+ cnt = 2000 >> 1;
+@@ -2129,15 +2117,16 @@
+ mb[2] = (ha->request_dma >> 16) & 0xffff;
+ mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff;
+ mb[6] = pci_dma_hi32(ha->request_dma) >> 16;
+- dprintk(2, "qla1280_setup_chip: op=%d 0x%p = 0x%4x,0x%4x,"
+- "0x%4x,0x%4x\n", mb[0], (void *)(long)ha->request_dma,
+- mb[6], mb[7], mb[2], mb[3]);
+- if ((status = qla1280_mailbox_command(ha, BIT_4 | BIT_3 |
+- BIT_2 | BIT_1 | BIT_0,
+- &mb[0]))) {
++ dprintk(2, "%s: op=%d 0x%p = 0x%4x,0x%4x,0x%4x,0x%4x\n",
++ __FUNCTION__, mb[0],
++ (void *)(long)ha->request_dma,
++ mb[6], mb[7], mb[2], mb[3]);
++ err = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | BIT_2 |
++ BIT_1 | BIT_0, mb);
++ if (err) {
+ printk(KERN_ERR "scsi(%li): Failed to load partial "
+ "segment of f\n", ha->host_no);
+- break;
++ goto out;
+ }
+
+ #if DUMP_IT_BACK
+@@ -2149,22 +2138,22 @@
+ mb[7] = pci_dma_hi32(p_tbuf) & 0xffff;
+ mb[6] = pci_dma_hi32(p_tbuf) >> 16;
+
+- if ((status = qla1280_mailbox_command(ha,
+- BIT_4 | BIT_3 | BIT_2 |
+- BIT_1 | BIT_0,
+- &mb[0]))) {
++ err = qla1280_mailbox_command(ha, BIT_4 | BIT_3 | BIT_2 |
++ BIT_1 | BIT_0, mb);
++ if (err) {
+ printk(KERN_ERR
+ "Failed to dump partial segment of f/w\n");
+- break;
++ goto out;
+ }
+ sp = (uint8_t *)ha->request_ring;
+ for (i = 0; i < (cnt << 1); i++) {
+ if (tbuf[i] != sp[i] && warn++ < 10) {
+- printk(KERN_ERR "qla1280_setup_chip: FW "
+- "compare error @ byte(0x%x) loop#=%x\n",
+- i, num);
+- printk(KERN_ERR "setup_chip: FWbyte=%x "
+- "FWfromChip=%x\n", sp[i], tbuf[i]);
++ printk(KERN_ERR "%s: FW compare error @ "
++ "byte(0x%x) loop#=%x\n",
++ __FUNCTION__, i, num);
++ printk(KERN_ERR "%s: FWbyte=%x "
++ "FWfromChip=%x\n",
++ __FUNCTION__, sp[i], tbuf[i]);
+ /*break; */
+ }
+ }
+@@ -2175,37 +2164,69 @@
+ num++;
+ }
+
+- /* Verify checksum of loaded RISC code. */
+- if (!status) {
+- dprintk(1, "qla1280_setup_chip: Verifying checksum of "
+- "loaded RISC code.\n");
+- mb[0] = MBC_VERIFY_CHECKSUM;
+- /* mb[1] = ql12_risc_code_addr01; */
+- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+-
+- if (!(status =
+- qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) {
+- /* Start firmware execution. */
+- dprintk(1,
+- "qla1280_setup_chip: start firmware running.\n");
+- mb[0] = MBC_EXECUTE_FIRMWARE;
+- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+- qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+- } else
+- printk(KERN_ERR "scsi(%li): qla1280_setup_chip: "
+- "Failed checksum\n", ha->host_no);
+- }
+-
++ out:
+ #if DUMP_IT_BACK
+- /* free consistent memory allocated for setup_chip */
+ pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
+ #endif
++ return err;
++}
+
+- if (status)
+- dprintk(2, "qla1280_setup_chip: **** FAILED ****\n");
++static int
++qla1280_start_firmware(struct scsi_qla_host *ha)
++{
++ uint16_t mb[MAILBOX_REGISTER_COUNT];
++ int err;
+
+- LEAVE("qla1280_setup_chip");
+- return status;
++ dprintk(1, "%s: Verifying checksum of loaded RISC code.\n",
++ __FUNCTION__);
++
++ /* Verify checksum of loaded RISC code. */
++ mb[0] = MBC_VERIFY_CHECKSUM;
++ /* mb[1] = ql12_risc_code_addr01; */
++ mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
++ err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb);
++ if (err) {
++ printk(KERN_ERR "scsi(%li): Failed checksum\n", ha->host_no);
++ return err;
++ }
++
++ /* Start firmware execution. */
++ dprintk(1, "%s: start firmware running.\n", __FUNCTION__);
++ mb[0] = MBC_EXECUTE_FIRMWARE;
++ mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
++ err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
++ if (err) {
++ printk(KERN_ERR "scsi(%li): Failed to start firmware\n",
++ ha->host_no);
++ }
++
++ return err;
++}
++
++static int
++qla1280_load_firmware(struct scsi_qla_host *ha)
++{
++ int err = -ENODEV;
++
++ /* If firmware needs to be loaded */
++ if (!qla1280_isp_firmware(ha)) {
++ printk(KERN_ERR "scsi(%li): isp_firmware() failed!\n",
++ ha->host_no);
++ goto out;
++ }
++
++ err = qla1280_chip_diag(ha);
++ if (err)
++ goto out;
++ if (IS_ISP1040(ha))
++ err = qla1280_load_firmware_pio(ha);
++ else
++ err = qla1280_load_firmware_dma(ha);
++ if (err)
++ goto out;
++ err = qla1280_start_firmware(ha);
++ out:
++ return err;
+ }
+
+ /*
+@@ -2271,123 +2292,9 @@
+ return status;
+ }
+
+-/*
+- * NVRAM configuration.
+- *
+- * Input:
+- * ha = adapter block pointer.
+- * ha->request_ring = request ring virtual address
+- *
+- * Output:
+- * host adapters parameters in host adapter block
+- *
+- * Returns:
+- * 0 = success.
+- */
+-static int
+-qla1280_nvram_config(struct scsi_qla_host *ha)
++static void
++qla1280_print_settings(struct nvram *nv)
+ {
+- struct device_reg *reg = ha->iobase;
+- struct nvram *nv;
+- int is1x160, status = 0;
+- int bus, target, lun;
+- uint16_t mb[MAILBOX_REGISTER_COUNT];
+- uint16_t mask;
+-
+- ENTER("qla1280_nvram_config");
+-
+- if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+- ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160)
+- is1x160 = 1;
+- else
+- is1x160 = 0;
+-
+- nv = &ha->nvram;
+- if (!ha->nvram_valid) {
+- dprintk(1, "Using defaults for NVRAM: \n");
+- memset(nv, 0, sizeof(struct nvram));
+-
+- /* nv->cntr_flags_1.disable_loading_risc_code = 1; */
+- nv->firmware_feature.f.enable_fast_posting = 1;
+- nv->firmware_feature.f.disable_synchronous_backoff = 1;
+-
+- nv->termination.f.scsi_bus_0_control = 3;
+- nv->termination.f.scsi_bus_1_control = 3;
+- nv->termination.f.auto_term_support = 1;
+-
+- /*
+- * Set default FIFO magic - What appropriate values
+- * would be here is unknown. This is what I have found
+- * testing with 12160s.
+- * Now, I would love the magic decoder ring for this one,
+- * the header file provided by QLogic seems to be bogus
+- * or incomplete at best.
+- */
+- nv->isp_config.c = 0x44;
+-
+- if (is1x160)
+- nv->isp_parameter = 0x01;
+-
+- for (bus = 0; bus < MAX_BUSES; bus++) {
+- nv->bus[bus].config_1.initiator_id = 7;
+- nv->bus[bus].bus_reset_delay = 5;
+- /* 8 = 5.0 clocks */
+- nv->bus[bus].config_2.async_data_setup_time = 8;
+- nv->bus[bus].config_2.req_ack_active_negation = 1;
+- nv->bus[bus].config_2.data_line_active_negation = 1;
+- nv->bus[bus].selection_timeout = 250;
+- nv->bus[bus].max_queue_depth = 256;
+-
+- for (target = 0; target < MAX_TARGETS; target++) {
+- nv->bus[bus].target[target].parameter.f.
+- renegotiate_on_error = 1;
+- nv->bus[bus].target[target].parameter.f.
+- auto_request_sense = 1;
+- nv->bus[bus].target[target].parameter.f.
+- tag_queuing = 1;
+- nv->bus[bus].target[target].parameter.f.
+- enable_sync = 1;
+-#if 1 /* Some SCSI Processors do not seem to like this */
+- nv->bus[bus].target[target].parameter.f.
+- enable_wide = 1;
+-#endif
+- nv->bus[bus].target[target].parameter.f.
+- parity_checking = 1;
+- nv->bus[bus].target[target].parameter.f.
+- disconnect_allowed = 1;
+- nv->bus[bus].target[target].execution_throttle=
+- nv->bus[bus].max_queue_depth - 1;
+- if (is1x160) {
+- nv->bus[bus].target[target].flags.
+- flags1x160.device_enable = 1;
+- nv->bus[bus].target[target].flags.
+- flags1x160.sync_offset = 0x0e;
+- nv->bus[bus].target[target].
+- sync_period = 9;
+- nv->bus[bus].target[target].
+- ppr_1x160.flags.enable_ppr = 1;
+- nv->bus[bus].target[target].ppr_1x160.
+- flags.ppr_options = 2;
+- nv->bus[bus].target[target].ppr_1x160.
+- flags.ppr_bus_width = 1;
+- } else {
+- nv->bus[bus].target[target].flags.
+- flags1x80.device_enable = 1;
+- nv->bus[bus].target[target].flags.
+- flags1x80.sync_offset = 0x8;
+- nv->bus[bus].target[target].
+- sync_period = 10;
+- }
+- }
+- }
+- } else {
+- /* Always force AUTO sense for LINUX SCSI */
+- for (bus = 0; bus < MAX_BUSES; bus++)
+- for (target = 0; target < MAX_TARGETS; target++) {
+- nv->bus[bus].target[target].parameter.f.
+- auto_request_sense = 1;
+- }
+- }
+ dprintk(1, "qla1280 : initiator scsi id bus[0]=%d\n",
+ nv->bus[0].config_1.initiator_id);
+ dprintk(1, "qla1280 : initiator scsi id bus[1]=%d\n",
+@@ -2433,36 +2340,262 @@
+ nv->bus[0].max_queue_depth);
+ dprintk(1, "qla1280 : max queue depth[1]=%d\n",
+ nv->bus[1].max_queue_depth);
++}
++
++static void
++qla1280_set_target_defaults(struct scsi_qla_host *ha, int bus, int target)
++{
++ struct nvram *nv = &ha->nvram;
++
++ nv->bus[bus].target[target].parameter.f.renegotiate_on_error = 1;
++ nv->bus[bus].target[target].parameter.f.auto_request_sense = 1;
++ nv->bus[bus].target[target].parameter.f.tag_queuing = 1;
++ nv->bus[bus].target[target].parameter.f.enable_sync = 1;
++#if 1 /* Some SCSI Processors do not seem to like this */
++ nv->bus[bus].target[target].parameter.f.enable_wide = 1;
++#endif
++ nv->bus[bus].target[target].parameter.f.parity_checking = 1;
++ nv->bus[bus].target[target].parameter.f.disconnect_allowed = 1;
++ nv->bus[bus].target[target].execution_throttle =
++ nv->bus[bus].max_queue_depth - 1;
++
++ if (IS_ISP1x160(ha)) {
++ nv->bus[bus].target[target].flags.flags1x160.device_enable = 1;
++ nv->bus[bus].target[target].flags.flags1x160.sync_offset = 0x0e;
++ nv->bus[bus].target[target].sync_period = 9;
++ nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 1;
++ nv->bus[bus].target[target].ppr_1x160.flags.ppr_options = 2;
++ nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width = 1;
++ } else {
++ nv->bus[bus].target[target].flags.flags1x80.device_enable = 1;
++ nv->bus[bus].target[target].flags.flags1x80.sync_offset = 12;
++ nv->bus[bus].target[target].sync_period = 10;
++ }
++}
++
++static void
++qla1280_set_defaults(struct scsi_qla_host *ha)
++{
++ struct nvram *nv = &ha->nvram;
++ int bus, target;
++
++ dprintk(1, "Using defaults for NVRAM: \n");
++ memset(nv, 0, sizeof(struct nvram));
++
++ /* nv->cntr_flags_1.disable_loading_risc_code = 1; */
++ nv->firmware_feature.f.enable_fast_posting = 1;
++ nv->firmware_feature.f.disable_synchronous_backoff = 1;
++ nv->termination.f.scsi_bus_0_control = 3;
++ nv->termination.f.scsi_bus_1_control = 3;
++ nv->termination.f.auto_term_support = 1;
++
++ /*
++ * Set default FIFO magic - What appropriate values would be here
++ * is unknown. This is what I have found testing with 12160s.
++ *
++ * Now, I would love the magic decoder ring for this one, the
++ * header file provided by QLogic seems to be bogus or incomplete
++ * at best.
++ */
++ nv->isp_config.c = ISP_CFG1_BENAB|ISP_CFG1_F128;
++ if (IS_ISP1x160(ha))
++ nv->isp_parameter = 0x01; /* fast memory enable */
++
++ for (bus = 0; bus < MAX_BUSES; bus++) {
++ nv->bus[bus].config_1.initiator_id = 7;
++ nv->bus[bus].config_2.req_ack_active_negation = 1;
++ nv->bus[bus].config_2.data_line_active_negation = 1;
++ nv->bus[bus].selection_timeout = 250;
++ nv->bus[bus].max_queue_depth = 256;
++
++ if (IS_ISP1040(ha)) {
++ nv->bus[bus].bus_reset_delay = 3;
++ nv->bus[bus].config_2.async_data_setup_time = 6;
++ nv->bus[bus].retry_delay = 1;
++ } else {
++ nv->bus[bus].bus_reset_delay = 5;
++ nv->bus[bus].config_2.async_data_setup_time = 8;
++ }
++
++ for (target = 0; target < MAX_TARGETS; target++)
++ qla1280_set_target_defaults(ha, bus, target);
++ }
++}
++
++static int
++qla1280_config_target(struct scsi_qla_host *ha, int bus, int target)
++{
++ struct nvram *nv = &ha->nvram;
++ uint16_t mb[MAILBOX_REGISTER_COUNT];
++ int status, lun;
++
++ /* Set Target Parameters. */
++ mb[0] = MBC_SET_TARGET_PARAMETERS;
++ mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
++ mb[1] <<= 8;
++
++ /*
++ * Do not enable wide, sync, and ppr for the initial
++ * INQUIRY run. We enable this later if we determine
++ * the target actually supports it.
++ */
++ nv->bus[bus].target[target].parameter.f.
++ auto_request_sense = 1;
++ nv->bus[bus].target[target].parameter.f.
++ stop_queue_on_check = 0;
++
++ if (IS_ISP1x160(ha))
++ nv->bus[bus].target[target].ppr_1x160.
++ flags.enable_ppr = 0;
++
++ /*
++ * No sync, wide, etc. while probing
++ */
++ mb[2] = (nv->bus[bus].target[target].parameter.c << 8) &
++ ~(TP_SYNC /*| TP_WIDE | TP_PPR*/);
++
++ if (IS_ISP1x160(ha))
++ mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
++ else
++ mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
++ mb[3] |= nv->bus[bus].target[target].sync_period;
++
++ status = qla1280_mailbox_command(ha, BIT_3 | BIT_2 | BIT_1 | BIT_0, &mb[0]);
++
++ /* Save Tag queuing enable flag. */
++ mb[0] = BIT_0 << target;
++ if (nv->bus[bus].target[target].parameter.f.tag_queuing)
++ ha->bus_settings[bus].qtag_enables |= mb[0];
++
++ /* Save Device enable flag. */
++ if (IS_ISP1x160(ha)) {
++ if (nv->bus[bus].target[target].flags.flags1x160.device_enable)
++ ha->bus_settings[bus].device_enables |= mb[0];
++ ha->bus_settings[bus].lun_disables |= 0;
++ } else {
++ if (nv->bus[bus].target[target].flags.flags1x80.device_enable)
++ ha->bus_settings[bus].device_enables |= mb[0];
++ /* Save LUN disable flag. */
++ if (nv->bus[bus].target[target].flags.flags1x80.lun_disable)
++ ha->bus_settings[bus].lun_disables |= mb[0];
++ }
++
++ /* Set Device Queue Parameters. */
++ for (lun = 0; lun < MAX_LUNS; lun++) {
++ mb[0] = MBC_SET_DEVICE_QUEUE;
++ mb[1] = (uint16_t)(bus ? target | BIT_7 : target);
++ mb[1] = mb[1] << 8 | lun;
++ mb[2] = nv->bus[bus].max_queue_depth;
++ mb[3] = nv->bus[bus].target[target].execution_throttle;
++ status |= qla1280_mailbox_command(ha, 0x0f, &mb[0]);
++ }
++
++ return status;
++}
++
++static int
++qla1280_config_bus(struct scsi_qla_host *ha, int bus)
++{
++ struct nvram *nv = &ha->nvram;
++ uint16_t mb[MAILBOX_REGISTER_COUNT];
++ int target, status;
++
++ /* SCSI Reset Disable. */
++ ha->bus_settings[bus].disable_scsi_reset =
++ nv->bus[bus].config_1.scsi_reset_disable;
++
++ /* Initiator ID. */
++ ha->bus_settings[bus].id = nv->bus[bus].config_1.initiator_id;
++ mb[0] = MBC_SET_INITIATOR_ID;
++ mb[1] = bus ? ha->bus_settings[bus].id | BIT_7 :
++ ha->bus_settings[bus].id;
++ status = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
++
++ /* Reset Delay. */
++ ha->bus_settings[bus].bus_reset_delay =
++ nv->bus[bus].bus_reset_delay;
++
++ /* Command queue depth per device. */
++ ha->bus_settings[bus].hiwat = nv->bus[bus].max_queue_depth - 1;
++
++ /* Set target parameters. */
++ for (target = 0; target < MAX_TARGETS; target++)
++ status |= qla1280_config_target(ha, bus, target);
++
++ return status;
++}
++
++static int
++qla1280_nvram_config(struct scsi_qla_host *ha)
++{
++ struct device_reg *reg = ha->iobase;
++ struct nvram *nv = &ha->nvram;
++ int bus, target, status = 0;
++ uint16_t mb[MAILBOX_REGISTER_COUNT];
++ uint16_t mask;
++
++ ENTER("qla1280_nvram_config");
++
++ if (ha->nvram_valid) {
++ /* Always force AUTO sense for LINUX SCSI */
++ for (bus = 0; bus < MAX_BUSES; bus++)
++ for (target = 0; target < MAX_TARGETS; target++) {
++ nv->bus[bus].target[target].parameter.f.
++ auto_request_sense = 1;
++ }
++ } else {
++ qla1280_set_defaults(ha);
++ }
++
++ qla1280_print_settings(nv);
+
+ /* Disable RISC load of firmware. */
+ ha->flags.disable_risc_code_load =
+ nv->cntr_flags_1.disable_loading_risc_code;
+
+- /* Set ISP hardware DMA burst */
+- mb[0] = nv->isp_config.c;
+- /* Enable DMA arbitration on dual channel controllers */
+- if (ha->ports > 1)
+- mb[0] |= BIT_13;
+- WRT_REG_WORD(®->cfg_1, mb[0]);
+-
+-#if 1 /* Is this safe? */
+- /* Set SCSI termination. */
+- WRT_REG_WORD(®->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0));
+- mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0);
+- WRT_REG_WORD(®->gpio_data, mb[0]);
+-#endif
++ if (IS_ISP1040(ha)) {
++ uint16_t hwrev, cfg1, cdma_conf, ddma_conf;
++
++ hwrev = RD_REG_WORD(®->cfg_0) & ISP_CFG0_HWMSK;
++
++ cfg1 = RD_REG_WORD(®->cfg_1);
++ cdma_conf = RD_REG_WORD(®->cdma_cfg);
++ ddma_conf = RD_REG_WORD(®->ddma_cfg);
++
++ /* Busted fifo, says mjacob. */
++ if (hwrev == ISP_CFG0_1040A)
++ WRT_REG_WORD(®->cfg_1, cfg1 | ISP_CFG1_F64);
++ else
++ WRT_REG_WORD(®->cfg_1, cfg1 | ISP_CFG1_F64 | ISP_CFG1_BENAB);
++
++ WRT_REG_WORD(®->cdma_cfg, cdma_conf | CDMA_CONF_BENAB);
++ WRT_REG_WORD(®->ddma_cfg, cdma_conf | DDMA_CONF_BENAB);
++ } else {
++ /* Set ISP hardware DMA burst */
++ mb[0] = nv->isp_config.c;
++ /* Enable DMA arbitration on dual channel controllers */
++ if (ha->ports > 1)
++ mb[0] |= BIT_13;
++ WRT_REG_WORD(®->cfg_1, mb[0]);
++
++ /* Set SCSI termination. */
++ WRT_REG_WORD(®->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0));
++ mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0);
++ WRT_REG_WORD(®->gpio_data, mb[0]);
++ }
+
+ /* ISP parameter word. */
+ mb[0] = MBC_SET_SYSTEM_PARAMETER;
+ mb[1] = nv->isp_parameter;
+ status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+
+-#if 0
+- /* clock rate - for qla1240 and older, only */
+- mb[0] = MBC_SET_CLOCK_RATE;
+- mb[1] = 0x50;
+- status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+-#endif
++ if (IS_ISP1x40(ha)) {
++ /* clock rate - for qla1240 and older, only */
++ mb[0] = MBC_SET_CLOCK_RATE;
++ mb[1] = 40;
++ status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb);
++ }
++
+ /* Firmware feature word. */
+ mb[0] = MBC_SET_FIRMWARE_FEATURES;
+ mask = BIT_5 | BIT_1 | BIT_0;
+@@ -2515,112 +2648,18 @@
+ mb[2] = 2; /* Command DMA Channel Burst Enable */
+ status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
+
++ mb[0] = MBC_SET_TAG_AGE_LIMIT;
++ mb[1] = 8;
++ status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
++
+ /* Selection timeout. */
+ mb[0] = MBC_SET_SELECTION_TIMEOUT;
+ mb[1] = nv->bus[0].selection_timeout;
+ mb[2] = nv->bus[1].selection_timeout;
+ status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
+
+- for (bus = 0; bus < ha->ports; bus++) {
+- /* SCSI Reset Disable. */
+- ha->bus_settings[bus].disable_scsi_reset =
+- nv->bus[bus].config_1.scsi_reset_disable;
+-
+- /* Initiator ID. */
+- ha->bus_settings[bus].id = nv->bus[bus].config_1.initiator_id;
+- mb[0] = MBC_SET_INITIATOR_ID;
+- mb[1] = bus ? ha->bus_settings[bus].id | BIT_7 :
+- ha->bus_settings[bus].id;
+- status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+-
+- /* Reset Delay. */
+- ha->bus_settings[bus].bus_reset_delay =
+- nv->bus[bus].bus_reset_delay;
+-
+- /* Command queue depth per device. */
+- ha->bus_settings[bus].hiwat = nv->bus[bus].max_queue_depth - 1;
+-
+- /* Set target parameters. */
+- for (target = 0; target < MAX_TARGETS; target++) {
+- uint8_t mr = BIT_2 | BIT_1 | BIT_0;
+-
+- /* Set Target Parameters. */
+- mb[0] = MBC_SET_TARGET_PARAMETERS;
+- mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
+- mb[1] <<= 8;
+- /*
+- * Do not enable wide, sync, and ppr for the initial
+- * INQUIRY run. We enable this later if we determine
+- * the target actually supports it.
+- */
+- nv->bus[bus].target[target].parameter.f.
+- auto_request_sense = 1;
+- nv->bus[bus].target[target].parameter.f.
+- stop_queue_on_check = 0;
+-
+- if (is1x160)
+- nv->bus[bus].target[target].ppr_1x160.
+- flags.enable_ppr = 0;
+- /*
+- * No sync, wide, etc. while probing
+- */
+- mb[2] = (nv->bus[bus].target[target].parameter.c << 8)&
+- ~(TP_SYNC /*| TP_WIDE | TP_PPR*/);
+-
+- if (is1x160)
+- mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
+- else
+- mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
+- mb[3] |= nv->bus[bus].target[target].sync_period;
+- mr |= BIT_3;
+-
+- /*
+- * We don't want to enable ppr etc. before we have
+- * determined that the target actually supports it
+- */
+-#if 0
+- if (is1x160) {
+- mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
+-
+- mb[6] = nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8;
+- mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
+- mr |= BIT_6;
+- }
+-#endif
+-
+- status = qla1280_mailbox_command(ha, mr, &mb[0]);
+-
+- /* Save Tag queuing enable flag. */
+- mb[0] = BIT_0 << target;
+- if (nv->bus[bus].target[target].parameter.f.tag_queuing)
+- ha->bus_settings[bus].qtag_enables |= mb[0];
+-
+- /* Save Device enable flag. */
+- if (is1x160) {
+- if (nv->bus[bus].target[target].flags.flags1x160.device_enable)
+- ha->bus_settings[bus].device_enables |= mb[0];
+- ha->bus_settings[bus].lun_disables |= 0;
+- } else {
+- if (nv->bus[bus].target[target].flags.flags1x80.device_enable)
+- ha->bus_settings[bus].device_enables |= mb[0];
+- /* Save LUN disable flag. */
+- if (nv->bus[bus].target[target].flags.flags1x80.lun_disable)
+- ha->bus_settings[bus].lun_disables |= mb[0];
+- }
+-
+-
+- /* Set Device Queue Parameters. */
+- for (lun = 0; lun < MAX_LUNS; lun++) {
+- mb[0] = MBC_SET_DEVICE_QUEUE;
+- mb[1] = (uint16_t)(bus ? target | BIT_7 : target);
+- mb[1] = mb[1] << 8 | lun;
+- mb[2] = nv->bus[bus].max_queue_depth;
+- mb[3] = nv->bus[bus].target[target].execution_throttle;
+- status |= qla1280_mailbox_command(ha, 0x0f,
+- &mb[0]);
+- }
+- }
+- }
++ for (bus = 0; bus < ha->ports; bus++)
++ status |= qla1280_config_bus(ha, bus);
+
+ if (status)
+ dprintk(2, "qla1280_nvram_config: **** FAILED ****\n");
+@@ -4231,6 +4270,7 @@
+ static int
+ qla1280_abort_isp(struct scsi_qla_host *ha)
+ {
++ struct device_reg *reg = ha->iobase;
+ struct srb *sp;
+ int status = 0;
+ int cnt;
+@@ -4238,69 +4278,53 @@
+
+ ENTER("qla1280_abort_isp");
+
+- if (!ha->flags.abort_isp_active && ha->flags.online) {
+- struct device_reg *reg = ha->iobase;
+- ha->flags.abort_isp_active = 1;
++ if (ha->flags.abort_isp_active || !ha->flags.online)
++ goto out;
++
++ ha->flags.abort_isp_active = 1;
+
+- /* Disable ISP interrupts. */
+- qla1280_disable_intrs(ha);
+- WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC);
+- RD_REG_WORD(®->id_l);
++ /* Disable ISP interrupts. */
++ qla1280_disable_intrs(ha);
++ WRT_REG_WORD(®->host_cmd, HC_PAUSE_RISC);
++ RD_REG_WORD(®->id_l);
+
+- printk(KERN_INFO "scsi(%li): dequeuing outstanding commands\n",
+- ha->host_no);
+- /* Dequeue all commands in outstanding command list. */
+- for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
+- struct scsi_cmnd *cmd;
+- sp = ha->outstanding_cmds[cnt];
+- if (sp) {
++ printk(KERN_INFO "scsi(%li): dequeuing outstanding commands\n",
++ ha->host_no);
++ /* Dequeue all commands in outstanding command list. */
++ for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
++ struct scsi_cmnd *cmd;
++ sp = ha->outstanding_cmds[cnt];
++ if (sp) {
+
+- cmd = sp->cmd;
+- CMD_RESULT(cmd) = DID_RESET << 16;
++ cmd = sp->cmd;
++ CMD_RESULT(cmd) = DID_RESET << 16;
+
+- sp->cmd = NULL;
+- ha->outstanding_cmds[cnt] = NULL;
++ sp->cmd = NULL;
++ ha->outstanding_cmds[cnt] = NULL;
+
+- (*cmd->scsi_done)(cmd);
++ (*cmd->scsi_done)(cmd);
+
+- sp->flags = 0;
+- }
++ sp->flags = 0;
+ }
++ }
+
+- /* If firmware needs to be loaded */
+- if (qla1280_isp_firmware (ha)) {
+- if (!(status = qla1280_chip_diag(ha)))
+- status = qla1280_setup_chip(ha);
+- }
++ status = qla1280_load_firmware(ha);
++ if (status)
++ goto out;
+
+- if (!status) {
+- /* Setup adapter based on NVRAM parameters. */
+- qla1280_nvram_config (ha);
+-
+- if (!(status = qla1280_init_rings(ha))) {
+- /* Issue SCSI reset. */
+- for (bus = 0; bus < ha->ports; bus++) {
+- qla1280_bus_reset(ha, bus);
+- }
+- /*
+- * qla1280_bus_reset() will do the marker
+- * dance - no reason to repeat here!
+- */
+-#if 0
+- /* Issue marker command. */
+- ha->flags.reset_marker = 0;
+- for (bus = 0; bus < ha->ports; bus++) {
+- ha->bus_settings[bus].
+- reset_marker = 0;
+- qla1280_marker(ha, bus, 0, 0,
+- MK_SYNC_ALL);
+- }
+-#endif
+- ha->flags.abort_isp_active = 0;
+- }
+- }
+- }
++ /* Setup adapter based on NVRAM parameters. */
++ qla1280_nvram_config (ha);
+
++ status = qla1280_init_rings(ha);
++ if (status)
++ goto out;
++
++ /* Issue SCSI reset. */
++ for (bus = 0; bus < ha->ports; bus++)
++ qla1280_bus_reset(ha, bus);
++
++ ha->flags.abort_isp_active = 0;
++ out:
+ if (status) {
+ printk(KERN_WARNING
+ "qla1280: ISP error recovery failed, board disabled");
+diff -Nur kernel-source-2.6.8-2.6.8.orig/drivers/scsi/qla1280.h kernel-source-2.6.8-2.6.8/drivers/scsi/qla1280.h
+--- kernel-source-2.6.8-2.6.8.orig/drivers/scsi/qla1280.h 2004-08-14 05:38:09.000000000 +0000
++++ kernel-source-2.6.8-2.6.8/drivers/scsi/qla1280.h 2005-01-08 14:39:38.000000000 +0000
+@@ -126,7 +126,20 @@
+ uint16_t id_l; /* ID low */
+ uint16_t id_h; /* ID high */
+ uint16_t cfg_0; /* Configuration 0 */
++#define ISP_CFG0_HWMSK 0x000f /* Hardware revision mask */
++#define ISP_CFG0_1020 BIT_0 /* ISP1020 */
++#define ISP_CFG0_1020A BIT_1 /* ISP1020A */
++#define ISP_CFG0_1040 BIT_2 /* ISP1040 */
++#define ISP_CFG0_1040A BIT_3 /* ISP1040A */
++#define ISP_CFG0_1040B BIT_4 /* ISP1040B */
++#define ISP_CFG0_1040C BIT_5 /* ISP1040C */
+ uint16_t cfg_1; /* Configuration 1 */
++#define ISP_CFG1_F128 BIT_6 /* 128-byte FIFO threshold */
++#define ISP_CFG1_F64 BIT_4|BIT_5 /* 128-byte FIFO threshold */
++#define ISP_CFG1_F32 BIT_5 /* 128-byte FIFO threshold */
++#define ISP_CFG1_F16 BIT_4 /* 128-byte FIFO threshold */
++#define ISP_CFG1_BENAB BIT_2 /* Global Bus burst enable */
++#define ISP_CFG1_SXP BIT_0 /* SXP register select */
+ uint16_t ictrl; /* Interface control */
+ #define ISP_RESET BIT_0 /* ISP soft reset */
+ #define ISP_EN_INT BIT_1 /* ISP enable interrupts. */
+@@ -147,7 +160,42 @@
+ uint16_t flash_data; /* Flash BIOS data */
+ uint16_t flash_address; /* Flash BIOS address */
+
+- uint16_t unused_1[0x2e]; /* 0x14-0x6f Gap */
++ uint16_t unused_1[0x06];
++
++ /* cdma_* and ddma_* are 1040 only */
++ uint16_t cdma_cfg;
++#define CDMA_CONF_SENAB BIT_3 /* SXP to DMA Data enable */
++#define CDMA_CONF_RIRQ BIT_2 /* RISC interrupt enable */
++#define CDMA_CONF_BENAB BIT_1 /* Bus burst enable */
++#define CDMA_CONF_DIR BIT_0 /* DMA direction (0=fifo->host 1=host->fifo) */
++ uint16_t cdma_ctrl;
++ uint16_t cdma_status;
++ uint16_t cdma_fifo_status;
++ uint16_t cdma_count;
++ uint16_t cdma_reserved;
++ uint16_t cdma_address_count_0;
++ uint16_t cdma_address_count_1;
++ uint16_t cdma_address_count_2;
++ uint16_t cdma_address_count_3;
++
++ uint16_t unused_2[0x06];
++
++ uint16_t ddma_cfg;
++#define DDMA_CONF_SENAB BIT_3 /* SXP to DMA Data enable */
++#define DDMA_CONF_RIRQ BIT_2 /* RISC interrupt enable */
++#define DDMA_CONF_BENAB BIT_1 /* Bus burst enable */
++#define DDMA_CONF_DIR BIT_0 /* DMA direction (0=fifo->host 1=host->fifo) */
++ uint16_t ddma_ctrl;
++ uint16_t ddma_status;
++ uint16_t ddma_fifo_status;
++ uint16_t ddma_xfer_count_low;
++ uint16_t ddma_xfer_count_high;
++ uint16_t ddma_addr_count_0;
++ uint16_t ddma_addr_count_1;
++ uint16_t ddma_addr_count_2;
++ uint16_t ddma_addr_count_3;
++
++ uint16_t unused_3[0x0e];
+
+ uint16_t mailbox0; /* Mailbox 0 */
+ uint16_t mailbox1; /* Mailbox 1 */
+@@ -158,18 +206,18 @@
+ uint16_t mailbox6; /* Mailbox 6 */
+ uint16_t mailbox7; /* Mailbox 7 */
+
+- uint16_t unused_2[0x20];/* 0x80-0xbf Gap */
++ uint16_t unused_4[0x20];/* 0x80-0xbf Gap */
+
+ uint16_t host_cmd; /* Host command and control */
+ #define HOST_INT BIT_7 /* host interrupt bit */
+ #define BIOS_ENABLE BIT_0
+
+- uint16_t unused_6[0x5]; /* 0xc2-0xcb Gap */
++ uint16_t unused_5[0x5]; /* 0xc2-0xcb Gap */
+
+ uint16_t gpio_data;
+ uint16_t gpio_enable;
+
+- uint16_t unused_7[0x11]; /* d0-f0 */
++ uint16_t unused_6[0x11]; /* d0-f0 */
+ uint16_t scsiControlPins; /* f2 */
+ };
+