+++ /dev/null
-From: Andrew Vasquez
-Subject: Update qla2xxx to 8.02.01-k8
-References: FATE#304113
-
-This patch updates the qla2xxx driver to version 8.02.01-k8.
-
-Signed-off-by: Hannes Reinecke <hare@suse.de>
-
----
- drivers/scsi/qla2xxx/qla_attr.c | 9
- drivers/scsi/qla2xxx/qla_def.h | 12 +
- drivers/scsi/qla2xxx/qla_fw.h | 71 +++++++
- drivers/scsi/qla2xxx/qla_gbl.h | 4
- drivers/scsi/qla2xxx/qla_init.c | 14 +
- drivers/scsi/qla2xxx/qla_inline.h | 2
- drivers/scsi/qla2xxx/qla_iocb.c | 30 ++-
- drivers/scsi/qla2xxx/qla_isr.c | 17 +
- drivers/scsi/qla2xxx/qla_mbx.c | 6
- drivers/scsi/qla2xxx/qla_os.c | 9
- drivers/scsi/qla2xxx/qla_sup.c | 336 +++++++++++++++++++++++++++++++++----
- drivers/scsi/qla2xxx/qla_version.h | 2
- 12 files changed, 444 insertions(+), 68 deletions(-)
-
---- a/drivers/scsi/qla2xxx/qla_attr.c
-+++ b/drivers/scsi/qla2xxx/qla_attr.c
-@@ -292,10 +292,11 @@ qla2x00_sysfs_write_optrom_ctl(struct ko
- valid = 0;
- if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
- valid = 1;
-- else if (start == (FA_BOOT_CODE_ADDR*4) ||
-- start == (FA_RISC_CODE_ADDR*4))
-+ else if (start == (ha->flt_region_boot * 4) ||
-+ start == (ha->flt_region_fw * 4))
- valid = 1;
-- else if (IS_QLA25XX(ha) && start == (FA_VPD_NVRAM_ADDR*4))
-+ else if (IS_QLA25XX(ha) &&
-+ start == (ha->flt_region_vpd_nvram * 4))
- valid = 1;
- if (!valid) {
- qla_printk(KERN_WARNING, ha,
-@@ -1064,6 +1065,8 @@ qla2x00_get_fc_host_stats(struct Scsi_Ho
- pfc_host_stat->dumped_frames = stats->dumped_frames;
- pfc_host_stat->nos_count = stats->nos_rcvd;
- }
-+ pfc_host_stat->fcp_input_megabytes = ha->qla_stats.input_bytes >> 20;
-+ pfc_host_stat->fcp_output_megabytes = ha->qla_stats.output_bytes >> 20;
-
- done_free:
- dma_pool_free(ha->s_dma_pool, stats, stats_dma);
---- a/drivers/scsi/qla2xxx/qla_def.h
-+++ b/drivers/scsi/qla2xxx/qla_def.h
-@@ -2157,6 +2157,8 @@ struct qla_chip_state_84xx {
-
- struct qla_statistics {
- uint32_t total_isp_aborts;
-+ uint64_t input_bytes;
-+ uint64_t output_bytes;
- };
-
- /*
-@@ -2238,6 +2240,7 @@ typedef struct scsi_qla_host {
- #define FCPORT_UPDATE_NEEDED 27
- #define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
- #define UNLOADING 29
-+#define NPIV_CONFIG_NEEDED 30
-
- uint32_t device_flags;
- #define DFLG_LOCAL_DEVICES BIT_0
-@@ -2507,7 +2510,6 @@ typedef struct scsi_qla_host {
- uint64_t fce_wr, fce_rd;
- struct mutex fce_mutex;
-
-- uint32_t hw_event_start;
- uint32_t hw_event_ptr;
- uint32_t hw_event_pause_errors;
-
-@@ -2553,6 +2555,14 @@ typedef struct scsi_qla_host {
- uint32_t fdt_unprotect_sec_cmd;
- uint32_t fdt_protect_sec_cmd;
-
-+ uint32_t flt_region_flt;
-+ uint32_t flt_region_fdt;
-+ uint32_t flt_region_boot;
-+ uint32_t flt_region_fw;
-+ uint32_t flt_region_vpd_nvram;
-+ uint32_t flt_region_hw_event;
-+ uint32_t flt_region_npiv_conf;
-+
- /* Needed for BEACON */
- uint16_t beacon_blink_led;
- uint8_t beacon_color_state;
---- a/drivers/scsi/qla2xxx/qla_fw.h
-+++ b/drivers/scsi/qla2xxx/qla_fw.h
-@@ -789,14 +789,23 @@ struct device_reg_24xx {
- #define FA_RISC_CODE_ADDR 0x20000
- #define FA_RISC_CODE_SEGMENTS 2
-
-+#define FA_FLASH_DESCR_ADDR_24 0x11000
-+#define FA_FLASH_LAYOUT_ADDR_24 0x11400
-+#define FA_NPIV_CONF0_ADDR_24 0x16000
-+#define FA_NPIV_CONF1_ADDR_24 0x17000
-+
- #define FA_FW_AREA_ADDR 0x40000
- #define FA_VPD_NVRAM_ADDR 0x48000
- #define FA_FEATURE_ADDR 0x4C000
- #define FA_FLASH_DESCR_ADDR 0x50000
-+#define FA_FLASH_LAYOUT_ADDR 0x50400
- #define FA_HW_EVENT0_ADDR 0x54000
--#define FA_HW_EVENT1_ADDR 0x54200
-+#define FA_HW_EVENT1_ADDR 0x54400
- #define FA_HW_EVENT_SIZE 0x200
- #define FA_HW_EVENT_ENTRY_SIZE 4
-+#define FA_NPIV_CONF0_ADDR 0x5C000
-+#define FA_NPIV_CONF1_ADDR 0x5D000
-+
- /*
- * Flash Error Log Event Codes.
- */
-@@ -806,10 +815,6 @@ struct device_reg_24xx {
- #define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023
- #define HW_EVENT_FLASH_FW_ERR 0xF024
-
--#define FA_BOOT_LOG_ADDR 0x58000
--#define FA_FW_DUMP0_ADDR 0x60000
--#define FA_FW_DUMP1_ADDR 0x70000
--
- uint32_t flash_data; /* Flash/NVRAM BIOS data. */
-
- uint32_t ctrl_status; /* Control/Status. */
-@@ -1203,6 +1208,62 @@ struct qla_fdt_layout {
- uint8_t unused2[65];
- };
-
-+/* Flash Layout Table ********************************************************/
-+
-+struct qla_flt_location {
-+ uint8_t sig[4];
-+ uint32_t start_lo;
-+ uint32_t start_hi;
-+ uint16_t unused;
-+ uint16_t checksum;
-+};
-+
-+struct qla_flt_header {
-+ uint16_t version;
-+ uint16_t length;
-+ uint16_t checksum;
-+ uint16_t unused;
-+};
-+
-+#define FLT_REG_FW 0x01
-+#define FLT_REG_BOOT_CODE 0x07
-+#define FLT_REG_VPD_0 0x14
-+#define FLT_REG_NVRAM_0 0x15
-+#define FLT_REG_VPD_1 0x16
-+#define FLT_REG_NVRAM_1 0x17
-+#define FLT_REG_FDT 0x1a
-+#define FLT_REG_FLT 0x1c
-+#define FLT_REG_HW_EVENT_0 0x1d
-+#define FLT_REG_HW_EVENT_1 0x1f
-+#define FLT_REG_NPIV_CONF_0 0x29
-+#define FLT_REG_NPIV_CONF_1 0x2a
-+
-+struct qla_flt_region {
-+ uint32_t code;
-+ uint32_t size;
-+ uint32_t start;
-+ uint32_t end;
-+};
-+
-+/* Flash NPIV Configuration Table ********************************************/
-+
-+struct qla_npiv_header {
-+ uint8_t sig[2];
-+ uint16_t version;
-+ uint16_t entries;
-+ uint16_t unused[4];
-+ uint16_t checksum;
-+};
-+
-+struct qla_npiv_entry {
-+ uint16_t flags;
-+ uint16_t vf_id;
-+ uint16_t qos;
-+ uint16_t unused1;
-+ uint8_t port_name[WWN_SIZE];
-+ uint8_t node_name[WWN_SIZE];
-+};
-+
- /* 84XX Support **************************************************************/
-
- #define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */
---- a/drivers/scsi/qla2xxx/qla_gbl.h
-+++ b/drivers/scsi/qla2xxx/qla_gbl.h
-@@ -313,9 +313,11 @@ extern int qla24xx_get_flash_version(scs
- extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
- uint16_t, uint16_t);
-
--extern void qla2xxx_get_flash_info(scsi_qla_host_t *);
-+extern int qla2xxx_get_flash_info(scsi_qla_host_t *);
- extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
-
-+extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *);
-+
- /*
- * Global Function Prototypes in qla_dbg.c source file.
- */
---- a/drivers/scsi/qla2xxx/qla_init.c
-+++ b/drivers/scsi/qla2xxx/qla_init.c
-@@ -83,6 +83,13 @@ qla2x00_initialize_adapter(scsi_qla_host
-
- ha->isp_ops->reset_chip(ha);
-
-+ rval = qla2xxx_get_flash_info(ha);
-+ if (rval) {
-+ DEBUG2(printk("scsi(%ld): Unable to validate FLASH data.\n",
-+ ha->host_no));
-+ return (rval);
-+ }
-+
- ha->isp_ops->get_flash_version(ha, ha->request_ring);
-
- qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
-@@ -109,7 +116,6 @@ qla2x00_initialize_adapter(scsi_qla_host
- rval = qla2x00_setup_chip(ha);
- if (rval)
- return (rval);
-- qla2xxx_get_flash_info(ha);
- }
- if (IS_QLA84XX(ha)) {
- ha->cs84xx = qla84xx_get_chip(ha);
-@@ -2016,7 +2022,7 @@ qla2x00_configure_loop(scsi_qla_host_t *
- DEBUG3(printk("%s: exiting normally\n", __func__));
- }
-
-- /* Restore state if a resync event occured during processing */
-+ /* Restore state if a resync event occurred during processing */
- if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
- if (test_bit(LOCAL_LOOP_UPDATE, &save_flags))
- set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
-@@ -2561,7 +2567,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho
- rval = QLA_SUCCESS;
-
- /* Try GID_PT to get device list, else GAN. */
-- swl = kcalloc(MAX_FIBRE_DEVICES, sizeof(sw_info_t), GFP_ATOMIC);
-+ swl = kcalloc(MAX_FIBRE_DEVICES, sizeof(sw_info_t), GFP_KERNEL);
- if (!swl) {
- /*EMPTY*/
- DEBUG2(printk("scsi(%ld): GID_PT allocations failed, fallback "
-@@ -3751,7 +3757,7 @@ qla24xx_load_risc_flash(scsi_qla_host_t
- rval = QLA_SUCCESS;
-
- segments = FA_RISC_CODE_SEGMENTS;
-- faddr = FA_RISC_CODE_ADDR;
-+ faddr = ha->flt_region_fw;
- dcode = (uint32_t *)ha->request_ring;
- *srisc_addr = 0;
-
---- a/drivers/scsi/qla2xxx/qla_inline.h
-+++ b/drivers/scsi/qla2xxx/qla_inline.h
-@@ -52,7 +52,7 @@ to_qla_parent(scsi_qla_host_t *ha)
- * @ha: HA context
- * @ha_locked: is function called with the hardware lock
- *
-- * Returns non-zero if a failure occured, else zero.
-+ * Returns non-zero if a failure occurred, else zero.
- */
- static inline int
- qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked)
---- a/drivers/scsi/qla2xxx/qla_iocb.c
-+++ b/drivers/scsi/qla2xxx/qla_iocb.c
-@@ -21,17 +21,22 @@ static void qla2x00_isp_cmd(scsi_qla_hos
- * Returns the proper CF_* direction based on CDB.
- */
- static inline uint16_t
--qla2x00_get_cmd_direction(struct scsi_cmnd *cmd)
-+qla2x00_get_cmd_direction(srb_t *sp)
- {
- uint16_t cflags;
-
- cflags = 0;
-
- /* Set transfer direction */
-- if (cmd->sc_data_direction == DMA_TO_DEVICE)
-+ if (sp->cmd->sc_data_direction == DMA_TO_DEVICE) {
- cflags = CF_WRITE;
-- else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
-+ sp->fcport->ha->qla_stats.output_bytes +=
-+ scsi_bufflen(sp->cmd);
-+ } else if (sp->cmd->sc_data_direction == DMA_FROM_DEVICE) {
- cflags = CF_READ;
-+ sp->fcport->ha->qla_stats.input_bytes +=
-+ scsi_bufflen(sp->cmd);
-+ }
- return (cflags);
- }
-
-@@ -169,7 +174,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *
-
- ha = sp->ha;
-
-- cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(cmd));
-+ cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
-
- /* Three DSDs are available in the Command Type 2 IOCB */
- avail_dsds = 3;
-@@ -228,7 +233,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *
-
- ha = sp->ha;
-
-- cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(cmd));
-+ cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(sp));
-
- /* Two DSDs are available in the Command Type 3 IOCB */
- avail_dsds = 2;
-@@ -262,7 +267,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *
- * qla2x00_start_scsi() - Send a SCSI command to the ISP
- * @sp: command to send to the ISP
- *
-- * Returns non-zero if a failure occured, else zero.
-+ * Returns non-zero if a failure occurred, else zero.
- */
- int
- qla2x00_start_scsi(srb_t *sp)
-@@ -407,7 +412,7 @@ queuing_error:
- *
- * Can be called from both normal and interrupt context.
- *
-- * Returns non-zero if a failure occured, else zero.
-+ * Returns non-zero if a failure occurred, else zero.
- */
- int
- __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
-@@ -625,12 +630,17 @@ qla24xx_build_scsi_iocbs(srb_t *sp, stru
- ha = sp->ha;
-
- /* Set transfer direction */
-- if (cmd->sc_data_direction == DMA_TO_DEVICE)
-+ if (cmd->sc_data_direction == DMA_TO_DEVICE) {
- cmd_pkt->task_mgmt_flags =
- __constant_cpu_to_le16(TMF_WRITE_DATA);
-- else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
-+ sp->fcport->ha->qla_stats.output_bytes +=
-+ scsi_bufflen(sp->cmd);
-+ } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
- cmd_pkt->task_mgmt_flags =
- __constant_cpu_to_le16(TMF_READ_DATA);
-+ sp->fcport->ha->qla_stats.input_bytes +=
-+ scsi_bufflen(sp->cmd);
-+ }
-
- /* One DSD is available in the Command Type 3 IOCB */
- avail_dsds = 1;
-@@ -666,7 +676,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, stru
- * qla24xx_start_scsi() - Send a SCSI command to the ISP
- * @sp: command to send to the ISP
- *
-- * Returns non-zero if a failure occured, else zero.
-+ * Returns non-zero if a failure occurred, else zero.
- */
- int
- qla24xx_start_scsi(srb_t *sp)
---- a/drivers/scsi/qla2xxx/qla_isr.c
-+++ b/drivers/scsi/qla2xxx/qla_isr.c
-@@ -391,9 +391,9 @@ qla2x00_async_event(scsi_qla_host_t *ha,
- break;
-
- case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
-- DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no,
-+ DEBUG2(printk("scsi(%ld): LIP occurred (%x).\n", ha->host_no,
- mb[1]));
-- qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]);
-+ qla_printk(KERN_INFO, ha, "LIP occurred (%x).\n", mb[1]);
-
- if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
- atomic_set(&ha->loop_state, LOOP_DOWN);
-@@ -460,7 +460,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
- DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
- ha->host_no, mb[1]));
- qla_printk(KERN_INFO, ha,
-- "LIP reset occured (%x).\n", mb[1]);
-+ "LIP reset occurred (%x).\n", mb[1]);
-
- if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
- atomic_set(&ha->loop_state, LOOP_DOWN);
-@@ -543,7 +543,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
-
- case MBA_PORT_UPDATE: /* Port database update */
- /*
-- * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
-+ * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET
- * event etc. earlier indicating loop is down) then process
- * it. Otherwise ignore it and Wait for RSCN to come in.
- */
-@@ -589,7 +589,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
- "scsi(%ld): RSCN database changed -- %04x %04x %04x.\n",
- ha->host_no, mb[1], mb[2], mb[3]));
-
-- rscn_entry = (mb[1] << 16) | mb[2];
-+ rscn_entry = ((mb[1] & 0xff) << 16) | mb[2];
- host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) |
- ha->d_id.b.al_pa;
- if (rscn_entry == host_pid) {
-@@ -600,6 +600,8 @@ qla2x00_async_event(scsi_qla_host_t *ha,
- break;
- }
-
-+ /* Ignore reserved bits from RSCN-payload. */
-+ rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2];
- rscn_queue_index = ha->rscn_in_ptr + 1;
- if (rscn_queue_index == MAX_RSCN_COUNT)
- rscn_queue_index = 0;
-@@ -1060,8 +1062,9 @@ qla2x00_status_entry(scsi_qla_host_t *ha
- resid = resid_len;
- /* Use F/W calculated residual length. */
- if (IS_FWI2_CAPABLE(ha)) {
-- if (scsi_status & SS_RESIDUAL_UNDER &&
-- resid != fw_resid_len) {
-+ if (!(scsi_status & SS_RESIDUAL_UNDER)) {
-+ lscsi_status = 0;
-+ } else if (resid != fw_resid_len) {
- scsi_status &= ~SS_RESIDUAL_UNDER;
- lscsi_status = 0;
- }
---- a/drivers/scsi/qla2xxx/qla_mbx.c
-+++ b/drivers/scsi/qla2xxx/qla_mbx.c
-@@ -233,7 +233,7 @@ qla2x00_mailbox_command(scsi_qla_host_t
- DEBUG2_3_11(printk("%s(%ld): timeout schedule "
- "isp_abort_needed.\n", __func__, ha->host_no));
- qla_printk(KERN_WARNING, ha,
-- "Mailbox command timeout occured. Scheduling ISP "
-+ "Mailbox command timeout occurred. Scheduling ISP "
- "abort.\n");
- set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
- qla2xxx_wake_dpc(ha);
-@@ -244,7 +244,7 @@ qla2x00_mailbox_command(scsi_qla_host_t
- DEBUG2_3_11(printk("%s(%ld): timeout calling "
- "abort_isp\n", __func__, ha->host_no));
- qla_printk(KERN_WARNING, ha,
-- "Mailbox command timeout occured. Issuing ISP "
-+ "Mailbox command timeout occurred. Issuing ISP "
- "abort.\n");
-
- set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
-@@ -1995,7 +1995,7 @@ qla2x00_get_fcal_position_map(scsi_qla_h
- char *pmap;
- dma_addr_t pmap_dma;
-
-- pmap = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pmap_dma);
-+ pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
- if (pmap == NULL) {
- DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****",
- __func__, ha->host_no));
---- a/drivers/scsi/qla2xxx/qla_os.c
-+++ b/drivers/scsi/qla2xxx/qla_os.c
-@@ -1515,6 +1515,7 @@ qla2xxx_scan_start(struct Scsi_Host *sho
- set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
- set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
- set_bit(RSCN_UPDATE, &ha->dpc_flags);
-+ set_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags);
- }
-
- static int
-@@ -1661,8 +1662,6 @@ qla2x00_probe_one(struct pci_dev *pdev,
- ha->gid_list_info_size = 8;
- ha->optrom_size = OPTROM_SIZE_25XX;
- ha->isp_ops = &qla25xx_isp_ops;
-- ha->hw_event_start = PCI_FUNC(pdev->devfn) ?
-- FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR;
- }
- host->can_queue = ha->request_q_length + 128;
-
-@@ -2431,6 +2430,12 @@ qla2x00_do_dpc(void *data)
- ha->host_no));
- }
-
-+ if (test_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags) &&
-+ atomic_read(&ha->loop_state) == LOOP_READY) {
-+ clear_bit(NPIV_CONFIG_NEEDED, &ha->dpc_flags);
-+ qla2xxx_flash_npiv_conf(ha);
-+ }
-+
- if (!ha->interrupts_on)
- ha->isp_ops->enable_intrs(ha);
-
---- a/drivers/scsi/qla2xxx/qla_sup.c
-+++ b/drivers/scsi/qla2xxx/qla_sup.c
-@@ -543,23 +543,198 @@ qla24xx_get_flash_manufacturer(scsi_qla_
- }
- }
-
--void
--qla2xxx_get_flash_info(scsi_qla_host_t *ha)
-+static int
-+qla2xxx_find_flt_start(scsi_qla_host_t *ha, uint32_t *start)
-+{
-+ const char *loc, *locations[] = { "DEF", "PCI" };
-+ uint32_t pcihdr, pcids;
-+ uint32_t *dcode;
-+ uint8_t *buf, *bcode, last_image;
-+ uint16_t cnt, chksum, *wptr;
-+ struct qla_flt_location *fltl;
-+
-+ /*
-+ * FLT-location structure resides after the last PCI region.
-+ */
-+
-+ /* Begin with sane defaults. */
-+ loc = locations[0];
-+ *start = IS_QLA24XX_TYPE(ha) ? FA_FLASH_LAYOUT_ADDR_24:
-+ FA_FLASH_LAYOUT_ADDR;
-+
-+ /* Begin with first PCI expansion ROM header. */
-+ buf = (uint8_t *)ha->request_ring;
-+ dcode = (uint32_t *)ha->request_ring;
-+ pcihdr = 0;
-+ last_image = 1;
-+ do {
-+ /* Verify PCI expansion ROM header. */
-+ qla24xx_read_flash_data(ha, dcode, pcihdr >> 2, 0x20);
-+ bcode = buf + (pcihdr % 4);
-+ if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa)
-+ goto end;
-+
-+ /* Locate PCI data structure. */
-+ pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
-+ qla24xx_read_flash_data(ha, dcode, pcids >> 2, 0x20);
-+ bcode = buf + (pcihdr % 4);
-+
-+ /* Validate signature of PCI data structure. */
-+ if (bcode[0x0] != 'P' || bcode[0x1] != 'C' ||
-+ bcode[0x2] != 'I' || bcode[0x3] != 'R')
-+ goto end;
-+
-+ last_image = bcode[0x15] & BIT_7;
-+
-+ /* Locate next PCI expansion ROM. */
-+ pcihdr += ((bcode[0x11] << 8) | bcode[0x10]) * 512;
-+ } while (!last_image);
-+
-+ /* Now verify FLT-location structure. */
-+ fltl = (struct qla_flt_location *)ha->request_ring;
-+ qla24xx_read_flash_data(ha, dcode, pcihdr >> 2,
-+ sizeof(struct qla_flt_location) >> 2);
-+ if (fltl->sig[0] != 'Q' || fltl->sig[1] != 'F' ||
-+ fltl->sig[2] != 'L' || fltl->sig[3] != 'T')
-+ goto end;
-+
-+ wptr = (uint16_t *)ha->request_ring;
-+ cnt = sizeof(struct qla_flt_location) >> 1;
-+ for (chksum = 0; cnt; cnt--)
-+ chksum += le16_to_cpu(*wptr++);
-+ if (chksum) {
-+ qla_printk(KERN_ERR, ha,
-+ "Inconsistent FLTL detected: checksum=0x%x.\n", chksum);
-+ qla2x00_dump_buffer(buf, sizeof(struct qla_flt_location));
-+ return QLA_FUNCTION_FAILED;
-+ }
-+
-+ /* Good data. Use specified location. */
-+ loc = locations[1];
-+ *start = le16_to_cpu(fltl->start_hi) << 16 |
-+ le16_to_cpu(fltl->start_lo);
-+end:
-+ DEBUG2(qla_printk(KERN_DEBUG, ha, "FLTL[%s] = 0x%x.\n", loc, *start));
-+ return QLA_SUCCESS;
-+}
-+
-+static void
-+qla2xxx_get_flt_info(scsi_qla_host_t *ha, uint32_t flt_addr)
-+{
-+ const char *loc, *locations[] = { "DEF", "FLT" };
-+ uint16_t *wptr;
-+ uint16_t cnt, chksum;
-+ uint32_t start;
-+ struct qla_flt_header *flt;
-+ struct qla_flt_region *region;
-+
-+ ha->flt_region_flt = flt_addr;
-+ wptr = (uint16_t *)ha->request_ring;
-+ flt = (struct qla_flt_header *)ha->request_ring;
-+ region = (struct qla_flt_region *)&flt[1];
-+ ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring,
-+ flt_addr << 2, OPTROM_BURST_SIZE);
-+ if (*wptr == __constant_cpu_to_le16(0xffff))
-+ goto no_flash_data;
-+ if (flt->version != __constant_cpu_to_le16(1)) {
-+ DEBUG2(qla_printk(KERN_INFO, ha, "Unsupported FLT detected: "
-+ "version=0x%x length=0x%x checksum=0x%x.\n",
-+ le16_to_cpu(flt->version), le16_to_cpu(flt->length),
-+ le16_to_cpu(flt->checksum)));
-+ goto no_flash_data;
-+ }
-+
-+ cnt = (sizeof(struct qla_flt_header) + le16_to_cpu(flt->length)) >> 1;
-+ for (chksum = 0; cnt; cnt--)
-+ chksum += le16_to_cpu(*wptr++);
-+ if (chksum) {
-+ DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent FLT detected: "
-+ "version=0x%x length=0x%x checksum=0x%x.\n",
-+ le16_to_cpu(flt->version), le16_to_cpu(flt->length),
-+ chksum));
-+ goto no_flash_data;
-+ }
-+
-+ loc = locations[1];
-+ cnt = le16_to_cpu(flt->length) / sizeof(struct qla_flt_region);
-+ for ( ; cnt; cnt--, region++) {
-+ /* Store addresses as DWORD offsets. */
-+ start = le32_to_cpu(region->start) >> 2;
-+
-+ DEBUG3(qla_printk(KERN_DEBUG, ha, "FLT[%02x]: start=0x%x "
-+ "end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start,
-+ le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size)));
-+
-+ switch (le32_to_cpu(region->code)) {
-+ case FLT_REG_FW:
-+ ha->flt_region_fw = start;
-+ break;
-+ case FLT_REG_BOOT_CODE:
-+ ha->flt_region_boot = start;
-+ break;
-+ case FLT_REG_VPD_0:
-+ ha->flt_region_vpd_nvram = start;
-+ break;
-+ case FLT_REG_FDT:
-+ ha->flt_region_fdt = start;
-+ break;
-+ case FLT_REG_HW_EVENT_0:
-+ if (!PCI_FUNC(ha->pdev->devfn))
-+ ha->flt_region_hw_event = start;
-+ break;
-+ case FLT_REG_HW_EVENT_1:
-+ if (PCI_FUNC(ha->pdev->devfn))
-+ ha->flt_region_hw_event = start;
-+ break;
-+ case FLT_REG_NPIV_CONF_0:
-+ if (!PCI_FUNC(ha->pdev->devfn))
-+ ha->flt_region_npiv_conf = start;
-+ break;
-+ case FLT_REG_NPIV_CONF_1:
-+ if (PCI_FUNC(ha->pdev->devfn))
-+ ha->flt_region_npiv_conf = start;
-+ break;
-+ }
-+ }
-+ goto done;
-+
-+no_flash_data:
-+ /* Use hardcoded defaults. */
-+ loc = locations[0];
-+ ha->flt_region_fw = FA_RISC_CODE_ADDR;
-+ ha->flt_region_boot = FA_BOOT_CODE_ADDR;
-+ ha->flt_region_vpd_nvram = FA_VPD_NVRAM_ADDR;
-+ ha->flt_region_fdt = IS_QLA24XX_TYPE(ha) ? FA_FLASH_DESCR_ADDR_24:
-+ FA_FLASH_DESCR_ADDR;
-+ ha->flt_region_hw_event = !PCI_FUNC(ha->pdev->devfn) ?
-+ FA_HW_EVENT0_ADDR: FA_HW_EVENT1_ADDR;
-+ ha->flt_region_npiv_conf = !PCI_FUNC(ha->pdev->devfn) ?
-+ (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF0_ADDR_24: FA_NPIV_CONF0_ADDR):
-+ (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF1_ADDR_24: FA_NPIV_CONF1_ADDR);
-+done:
-+ DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
-+ "vpd_nvram=0x%x fdt=0x%x flt=0x%x hwe=0x%x npiv=0x%x.\n", loc,
-+ ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram,
-+ ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_hw_event,
-+ ha->flt_region_npiv_conf));
-+}
-+
-+static void
-+qla2xxx_get_fdt_info(scsi_qla_host_t *ha)
- {
- #define FLASH_BLK_SIZE_32K 0x8000
- #define FLASH_BLK_SIZE_64K 0x10000
-+ const char *loc, *locations[] = { "MID", "FDT" };
- uint16_t cnt, chksum;
- uint16_t *wptr;
- struct qla_fdt_layout *fdt;
- uint8_t man_id, flash_id;
--
-- if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
-- return;
-+ uint16_t mid, fid;
-
- wptr = (uint16_t *)ha->request_ring;
- fdt = (struct qla_fdt_layout *)ha->request_ring;
- ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring,
-- FA_FLASH_DESCR_ADDR << 2, OPTROM_BURST_SIZE);
-+ ha->flt_region_fdt << 2, OPTROM_BURST_SIZE);
- if (*wptr == __constant_cpu_to_le16(0xffff))
- goto no_flash_data;
- if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' ||
-@@ -577,7 +752,10 @@ qla2xxx_get_flash_info(scsi_qla_host_t *
- goto no_flash_data;
- }
-
-- ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f;
-+ loc = locations[1];
-+ mid = le16_to_cpu(fdt->man_id);
-+ fid = le16_to_cpu(fdt->id);
-+ ha->fdt_odd_index = mid == 0x1f;
- ha->fdt_wrt_disable = fdt->wrt_disable_bits;
- ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
- ha->fdt_block_size = le32_to_cpu(fdt->block_size);
-@@ -588,16 +766,12 @@ qla2xxx_get_flash_info(scsi_qla_host_t *
- flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd):
- flash_conf_to_access_addr(0x0336);
- }
--
-- DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x "
-- "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n",
-- le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd,
-- ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd,
-- ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size));
-- return;
--
-+ goto done;
- no_flash_data:
-+ loc = locations[0];
- qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id);
-+ mid = man_id;
-+ fid = flash_id;
- ha->fdt_wrt_disable = 0x9c;
- ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8);
- switch (man_id) {
-@@ -625,14 +799,115 @@ no_flash_data:
- ha->fdt_block_size = FLASH_BLK_SIZE_64K;
- break;
- }
--
-- DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x "
-- "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id,
-+done:
-+ DEBUG2(qla_printk(KERN_DEBUG, ha, "FDT[%s]: (0x%x/0x%x) erase=0x%x "
-+ "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", loc, mid, fid,
- ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd,
- ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable,
- ha->fdt_block_size));
- }
-
-+int
-+qla2xxx_get_flash_info(scsi_qla_host_t *ha)
-+{
-+ int ret;
-+ uint32_t flt_addr;
-+
-+ if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
-+ return QLA_SUCCESS;
-+
-+ ret = qla2xxx_find_flt_start(ha, &flt_addr);
-+ if (ret != QLA_SUCCESS)
-+ return ret;
-+
-+ qla2xxx_get_flt_info(ha, flt_addr);
-+ qla2xxx_get_fdt_info(ha);
-+
-+ return QLA_SUCCESS;
-+}
-+
-+void
-+qla2xxx_flash_npiv_conf(scsi_qla_host_t *ha)
-+{
-+#define NPIV_CONFIG_SIZE (16*1024)
-+ void *data;
-+ uint16_t *wptr;
-+ uint16_t cnt, chksum;
-+ struct qla_npiv_header hdr;
-+ struct qla_npiv_entry *entry;
-+
-+ if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
-+ return;
-+
-+ ha->isp_ops->read_optrom(ha, (uint8_t *)&hdr,
-+ ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header));
-+ if (hdr.version == __constant_cpu_to_le16(0xffff))
-+ return;
-+ if (hdr.version != __constant_cpu_to_le16(1)) {
-+ DEBUG2(qla_printk(KERN_INFO, ha, "Unsupported NPIV-Config "
-+ "detected: version=0x%x entries=0x%x checksum=0x%x.\n",
-+ le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries),
-+ le16_to_cpu(hdr.checksum)));
-+ return;
-+ }
-+
-+ data = kmalloc(NPIV_CONFIG_SIZE, GFP_KERNEL);
-+ if (!data) {
-+ DEBUG2(qla_printk(KERN_INFO, ha, "NPIV-Config: Unable to "
-+ "allocate memory.\n"));
-+ return;
-+ }
-+
-+ ha->isp_ops->read_optrom(ha, (uint8_t *)data,
-+ ha->flt_region_npiv_conf << 2, NPIV_CONFIG_SIZE);
-+
-+ cnt = (sizeof(struct qla_npiv_header) + le16_to_cpu(hdr.entries) *
-+ sizeof(struct qla_npiv_entry)) >> 1;
-+ for (wptr = data, chksum = 0; cnt; cnt--)
-+ chksum += le16_to_cpu(*wptr++);
-+ if (chksum) {
-+ DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent NPIV-Config "
-+ "detected: version=0x%x entries=0x%x checksum=0x%x.\n",
-+ le16_to_cpu(hdr.version), le16_to_cpu(hdr.entries),
-+ chksum));
-+ goto done;
-+ }
-+
-+ entry = data + sizeof(struct qla_npiv_header);
-+ cnt = le16_to_cpu(hdr.entries);
-+ for ( ; cnt; cnt--, entry++) {
-+ uint16_t flags;
-+ struct fc_vport_identifiers vid;
-+ struct fc_vport *vport;
-+
-+ flags = le16_to_cpu(entry->flags);
-+ if (flags == 0xffff)
-+ continue;
-+ if ((flags & BIT_0) == 0)
-+ continue;
-+
-+ memset(&vid, 0, sizeof(vid));
-+ vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
-+ vid.vport_type = FC_PORTTYPE_NPIV;
-+ vid.disable = false;
-+ vid.port_name = wwn_to_u64(entry->port_name);
-+ vid.node_name = wwn_to_u64(entry->node_name);
-+
-+ DEBUG2(qla_printk(KERN_DEBUG, ha, "NPIV[%02x]: wwpn=%llx "
-+ "wwnn=%llx vf_id=0x%x qos=0x%x.\n", cnt, vid.port_name,
-+ vid.node_name, le16_to_cpu(entry->vf_id),
-+ le16_to_cpu(entry->qos)));
-+
-+ vport = fc_vport_create(ha->host, 0, &vid);
-+ if (!vport)
-+ qla_printk(KERN_INFO, ha, "NPIV-Config: Failed to "
-+ "create vport [%02x]: wwpn=%llx wwnn=%llx.\n", cnt,
-+ vid.port_name, vid.node_name);
-+ }
-+done:
-+ kfree(data);
-+}
-+
- static void
- qla24xx_unprotect_flash(scsi_qla_host_t *ha)
- {
-@@ -920,7 +1195,8 @@ qla25xx_read_nvram_data(scsi_qla_host_t
- dwptr = (uint32_t *)buf;
- for (i = 0; i < bytes >> 2; i++, naddr++)
- dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
-- flash_data_to_access_addr(FA_VPD_NVRAM_ADDR | naddr)));
-+ flash_data_to_access_addr(ha->flt_region_vpd_nvram |
-+ naddr)));
-
- return buf;
- }
-@@ -935,10 +1211,10 @@ qla25xx_write_nvram_data(scsi_qla_host_t
- dbuf = vmalloc(RMW_BUFFER_SIZE);
- if (!dbuf)
- return QLA_MEMORY_ALLOC_FAILED;
-- ha->isp_ops->read_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2,
-+ ha->isp_ops->read_optrom(ha, dbuf, ha->flt_region_vpd_nvram << 2,
- RMW_BUFFER_SIZE);
- memcpy(dbuf + (naddr << 2), buf, bytes);
-- ha->isp_ops->write_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2,
-+ ha->isp_ops->write_optrom(ha, dbuf, ha->flt_region_vpd_nvram << 2,
- RMW_BUFFER_SIZE);
- vfree(dbuf);
-
-@@ -2166,7 +2442,7 @@ qla2x00_get_flash_version(scsi_qla_host_
- memset(dbyte, 0, 8);
- dcode = (uint16_t *)dbyte;
-
-- qla2x00_read_flash_data(ha, dbyte, FA_RISC_CODE_ADDR * 4 + 10,
-+ qla2x00_read_flash_data(ha, dbyte, ha->flt_region_fw * 4 + 10,
- 8);
- DEBUG3(printk("%s(%ld): dumping fw ver from flash:\n",
- __func__, ha->host_no));
-@@ -2177,7 +2453,7 @@ qla2x00_get_flash_version(scsi_qla_host_
- (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
- dcode[3] == 0)) {
- DEBUG2(printk("%s(): Unrecognized fw revision at "
-- "%x.\n", __func__, FA_RISC_CODE_ADDR * 4));
-+ "%x.\n", __func__, ha->flt_region_fw * 4));
- } else {
- /* values are in big endian */
- ha->fw_revision[0] = dbyte[0] << 16 | dbyte[1];
-@@ -2212,7 +2488,7 @@ qla24xx_get_flash_version(scsi_qla_host_
- dcode = mbuf;
-
- /* Begin with first PCI expansion ROM header. */
-- pcihdr = 0;
-+ pcihdr = ha->flt_region_boot;
- last_image = 1;
- do {
- /* Verify PCI expansion ROM header. */
-@@ -2282,7 +2558,7 @@ qla24xx_get_flash_version(scsi_qla_host_
- memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
- dcode = mbuf;
-
-- qla24xx_read_flash_data(ha, dcode, FA_RISC_CODE_ADDR + 4, 4);
-+ qla24xx_read_flash_data(ha, dcode, ha->flt_region_fw + 4, 4);
- for (i = 0; i < 4; i++)
- dcode[i] = be32_to_cpu(dcode[i]);
-
-@@ -2291,7 +2567,7 @@ qla24xx_get_flash_version(scsi_qla_host_
- (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
- dcode[3] == 0)) {
- DEBUG2(printk("%s(): Unrecognized fw version at %x.\n",
-- __func__, FA_RISC_CODE_ADDR));
-+ __func__, ha->flt_region_fw));
- } else {
- ha->fw_revision[0] = dcode[0];
- ha->fw_revision[1] = dcode[1];
-@@ -2355,7 +2631,7 @@ qla2xxx_hw_event_store(scsi_qla_host_t *
- /* Locate first empty entry. */
- for (;;) {
- if (ha->hw_event_ptr >=
-- ha->hw_event_start + FA_HW_EVENT_SIZE) {
-+ ha->flt_region_hw_event + FA_HW_EVENT_SIZE) {
- DEBUG2(qla_printk(KERN_WARNING, ha,
- "HW event -- Log Full!\n"));
- return QLA_MEMORY_ALLOC_FAILED;
-@@ -2391,7 +2667,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha
- int rval;
- uint32_t marker[2], fdata[4];
-
-- if (ha->hw_event_start == 0)
-+ if (ha->flt_region_hw_event == 0)
- return QLA_FUNCTION_FAILED;
-
- DEBUG2(qla_printk(KERN_WARNING, ha,
-@@ -2406,7 +2682,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha
- QLA_DRIVER_PATCH_VER, QLA_DRIVER_BETA_VER);
-
- /* Locate marker. */
-- ha->hw_event_ptr = ha->hw_event_start;
-+ ha->hw_event_ptr = ha->flt_region_hw_event;
- for (;;) {
- qla24xx_read_flash_data(ha, fdata, ha->hw_event_ptr,
- 4);
-@@ -2415,7 +2691,7 @@ qla2xxx_hw_event_log(scsi_qla_host_t *ha
- break;
- ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE;
- if (ha->hw_event_ptr >=
-- ha->hw_event_start + FA_HW_EVENT_SIZE) {
-+ ha->flt_region_hw_event + FA_HW_EVENT_SIZE) {
- DEBUG2(qla_printk(KERN_WARNING, ha,
- "HW event -- Log Full!\n"));
- return QLA_MEMORY_ALLOC_FAILED;
---- a/drivers/scsi/qla2xxx/qla_version.h
-+++ b/drivers/scsi/qla2xxx/qla_version.h
-@@ -7,7 +7,7 @@
- /*
- * Driver version
- */
--#define QLA2XXX_VERSION "8.02.01-k7"
-+#define QLA2XXX_VERSION "8.02.01-k8"
-
- #define QLA_DRIVER_MAJOR_VER 8
- #define QLA_DRIVER_MINOR_VER 2