All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/29] Update driver to 8.06.00.08-k
@ 2013-08-27  5:37 Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 01/29] qla2xxx: Print some variables to hexadecimal string via %*phN format Saurav Kashyap
                   ` (29 more replies)
  0 siblings, 30 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

Hi James,

Please apply the following patches to the scsi tree, misc branch at your
earliest convenience.

Thanks,
~Saurav


Andrew Vasquez (1):
  qla2xxx: Correct multiqueue offset calculations.

Andy Shevchenko (1):
  qla2xxx: print MAC via %pMR.

Armen Baloyan (12):
  qla2xxx: Set factory reset recovery timeout to 10 min. for ISPFX00.
  qla2xxx: Perform warm reset every 2 minutes if firmware load fails
    for ISPFX00.
  qla2xxx: Add ISPFX00 specific bus reset routine.
  qla2xxx: Notify ISPFX00 firmware when driver is unloaded or system is
    shut down.
  qla2xxx: Add critical temperature handling for ISPFX00.
  qla2xxx: Add changes to support extended IOs for ISPFX00
  qla2xxx: Add changes in initialization for ISPFX00 cards with BIOS
  qla2xxx: Send all AENs for ISPFx00 to above layers.
  qla2xxx: Remove handling of Shutdown Requested AEN from
    qlafx00_process_aen().
  qla2xxx: Correct Interrupt Register offset for ISPFX00
  qla2xxx: QLAFX00 make over temperature AEN handling informational,
    add log for normal temperature AEN
  qla2xxx: Set default critical temperature value in cases when ISPFX00
    firmware doesn't provide it

Atul Deshmukh (1):
  qla2xxx: Add support for ISP8044.

Chad Dupuis (3):
  qla2xxx: Remove QL_DEBUG_LEVEL_17 defines from qla_nx.c.
  qla2xxx: Make log message that prints when a completion status
    requires a port down more readable.
  qla2xxx: Move queue depth ramp down message to i/o debug level.

Joe Carnuccio (6):
  qla2xxx: Fix incorrect test after list_for_each_entry() exits.
  qla2xxx: Add setting of driver version string for vendor application.
  qla2xxx: Reconfigure thermal temperature.
  qla2xxx: Add missing FCP statistics to sysfs interface.
  qla2xxx: Select link initialization option bits from current
    operating mode.
  qla2xxx: Correctly print out/in mailbox registers.

Oleksandr Khoshaba (1):
  qla2xxx: Print some variables to hexadecimal string via %*phN format

Santosh Vernekar (1):
  qla2xxx: Add loopback IDC-TIME-EXTEND aen handling support.

Saurav Kashyap (2):
  qla2xxx: Correction to message ids.
  qla2xxx: Update the driver version to 8.06.00.08-k.

Sawan Chandak (1):
  qla2xxx: Add a new interface to update versions.

 drivers/scsi/qla2xxx/Makefile      |    2 +-
 drivers/scsi/qla2xxx/qla_attr.c    |   79 +-
 drivers/scsi/qla2xxx/qla_bsg.c     |   43 +-
 drivers/scsi/qla2xxx/qla_dbg.c     |   58 +-
 drivers/scsi/qla2xxx/qla_def.h     |   39 +-
 drivers/scsi/qla2xxx/qla_fw.h      |    2 +
 drivers/scsi/qla2xxx/qla_gbl.h     |   40 +
 drivers/scsi/qla2xxx/qla_gs.c      |   97 +-
 drivers/scsi/qla2xxx/qla_init.c    |   86 +-
 drivers/scsi/qla2xxx/qla_inline.h  |    2 +-
 drivers/scsi/qla2xxx/qla_iocb.c    |   17 +-
 drivers/scsi/qla2xxx/qla_isr.c     |   91 +-
 drivers/scsi/qla2xxx/qla_mbx.c     |  297 +++-
 drivers/scsi/qla2xxx/qla_mid.c     |    2 +
 drivers/scsi/qla2xxx/qla_mr.c      |  164 ++-
 drivers/scsi/qla2xxx/qla_mr.h      |   35 +-
 drivers/scsi/qla2xxx/qla_nx.c      |  117 +-
 drivers/scsi/qla2xxx/qla_nx.h      |   10 +
 drivers/scsi/qla2xxx/qla_nx2.c     | 3716 ++++++++++++++++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_nx2.h     |  551 ++++++
 drivers/scsi/qla2xxx/qla_os.c      |  213 ++-
 drivers/scsi/qla2xxx/qla_sup.c     |  162 ++-
 drivers/scsi/qla2xxx/qla_target.c  |   69 +-
 drivers/scsi/qla2xxx/qla_version.h |    4 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |   14 +-
 25 files changed, 5427 insertions(+), 483 deletions(-)
 create mode 100644 drivers/scsi/qla2xxx/qla_nx2.c
 create mode 100644 drivers/scsi/qla2xxx/qla_nx2.h

-- 
1.7.7


^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH 01/29] qla2xxx: Print some variables to hexadecimal string via %*phN format
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 02/29] qla2xxx: Add support for ISP8044 Saurav Kashyap
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Oleksandr Khoshaba <Oleksandr.Khoshaba@gmail.com>

The patch changes a specifier used to output some variables. Instead of using
stack for each byte the '%*ph[CN]' allows to take a one pointer and prints
entire buffer as a hexadecimal string with the separator ':' or ''.

Signed-off-by: Oleksandr Khoshaba <Oleksandr.Khoshaba@gmail.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_bsg.c     |    9 +--
 drivers/scsi/qla2xxx/qla_gs.c      |   91 ++++++------------------------------
 drivers/scsi/qla2xxx/qla_init.c    |   24 ++--------
 drivers/scsi/qla2xxx/qla_isr.c     |    9 +--
 drivers/scsi/qla2xxx/qla_mr.c      |   13 ++---
 drivers/scsi/qla2xxx/qla_os.c      |   10 +---
 drivers/scsi/qla2xxx/qla_target.c  |   69 ++++++++-------------------
 drivers/scsi/qla2xxx/tcm_qla2xxx.c |   14 ++----
 8 files changed, 58 insertions(+), 181 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 417eaad..2dbae07 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1318,12 +1318,9 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
 
 	if (rval) {
 		ql_log(ql_log_warn, vha, 0x704c,
-		    "iIDMA cmd failed for %02x%02x%02x%02x%02x%02x%02x%02x -- "
-		    "%04x %x %04x %04x.\n", fcport->port_name[0],
-		    fcport->port_name[1], fcport->port_name[2],
-		    fcport->port_name[3], fcport->port_name[4],
-		    fcport->port_name[5], fcport->port_name[6],
-		    fcport->port_name[7], rval, fcport->fp_speed, mb[0], mb[1]);
+		    "iIDMA cmd failed for %8phN -- "
+		    "%04x %x %04x %04x.\n", fcport->port_name,
+		    rval, fcport->fp_speed, mb[0], mb[1]);
 		rval = (DID_ERROR << 16);
 	} else {
 		if (!port_param->mode) {
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 0926451..84cce36 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -226,17 +226,9 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
 			fcport->d_id.b.domain = 0xf0;
 
 		ql_dbg(ql_dbg_disc, vha, 0x2063,
-		    "GA_NXT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x "
-		    "pn %02x%02x%02x%02x%02x%02x%02x%02x "
+		    "GA_NXT entry - nn %8phN pn %8phN "
 		    "port_id=%02x%02x%02x.\n",
-		    fcport->node_name[0], fcport->node_name[1],
-		    fcport->node_name[2], fcport->node_name[3],
-		    fcport->node_name[4], fcport->node_name[5],
-		    fcport->node_name[6], fcport->node_name[7],
-		    fcport->port_name[0], fcport->port_name[1],
-		    fcport->port_name[2], fcport->port_name[3],
-		    fcport->port_name[4], fcport->port_name[5],
-		    fcport->port_name[6], fcport->port_name[7],
+		    fcport->node_name, fcport->port_name,
 		    fcport->d_id.b.domain, fcport->d_id.b.area,
 		    fcport->d_id.b.al_pa);
 	}
@@ -447,17 +439,9 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
 			    ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
 
 			ql_dbg(ql_dbg_disc, vha, 0x2058,
-			    "GID_PT entry - nn %02x%02x%02x%02x%02x%02x%02X%02x "
-			    "pn %02x%02x%02x%02x%02x%02x%02X%02x "
+			    "GID_PT entry - nn %8phN pn %8phN "
 			    "portid=%02x%02x%02x.\n",
-			    list[i].node_name[0], list[i].node_name[1],
-			    list[i].node_name[2], list[i].node_name[3],
-			    list[i].node_name[4], list[i].node_name[5],
-			    list[i].node_name[6], list[i].node_name[7],
-			    list[i].port_name[0], list[i].port_name[1],
-			    list[i].port_name[2], list[i].port_name[3],
-			    list[i].port_name[4], list[i].port_name[5],
-			    list[i].port_name[6], list[i].port_name[7],
+			    list[i].node_name, list[i].port_name,
 			    list[i].d_id.b.domain, list[i].d_id.b.area,
 			    list[i].d_id.b.al_pa);
 		}
@@ -796,17 +780,9 @@ qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
 			fcport->d_id.b.domain = 0xf0;
 
 		ql_dbg(ql_dbg_disc, vha, 0x2061,
-		    "GA_NXT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x "
-		    "pn %02x%02x%02x%02x%02x%02x%02x%02x "
+		    "GA_NXT entry - nn %8phN pn %8phN "
 		    "port_id=%02x%02x%02x.\n",
-		    fcport->node_name[0], fcport->node_name[1],
-		    fcport->node_name[2], fcport->node_name[3],
-		    fcport->node_name[4], fcport->node_name[5],
-		    fcport->node_name[6], fcport->node_name[7],
-		    fcport->port_name[0], fcport->port_name[1],
-		    fcport->port_name[2], fcport->port_name[3],
-		    fcport->port_name[4], fcport->port_name[5],
-		    fcport->port_name[6], fcport->port_name[7],
+		    fcport->node_name, fcport->port_name,
 		    fcport->d_id.b.domain, fcport->d_id.b.area,
 		    fcport->d_id.b.al_pa);
 	}
@@ -991,17 +967,9 @@ qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
 			    WWN_SIZE);
 
 			ql_dbg(ql_dbg_disc, vha, 0x206e,
-			    "GID_PT entry - nn %02x%02x%02x%02x%02x%02x%02x%02x "
-			    "pn %02x%02x%02x%02x%02x%02x%02x%02x "
+			    "GID_PT entry - nn %8phN pn %8phN "
 			    "port_id=%02x%02x%02x.\n",
-			    list[i].node_name[0], list[i].node_name[1],
-			    list[i].node_name[2], list[i].node_name[3],
-			    list[i].node_name[4], list[i].node_name[5],
-			    list[i].node_name[6], list[i].node_name[7],
-			    list[i].port_name[0], list[i].port_name[1],
-			    list[i].port_name[2], list[i].port_name[3],
-			    list[i].port_name[4], list[i].port_name[5],
-			    list[i].port_name[6], list[i].port_name[7],
+			    list[i].node_name, list[i].port_name,
 			    list[i].d_id.b.domain, list[i].d_id.b.area,
 			    list[i].d_id.b.al_pa);
 		}
@@ -1321,11 +1289,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
 	size += 4 + WWN_SIZE;
 
 	ql_dbg(ql_dbg_disc, vha, 0x2025,
-	    "NodeName = %02x%02x%02x%02x%02x%02x%02x%02x.\n",
-	    eiter->a.node_name[0], eiter->a.node_name[1],
-	    eiter->a.node_name[2], eiter->a.node_name[3],
-	    eiter->a.node_name[4], eiter->a.node_name[5],
-	    eiter->a.node_name[6], eiter->a.node_name[7]);
+	    "NodeName = %8phN.\n", eiter->a.node_name);
 
 	/* Manufacturer. */
 	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
@@ -1428,16 +1392,8 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
 	qla2x00_update_ms_fdmi_iocb(vha, size + 16);
 
 	ql_dbg(ql_dbg_disc, vha, 0x202e,
-	    "RHBA identifier = "
-	    "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n",
-	    ct_req->req.rhba.hba_identifier[0],
-	    ct_req->req.rhba.hba_identifier[1],
-	    ct_req->req.rhba.hba_identifier[2],
-	    ct_req->req.rhba.hba_identifier[3],
-	    ct_req->req.rhba.hba_identifier[4],
-	    ct_req->req.rhba.hba_identifier[5],
-	    ct_req->req.rhba.hba_identifier[6],
-	    ct_req->req.rhba.hba_identifier[7], size);
+	    "RHBA identifier = %8phN size=%d.\n",
+	    ct_req->req.rhba.hba_identifier, size);
 	ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076,
 	    entries, size);
 
@@ -1494,11 +1450,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
 	memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
 
 	ql_dbg(ql_dbg_disc, vha, 0x2036,
-	    "DHBA portname = %02x%02x%02x%02x%02x%02x%02x%02x.\n",
-	    ct_req->req.dhba.port_name[0], ct_req->req.dhba.port_name[1],
-	    ct_req->req.dhba.port_name[2], ct_req->req.dhba.port_name[3],
-	    ct_req->req.dhba.port_name[4], ct_req->req.dhba.port_name[5],
-	    ct_req->req.dhba.port_name[6], ct_req->req.dhba.port_name[7]);
+	    "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name);
 
 	/* Execute MS IOCB */
 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
@@ -1678,12 +1630,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
 	qla2x00_update_ms_fdmi_iocb(vha, size + 16);
 
 	ql_dbg(ql_dbg_disc, vha, 0x203e,
-	    "RPA portname= %02x%02x%02x%02x%02X%02x%02x%02x size=%d.\n",
-	    ct_req->req.rpa.port_name[0], ct_req->req.rpa.port_name[1],
-	    ct_req->req.rpa.port_name[2], ct_req->req.rpa.port_name[3],
-	    ct_req->req.rpa.port_name[4], ct_req->req.rpa.port_name[5],
-	    ct_req->req.rpa.port_name[6], ct_req->req.rpa.port_name[7],
-	    size);
+	    "RPA portname= %8phN size=%d.\n", ct_req->req.rpa.port_name, size);
 	ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079,
 	    entries, size);
 
@@ -1940,16 +1887,8 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
 
 			ql_dbg(ql_dbg_disc, vha, 0x205b,
 			    "GPSC ext entry - fpn "
-			    "%02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x "
-			    "speed=%04x.\n",
-			    list[i].fabric_port_name[0],
-			    list[i].fabric_port_name[1],
-			    list[i].fabric_port_name[2],
-			    list[i].fabric_port_name[3],
-			    list[i].fabric_port_name[4],
-			    list[i].fabric_port_name[5],
-			    list[i].fabric_port_name[6],
-			    list[i].fabric_port_name[7],
+			    "%8phN speeds=%04x speed=%04x.\n",
+			    list[i].fabric_port_name,
 			    be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
 			    be16_to_cpu(ct_rsp->rsp.gpsc.speed));
 		}
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f2216ed..d60e2c1 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -564,12 +564,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
 	if (ha->flags.disable_serdes) {
 		/* Mask HBA via NVRAM settings? */
 		ql_log(ql_log_info, vha, 0x0077,
-		    "Masking HBA WWPN "
-		    "%02x%02x%02x%02x%02x%02x%02x%02x (via NVRAM).\n",
-		    vha->port_name[0], vha->port_name[1],
-		    vha->port_name[2], vha->port_name[3],
-		    vha->port_name[4], vha->port_name[5],
-		    vha->port_name[6], vha->port_name[7]);
+		    "Masking HBA WWPN %8phN (via NVRAM).\n", vha->port_name);
 		return QLA_FUNCTION_FAILED;
 	}
 
@@ -3061,22 +3056,13 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
 	    mb);
 	if (rval != QLA_SUCCESS) {
 		ql_dbg(ql_dbg_disc, vha, 0x2004,
-		    "Unable to adjust iIDMA "
-		    "%02x%02x%02x%02x%02x%02x%02x%02x -- %04x %x %04x "
-		    "%04x.\n", fcport->port_name[0], fcport->port_name[1],
-		    fcport->port_name[2], fcport->port_name[3],
-		    fcport->port_name[4], fcport->port_name[5],
-		    fcport->port_name[6], fcport->port_name[7], rval,
-		    fcport->fp_speed, mb[0], mb[1]);
+		    "Unable to adjust iIDMA %8phN -- %04x %x %04x %04x.\n",
+		    fcport->port_name, rval, fcport->fp_speed, mb[0], mb[1]);
 	} else {
 		ql_dbg(ql_dbg_disc, vha, 0x2005,
-		    "iIDMA adjusted to %s GB/s "
-		    "on %02x%02x%02x%02x%02x%02x%02x%02x.\n",
+		    "iIDMA adjusted to %s GB/s on %8phN.\n",
 		    qla2x00_get_link_speed_str(ha, fcport->fp_speed),
-		    fcport->port_name[0], fcport->port_name[1],
-		    fcport->port_name[2], fcport->port_name[3],
-		    fcport->port_name[4], fcport->port_name[5],
-		    fcport->port_name[6], fcport->port_name[7]);
+		    fcport->port_name);
 	}
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 2d8e7b8..e779506 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2212,16 +2212,13 @@ check_scsi_status:
 out:
 	if (logit)
 		ql_dbg(ql_dbg_io, fcport->vha, 0x3022,
-		    "FCP command status: 0x%x-0x%x (0x%x) "
-		    "nexus=%ld:%d:%d portid=%02x%02x%02x oxid=0x%x "
-		    "cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x "
+		    "FCP command status: 0x%x-0x%x (0x%x) nexus=%ld:%d:%d "
+		    "portid=%02x%02x%02x oxid=0x%x cdb=%10phN len=0x%x "
 		    "rsp_info=0x%x resid=0x%x fw_resid=0x%x.\n",
 		    comp_status, scsi_status, res, vha->host_no,
 		    cp->device->id, cp->device->lun, fcport->d_id.b.domain,
 		    fcport->d_id.b.area, fcport->d_id.b.al_pa, ox_id,
-		    cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
-		    cp->cmnd[4], cp->cmnd[5], cp->cmnd[6], cp->cmnd[7],
-		    cp->cmnd[8], cp->cmnd[9], scsi_bufflen(cp), rsp_info_len,
+		    cp->cmnd, scsi_bufflen(cp), rsp_info_len,
 		    resid_len, fw_resid_len);
 
 	if (!res)
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index d799379..413f050 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -2526,16 +2526,13 @@ check_scsi_status:
 
 	if (logit)
 		ql_dbg(ql_dbg_io, fcport->vha, 0x3058,
-		    "FCP command status: 0x%x-0x%x (0x%x) "
-		    "nexus=%ld:%d:%d tgt_id: 0x%x lscsi_status: 0x%x"
-		    "cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x "
-		    "rsp_info=0x%x resid=0x%x fw_resid=0x%x "
-		    "sense_len=0x%x, par_sense_len=0x%x, rsp_info_len=0x%x\n",
+		    "FCP command status: 0x%x-0x%x (0x%x) nexus=%ld:%d:%d "
+		    "tgt_id: 0x%x lscsi_status: 0x%x cdb=%10phN len=0x%x "
+		    "rsp_info=0x%x resid=0x%x fw_resid=0x%x sense_len=0x%x, "
+		    "par_sense_len=0x%x, rsp_info_len=0x%x\n",
 		    comp_status, scsi_status, res, vha->host_no,
 		    cp->device->id, cp->device->lun, fcport->tgt_id,
-		    lscsi_status, cp->cmnd[0], cp->cmnd[1], cp->cmnd[2],
-		    cp->cmnd[3], cp->cmnd[4], cp->cmnd[5], cp->cmnd[6],
-		    cp->cmnd[7], cp->cmnd[8], cp->cmnd[9], scsi_bufflen(cp),
+		    lscsi_status, cp->cmnd, scsi_bufflen(cp),
 		    rsp_info_len, resid_len, fw_resid_len, sense_len,
 		    par_sense_len, rsp_info_len);
 
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3e21e9f..9207aeb 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3210,14 +3210,8 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
 
 		ql_dbg(ql_dbg_disc, vha, 0x2067,
-		    "Port login retry "
-		    "%02x%02x%02x%02x%02x%02x%02x%02x, "
-		    "id = 0x%04x retry cnt=%d.\n",
-		    fcport->port_name[0], fcport->port_name[1],
-		    fcport->port_name[2], fcport->port_name[3],
-		    fcport->port_name[4], fcport->port_name[5],
-		    fcport->port_name[6], fcport->port_name[7],
-		    fcport->loop_id, fcport->login_retry);
+		    "Port login retry %8phN, id = 0x%04x retry cnt=%d.\n",
+		    fcport->port_name, fcport->loop_id, fcport->login_retry);
 	}
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 83a8f7a..ff12d46 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -430,13 +430,8 @@ static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd)
 	}
 
 	ql_dbg(ql_dbg_tgt, vha, 0xe047,
-	    "scsi(%ld): resetting (session %p from port "
-	    "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, "
-	    "mcmd %x, loop_id %d)\n", vha->host_no, sess,
-	    sess->port_name[0], sess->port_name[1],
-	    sess->port_name[2], sess->port_name[3],
-	    sess->port_name[4], sess->port_name[5],
-	    sess->port_name[6], sess->port_name[7],
+	    "scsi(%ld): resetting (session %p from port %8phC mcmd %x, "
+	    "loop_id %d)\n", vha->host_no, sess, sess->port_name,
 	    mcmd, loop_id);
 
 	lun = a->u.isp24.fcp_cmnd.lun;
@@ -467,15 +462,10 @@ static void qlt_schedule_sess_for_deletion(struct qla_tgt_sess *sess,
 	sess->expires = jiffies + dev_loss_tmo * HZ;
 
 	ql_dbg(ql_dbg_tgt, sess->vha, 0xe048,
-	    "qla_target(%d): session for port %02x:%02x:%02x:"
-	    "%02x:%02x:%02x:%02x:%02x (loop ID %d) scheduled for "
+	    "qla_target(%d): session for port %8phC (loop ID %d) scheduled for "
 	    "deletion in %u secs (expires: %lu) immed: %d\n",
-	    sess->vha->vp_idx,
-	    sess->port_name[0], sess->port_name[1],
-	    sess->port_name[2], sess->port_name[3],
-	    sess->port_name[4], sess->port_name[5],
-	    sess->port_name[6], sess->port_name[7],
-	    sess->loop_id, dev_loss_tmo, sess->expires, immediate);
+	    sess->vha->vp_idx, sess->port_name, sess->loop_id, dev_loss_tmo,
+	    sess->expires, immediate);
 
 	if (immediate)
 		schedule_delayed_work(&tgt->sess_del_work, 0);
@@ -630,13 +620,9 @@ static struct qla_tgt_sess *qlt_create_sess(
 	sess = kzalloc(sizeof(*sess), GFP_KERNEL);
 	if (!sess) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04a,
-		    "qla_target(%u): session allocation failed, "
-		    "all commands from port %02x:%02x:%02x:%02x:"
-		    "%02x:%02x:%02x:%02x will be refused", vha->vp_idx,
-		    fcport->port_name[0], fcport->port_name[1],
-		    fcport->port_name[2], fcport->port_name[3],
-		    fcport->port_name[4], fcport->port_name[5],
-		    fcport->port_name[6], fcport->port_name[7]);
+		    "qla_target(%u): session allocation failed, all commands "
+		    "from port %8phC will be refused", vha->vp_idx,
+		    fcport->port_name);
 
 		return NULL;
 	}
@@ -680,15 +666,11 @@ static struct qla_tgt_sess *qlt_create_sess(
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b,
-	    "qla_target(%d): %ssession for wwn %02x:%02x:%02x:%02x:"
-	    "%02x:%02x:%02x:%02x (loop_id %d, s_id %x:%x:%x, confirmed"
-	    " completion %ssupported) added\n",
-	    vha->vp_idx, local ?  "local " : "", fcport->port_name[0],
-	    fcport->port_name[1], fcport->port_name[2], fcport->port_name[3],
-	    fcport->port_name[4], fcport->port_name[5], fcport->port_name[6],
-	    fcport->port_name[7], fcport->loop_id, sess->s_id.b.domain,
-	    sess->s_id.b.area, sess->s_id.b.al_pa, sess->conf_compl_supported ?
-	    "" : "not ");
+	    "qla_target(%d): %ssession for wwn %8phC (loop_id %d, "
+	    "s_id %x:%x:%x, confirmed completion %ssupported) added\n",
+	    vha->vp_idx, local ?  "local " : "", fcport->port_name,
+	    fcport->loop_id, sess->s_id.b.domain, sess->s_id.b.area,
+	    sess->s_id.b.al_pa, sess->conf_compl_supported ?  "" : "not ");
 
 	return sess;
 }
@@ -730,13 +712,9 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
 			qlt_undelete_sess(sess);
 
 			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04c,
-			    "qla_target(%u): %ssession for port %02x:"
-			    "%02x:%02x:%02x:%02x:%02x:%02x:%02x (loop ID %d) "
-			    "reappeared\n", vha->vp_idx, sess->local ? "local "
-			    : "", sess->port_name[0], sess->port_name[1],
-			    sess->port_name[2], sess->port_name[3],
-			    sess->port_name[4], sess->port_name[5],
-			    sess->port_name[6], sess->port_name[7],
+			    "qla_target(%u): %ssession for port %8phC "
+			    "(loop ID %d) reappeared\n", vha->vp_idx,
+			    sess->local ? "local " : "", sess->port_name,
 			    sess->loop_id);
 
 			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007,
@@ -749,13 +727,8 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
 	if (sess && sess->local) {
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04d,
 		    "qla_target(%u): local session for "
-		    "port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
-		    "(loop ID %d) became global\n", vha->vp_idx,
-		    fcport->port_name[0], fcport->port_name[1],
-		    fcport->port_name[2], fcport->port_name[3],
-		    fcport->port_name[4], fcport->port_name[5],
-		    fcport->port_name[6], fcport->port_name[7],
-		    sess->loop_id);
+		    "port %8phC (loop ID %d) became global\n", vha->vp_idx,
+		    fcport->port_name, sess->loop_id);
 		sess->local = 0;
 	}
 	ha->tgt.tgt_ops->put_sess(sess);
@@ -2840,10 +2813,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
 	int res = 0;
 
 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf026,
-	    "qla_target(%d): Port ID: 0x%02x:%02x:%02x"
-	    " ELS opcode: 0x%02x\n", vha->vp_idx, iocb->u.isp24.port_id[0],
-	    iocb->u.isp24.port_id[1], iocb->u.isp24.port_id[2],
-	    iocb->u.isp24.status_subcode);
+	    "qla_target(%d): Port ID: 0x%3phC ELS opcode: 0x%02x\n",
+	    vha->vp_idx, iocb->u.isp24.port_id, iocb->u.isp24.status_subcode);
 
 	switch (iocb->u.isp24.status_subcode) {
 	case ELS_PLOGI:
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index a318092..a6da313 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1474,15 +1474,11 @@ static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id,
 
 
 	if (sess->loop_id != loop_id || sess->s_id.b24 != s_id.b24)
-		pr_info("Updating session %p from port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x loop_id %d -> %d s_id %x:%x:%x -> %x:%x:%x\n",
-			sess,
-			sess->port_name[0], sess->port_name[1],
-			sess->port_name[2], sess->port_name[3],
-			sess->port_name[4], sess->port_name[5],
-			sess->port_name[6], sess->port_name[7],
-			sess->loop_id, loop_id,
-			sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa,
-			s_id.b.domain, s_id.b.area, s_id.b.al_pa);
+		pr_info("Updating session %p from port %8phC loop_id %d -> %d s_id %x:%x:%x -> %x:%x:%x\n",
+		    sess, sess->port_name,
+		    sess->loop_id, loop_id, sess->s_id.b.domain,
+		    sess->s_id.b.area, sess->s_id.b.al_pa, s_id.b.domain,
+		    s_id.b.area, s_id.b.al_pa);
 
 	if (sess->loop_id != loop_id) {
 		/*
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 02/29] qla2xxx: Add support for ISP8044.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 01/29] qla2xxx: Print some variables to hexadecimal string via %*phN format Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-28  7:15   ` James Bottomley
  2013-08-27  5:37 ` [PATCH 03/29] qla2xxx: Fix incorrect test after list_for_each_entry() exits Saurav Kashyap
                   ` (27 subsequent siblings)
  29 siblings, 1 reply; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Atul Deshmukh <atul.deshmukh@qlogic.com>

Signed-off-by: Atul Deshmukh <atul.deshmukh@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/Makefile     |    2 +-
 drivers/scsi/qla2xxx/qla_attr.c   |   29 +-
 drivers/scsi/qla2xxx/qla_bsg.c    |   12 +-
 drivers/scsi/qla2xxx/qla_dbg.c    |   16 +-
 drivers/scsi/qla2xxx/qla_def.h    |   16 +-
 drivers/scsi/qla2xxx/qla_fw.h     |    2 +
 drivers/scsi/qla2xxx/qla_gbl.h    |   30 +
 drivers/scsi/qla2xxx/qla_init.c   |   55 +-
 drivers/scsi/qla2xxx/qla_inline.h |    2 +-
 drivers/scsi/qla2xxx/qla_iocb.c   |    4 +-
 drivers/scsi/qla2xxx/qla_isr.c    |   26 +-
 drivers/scsi/qla2xxx/qla_mbx.c    |   78 +-
 drivers/scsi/qla2xxx/qla_nx.c     |   95 +-
 drivers/scsi/qla2xxx/qla_nx.h     |   10 +
 drivers/scsi/qla2xxx/qla_nx2.c    | 3708 +++++++++++++++++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_nx2.h    |  551 ++++++
 drivers/scsi/qla2xxx/qla_os.c     |  175 ++-
 drivers/scsi/qla2xxx/qla_sup.c    |  162 ++-
 18 files changed, 4832 insertions(+), 141 deletions(-)
 create mode 100644 drivers/scsi/qla2xxx/qla_nx2.c
 create mode 100644 drivers/scsi/qla2xxx/qla_nx2.h

diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
index c37b244..ff0fc7c 100644
--- a/drivers/scsi/qla2xxx/Makefile
+++ b/drivers/scsi/qla2xxx/Makefile
@@ -1,6 +1,6 @@
 qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
 		qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \
-        qla_nx.o qla_mr.o qla_target.o
+        qla_nx.o qla_mr.o qla_nx2.o qla_target.o
 
 obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
 obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index d7a99ae..8e8b50e 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -29,7 +29,7 @@ qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj,
 	if (!(ha->fw_dump_reading || ha->mctp_dump_reading))
 		return 0;
 
-	if (IS_QLA82XX(ha)) {
+	if (IS_P3P_TYPE(ha)) {
 		if (off < ha->md_template_size) {
 			rval = memory_read_from_buffer(buf, count,
 			    &off, ha->md_tmplt_hdr, ha->md_template_size);
@@ -71,7 +71,7 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
 		ql_log(ql_log_info, vha, 0x705d,
 		    "Firmware dump cleared on (%ld).\n", vha->host_no);
 
-		if (IS_QLA82XX(vha->hw)) {
+		if (IS_P3P_TYPE(ha)) {
 			qla82xx_md_free(vha);
 			qla82xx_md_prep(vha);
 		}
@@ -95,11 +95,15 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
 			qla82xx_idc_lock(ha);
 			qla82xx_set_reset_owner(vha);
 			qla82xx_idc_unlock(ha);
+		} else if (IS_QLA8044(ha)) {
+			qla8044_idc_lock(ha);
+			qla82xx_set_reset_owner(vha);
+			qla8044_idc_unlock(ha);
 		} else
 			qla2x00_system_error(vha);
 		break;
 	case 4:
-		if (IS_QLA82XX(ha)) {
+		if (IS_P3P_TYPE(ha)) {
 			if (ha->md_tmplt_hdr)
 				ql_dbg(ql_dbg_user, vha, 0x705b,
 				    "MiniDump supported with this firmware.\n");
@@ -109,7 +113,7 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
 		}
 		break;
 	case 5:
-		if (IS_QLA82XX(ha))
+		if (IS_P3P_TYPE(ha))
 			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 		break;
 	case 6:
@@ -597,14 +601,23 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
 		    "Issuing ISP reset.\n");
 
 		scsi_block_requests(vha->host);
-		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 		if (IS_QLA82XX(ha)) {
 			ha->flags.isp82xx_no_md_cap = 1;
 			qla82xx_idc_lock(ha);
 			qla82xx_set_reset_owner(vha);
 			qla82xx_idc_unlock(ha);
+		} else if (IS_QLA8044(ha)) {
+			qla8044_idc_lock(ha);
+			idc_control = qla8044_rd_reg(ha,
+			    QLA8044_IDC_DRV_CTRL);
+			qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL,
+			    (idc_control | GRACEFUL_RESET_BIT1));
+			qla82xx_set_reset_owner(vha);
+			qla8044_idc_unlock(ha);
+		} else {
+			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+			qla2xxx_wake_dpc(vha);
 		}
-		qla2xxx_wake_dpc(vha);
 		qla2x00_wait_for_chip_reset(vha);
 		scsi_unblock_requests(vha->host);
 		break;
@@ -640,7 +653,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
 			break;
 		}
 	case 0x2025e:
-		if (!IS_QLA82XX(ha) || vha != base_vha) {
+		if (!IS_P3P_TYPE(ha) || vha != base_vha) {
 			ql_log(ql_log_info, vha, 0x7071,
 			    "FCoE ctx reset no supported.\n");
 			return -EPERM;
@@ -1212,7 +1225,7 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
 	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
 		return snprintf(buf, PAGE_SIZE, "\n");
 
 	return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 2dbae07..ffcad26 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -125,7 +125,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 	uint32_t len;
 	uint32_t oper;
 
-	if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA82XX(ha))) {
+	if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_P3P_TYPE(ha))) {
 		ret = -EINVAL;
 		goto exit_fcp_prio_cfg;
 	}
@@ -559,7 +559,7 @@ qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
 	uint16_t new_config[4];
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
 		goto done_reset_internal;
 
 	memset(new_config, 0 , sizeof(new_config));
@@ -629,7 +629,7 @@ qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
 	int rval = 0;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
 		goto done_set_internal;
 
 	if (mode == INTERNAL_LOOPBACK)
@@ -773,7 +773,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 
 	if (atomic_read(&vha->loop_state) == LOOP_READY &&
 	    (ha->current_topology == ISP_CFG_F ||
-	    ((IS_QLA81XX(ha) || IS_QLA8031(ha)) &&
+	    ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) &&
 	    le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
 	    && req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
 		elreq.options == EXTERNAL_LOOPBACK) {
@@ -783,7 +783,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 		command_sent = INT_DEF_LB_ECHO_CMD;
 		rval = qla2x00_echo_test(vha, &elreq, response);
 	} else {
-		if (IS_QLA81XX(ha) || IS_QLA8031(ha)) {
+		if (IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) {
 			memset(config, 0, sizeof(config));
 			memset(new_config, 0, sizeof(new_config));
 
@@ -806,7 +806,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 			    "elreq.options=%04x\n", elreq.options);
 
 			if (elreq.options == EXTERNAL_LOOPBACK)
-				if (IS_QLA8031(ha))
+				if (IS_QLA8031(ha) || IS_QLA8044(ha))
 					rval = qla81xx_set_loopback_mode(vha,
 					    config, new_config, elreq.options);
 				else
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index df132fe..6ed98f9 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -11,7 +11,7 @@
  * ----------------------------------------------------------------------
  * |             Level            |   Last Value Used  |     Holes	|
  * ----------------------------------------------------------------------
- * | Module Init and Probe        |       0x014f       | 0x4b,0xba,0xfa |
+ * | Module Init and Probe        |       0x0151       | 0x4b,0xba,0xfa |
  * | Mailbox commands             |       0x117a       | 0x111a-0x111b  |
  * |                              |                    | 0x1155-0x1158  |
  * | Device Discovery             |       0x2095       | 0x2020-0x2022, |
@@ -42,7 +42,15 @@
  * |                              |                    | 0x800b,0x8039  |
  * | AER/EEH                      |       0x9011       |		|
  * | Virtual Port                 |       0xa007       |		|
- * | ISP82XX Specific             |       0xb086       | 0xb002,0xb024  |
+ * | ISP82XX Specific             |       0xb14c       | 0xb002,0xb024  |
+ * |                              |                    | 0xb09e,0xb0ae  |
+ * |                              |                    | 0xb0e0-0xb0ef  |
+ * |                              |                    | 0xb085,0xb0dc  |
+ * |                              |                    | 0xb107,0xb108  |
+ * |                              |                    | 0xb111,0xb11e  |
+ * |                              |                    | 0xb12c,0xb12d  |
+ * |                              |                    | 0xb13a,0xb142  |
+ * |                              |                    | 0xb13c-0xb140  |
  * | MultiQ                       |       0xc00c       |		|
  * | Misc                         |       0xd010       |		|
  * | Target Mode		  |	  0xe070       |		|
@@ -941,7 +949,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 	uint32_t	*last_chain = NULL;
 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return;
 
 	risc_address = ext_mem_cnt = 0;
@@ -2530,7 +2538,7 @@ ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id)
 	if (!ql_mask_match(level))
 		return;
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		mbx_reg = &reg82->mailbox_in[0];
 	else if (IS_FWI2_CAPABLE(ha))
 		mbx_reg = &reg24->mailbox0;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 95ca32a..c0a1a71 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -35,6 +35,7 @@
 
 #include "qla_bsg.h"
 #include "qla_nx.h"
+#include "qla_nx2.h"
 #define QLA2XXX_DRIVER_NAME	"qla2xxx"
 #define QLA2XXX_APIDEV		"ql2xapidev"
 #define QLA2XXX_MANUFACTURER	"QLogic Corporation"
@@ -2935,7 +2936,8 @@ struct qla_hw_data {
 #define DT_ISP2031			BIT_15
 #define DT_ISP8031			BIT_16
 #define DT_ISPFX00			BIT_17
-#define DT_ISP_LAST			(DT_ISPFX00 << 1)
+#define DT_ISP8044			BIT_18
+#define DT_ISP_LAST			(DT_ISP8044 << 1)
 
 #define DT_T10_PI                       BIT_25
 #define DT_IIDMA                        BIT_26
@@ -2961,6 +2963,7 @@ struct qla_hw_data {
 #define IS_QLA8001(ha)	(DT_MASK(ha) & DT_ISP8001)
 #define IS_QLA81XX(ha)	(IS_QLA8001(ha))
 #define IS_QLA82XX(ha)	(DT_MASK(ha) & DT_ISP8021)
+#define IS_QLA8044(ha)  (DT_MASK(ha) & DT_ISP8044)
 #define IS_QLA2031(ha)	(DT_MASK(ha) & DT_ISP2031)
 #define IS_QLA8031(ha)	(DT_MASK(ha) & DT_ISP8031)
 #define IS_QLAFX00(ha)	(DT_MASK(ha) & DT_ISPFX00)
@@ -2975,10 +2978,12 @@ struct qla_hw_data {
 #define IS_QLA24XX_TYPE(ha)     (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
 				IS_QLA84XX(ha))
 #define IS_CNA_CAPABLE(ha)	(IS_QLA81XX(ha) || IS_QLA82XX(ha) || \
-				IS_QLA8031(ha))
+				IS_QLA8031(ha) || IS_QLA8044(ha))
+#define IS_P3P_TYPE(ha)		(IS_QLA82XX(ha) || IS_QLA8044(ha))
 #define IS_QLA2XXX_MIDTYPE(ha)	(IS_QLA24XX(ha) || IS_QLA84XX(ha) || \
 				IS_QLA25XX(ha) || IS_QLA81XX(ha) || \
-				IS_QLA82XX(ha) || IS_QLA83XX(ha))
+				IS_QLA82XX(ha) || IS_QLA83XX(ha) || \
+				IS_QLA8044(ha))
 #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha))
 #define IS_NOPOLLING_TYPE(ha)	((IS_QLA25XX(ha) || IS_QLA81XX(ha) || \
 			IS_QLA83XX(ha)) && (ha)->flags.msix_enabled)
@@ -3187,10 +3192,12 @@ struct qla_hw_data {
 	uint32_t	nvram_data_off;
 
 	uint32_t	fdt_wrt_disable;
+	uint32_t	fdt_wrt_enable;
 	uint32_t	fdt_erase_cmd;
 	uint32_t	fdt_block_size;
 	uint32_t	fdt_unprotect_sec_cmd;
 	uint32_t	fdt_protect_sec_cmd;
+	uint32_t	fdt_wrt_sts_reg_cmd;
 
 	uint32_t        flt_region_flt;
 	uint32_t        flt_region_fdt;
@@ -3402,7 +3409,7 @@ typedef struct scsi_qla_host {
 	uint16_t	fcoe_fcf_idx;
 	uint8_t		fcoe_vn_port_mac[6];
 
-	uint32_t   	vp_abort_cnt;
+	uint32_t	vp_abort_cnt;
 
 	struct fc_vport	*fc_vport;	/* holds fc_vport * for each vport */
 	uint16_t        vp_idx;		/* vport ID */
@@ -3435,6 +3442,7 @@ typedef struct scsi_qla_host {
 	struct bidi_statistics bidi_stats;
 
 	atomic_t	vref_count;
+	struct qla8044_reset_template reset_tmplt;
 } scsi_qla_host_t;
 
 #define SET_VP_IDX	1
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 1ac2b0e..610d3aa 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1387,6 +1387,8 @@ struct qla_flt_header {
 #define FLT_REG_GOLD_FW		0x2f
 #define FLT_REG_FCP_PRIO_0	0x87
 #define FLT_REG_FCP_PRIO_1	0x88
+#define FLT_REG_CNA_FW		0x97
+#define FLT_REG_BOOT_CODE_8044	0xA2
 #define FLT_REG_FCOE_FW		0xA4
 #define FLT_REG_FCOE_NVRAM_0	0xAA
 #define FLT_REG_FCOE_NVRAM_1	0xAC
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 2d98232..152e5dd 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -475,9 +475,13 @@ extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
     uint32_t, uint32_t);
 extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
     uint32_t, uint32_t);
+extern uint8_t *qla8044_read_optrom_data(struct scsi_qla_host *,
+    uint8_t *, uint32_t, uint32_t);
+extern void qla8044_watchdog(struct scsi_qla_host *vha);
 
 extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
 extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
+extern int qla82xx_get_flash_version(scsi_qla_host_t *, void *);
 
 extern int qla2xxx_get_flash_info(scsi_qla_host_t *);
 extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
@@ -695,5 +699,31 @@ extern void qla82xx_md_free(scsi_qla_host_t *);
 extern int qla82xx_md_collect(scsi_qla_host_t *);
 extern void qla82xx_md_prep(scsi_qla_host_t *);
 extern void qla82xx_set_reset_owner(scsi_qla_host_t *);
+extern int qla82xx_validate_template_chksum(scsi_qla_host_t *vha);
+
+/* Function declarations for ISP8044 */
+extern int qla8044_idc_lock(struct qla_hw_data *ha);
+extern void qla8044_idc_unlock(struct qla_hw_data *ha);
+extern uint32_t qla8044_rd_reg(struct qla_hw_data *ha, ulong addr);
+extern void qla8044_wr_reg(struct qla_hw_data *ha, ulong addr, uint32_t val);
+extern void qla8044_read_reset_template(struct scsi_qla_host *ha);
+extern void qla8044_set_idc_dontreset(struct scsi_qla_host *ha);
+extern int qla8044_rd_direct(struct scsi_qla_host *vha, const uint32_t crb_reg);
+extern void qla8044_wr_direct(struct scsi_qla_host *vha,
+    const uint32_t crb_reg, const uint32_t value);
+extern inline void qla8044_set_qsnt_ready(struct scsi_qla_host *vha);
+extern inline void qla8044_need_reset_handler(struct scsi_qla_host *vha);
+extern int qla8044_device_state_handler(struct scsi_qla_host *vha);
+extern void qla8044_clear_qsnt_ready(struct scsi_qla_host *vha);
+extern void qla8044_clear_drv_active(struct scsi_qla_host *vha);
+void qla8044_get_minidump(struct scsi_qla_host *vha);
+int qla8044_collect_md_data(struct scsi_qla_host *vha);
+extern int qla8044_md_get_template(scsi_qla_host_t *);
+extern int qla8044_write_optrom_data(struct scsi_qla_host *, uint8_t *,
+    uint32_t, uint32_t);
+extern irqreturn_t qla8044_intr_handler(int, void *);
+extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t);
+extern int qla8044_abort_isp(scsi_qla_host_t *);
+extern int qla8044_check_fw_alive(struct scsi_qla_host *);
 
 #endif /* _QLA_GBL_H */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index d60e2c1..a92b166a 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -552,7 +552,18 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
 	if (rval) {
 		ql_log(ql_log_fatal, vha, 0x004f,
 		    "Unable to validate FLASH data.\n");
-		return (rval);
+		return rval;
+	}
+
+	if (IS_QLA8044(ha)) {
+		qla8044_read_reset_template(vha);
+
+		/* NOTE: If ql2xdontresethba==1, set IDC_CTRL DONTRESET_BIT0.
+		 * If DONRESET_BIT0 is set, drivers should not set dev_state
+		 * to NEED_RESET. But if NEED_RESET is set, drivers should
+		 * should honor the reset. */
+		if (ql2xdontresethba == 1)
+			qla8044_set_idc_dontreset(vha);
 	}
 
 	ha->isp_ops->get_flash_version(vha, req->ring);
@@ -1327,7 +1338,7 @@ qla24xx_chip_diag(scsi_qla_host_t *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req = ha->req_q_map[0];
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return QLA_SUCCESS;
 
 	ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length;
@@ -1610,7 +1621,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
 	unsigned long flags;
 	uint16_t fw_major_version;
 
-	if (IS_QLA82XX(ha)) {
+	if (IS_P3P_TYPE(ha)) {
 		rval = ha->isp_ops->load_risc(vha, &srisc_address);
 		if (rval == QLA_SUCCESS) {
 			qla2x00_stop_firmware(vha);
@@ -1646,7 +1657,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
 			if (rval == QLA_SUCCESS) {
 enable_82xx_npiv:
 				fw_major_version = ha->fw_major_version;
-				if (IS_QLA82XX(ha))
+				if (IS_P3P_TYPE(ha))
 					qla82xx_check_md_needed(vha);
 				else
 					rval = qla2x00_get_fw_version(vha);
@@ -1676,7 +1687,7 @@ enable_82xx_npiv:
 					goto failed;
 
 				if (!fw_major_version && ql2xallocfwdump
-				    && !IS_QLA82XX(ha))
+				    && !(IS_P3P_TYPE(ha)))
 					qla2x00_alloc_fw_dump(vha);
 			}
 		} else {
@@ -1844,7 +1855,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
 	int rval;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return;
 
 	/* Update Serial Link options. */
@@ -3993,10 +4004,18 @@ qla83xx_reset_ownership(scsi_qla_host_t *vha)
 	uint32_t class_type_mask = 0x3;
 	uint16_t fcoe_other_function = 0xffff, i;
 
-	qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
-
-	qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO1, &dev_part_info1);
-	qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO2, &dev_part_info2);
+	if (IS_QLA8044(ha)) {
+		drv_presence = qla8044_rd_direct(vha,
+		    QLA8044_CRB_DRV_ACTIVE_INDEX);
+		dev_part_info1 = qla8044_rd_direct(vha,
+		    QLA8044_CRB_DEV_PART_INFO_INDEX);
+		dev_part_info2 = qla8044_rd_direct(vha,
+		    QLA8044_CRB_DEV_PART_INFO2);
+	} else {
+		qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
+		qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO1, &dev_part_info1);
+		qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO2, &dev_part_info2);
+	}
 	for (i = 0; i < 8; i++) {
 		class_type = ((dev_part_info1 >> (i * 4)) & class_type_mask);
 		if ((class_type == QLA83XX_CLASS_TYPE_FCOE) &&
@@ -4333,7 +4352,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
 	/* For ISP82XX, driver waits for completion of the commands.
 	 * online flag should be set.
 	 */
-	if (!IS_QLA82XX(ha))
+	if (!(IS_P3P_TYPE(ha)))
 		vha->flags.online = 0;
 	ha->flags.chip_reset_done = 0;
 	clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -4346,7 +4365,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
 	 * Driver waits for the completion of the commands.
 	 * the interrupts need to be enabled.
 	 */
-	if (!IS_QLA82XX(ha))
+	if (!(IS_P3P_TYPE(ha)))
 		ha->isp_ops->reset_chip(vha);
 
 	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
@@ -4389,7 +4408,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
 
 	if (!ha->flags.eeh_busy) {
 		/* Make sure for ISP 82XX IO DMA is complete */
-		if (IS_QLA82XX(ha)) {
+		if (IS_P3P_TYPE(ha)) {
 			qla82xx_chip_reset_cleanup(vha);
 			ql_log(ql_log_info, vha, 0x00b4,
 			    "Done chip reset cleanup.\n");
@@ -4709,7 +4728,7 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return;
 
 	vha->flags.online = 0;
@@ -4775,8 +4794,6 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
 	}
 	ha->nvram_size = sizeof(struct nvram_24xx);
 	ha->vpd_size = FA_NVRAM_VPD_SIZE;
-	if (IS_QLA82XX(ha))
-		ha->vpd_size = FA_VPD_SIZE_82XX;
 
 	/* Get VPD data into cache */
 	ha->vpd = ha->nvram + VPD_OFFSET;
@@ -5538,6 +5555,8 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
 	/* Determine NVRAM starting address. */
 	ha->nvram_size = sizeof(struct nvram_81xx);
 	ha->vpd_size = FA_NVRAM_VPD_SIZE;
+	if (IS_P3P_TYPE(ha) || IS_QLA8031(ha))
+		ha->vpd_size = FA_VPD_SIZE_82XX;
 
 	/* Get VPD data into cache */
 	ha->vpd = ha->nvram + VPD_OFFSET;
@@ -5720,7 +5739,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
 
 	/* Link Down Timeout = 0:
 	 *
-	 * 	When Port Down timer expires we will start returning
+	 *	When Port Down timer expires we will start returning
 	 *	I/O's to OS with "DID_NO_CONNECT".
 	 *
 	 * Link Down Timeout != 0:
@@ -6047,7 +6066,7 @@ qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport)
 	if (priority < 0)
 		return QLA_FUNCTION_FAILED;
 
-	if (IS_QLA82XX(vha->hw)) {
+	if (IS_P3P_TYPE(vha->hw)) {
 		fcport->fcp_prio = priority & 0xf;
 		return QLA_SUCCESS;
 	}
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 28c38b4..957088b 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -59,7 +59,7 @@ qla2x00_poll(struct rsp_que *rsp)
 	unsigned long flags;
 	struct qla_hw_data *ha = rsp->hw;
 	local_irq_save(flags);
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		qla82xx_poll(0, rsp);
 	else
 		ha->isp_ops->intr_handler(0, rsp);
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index ef0a548..e2a7d2d 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -474,7 +474,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
 	struct qla_hw_data *ha = vha->hw;
 	device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
 
-	if (IS_QLA82XX(ha)) {
+	if (IS_P3P_TYPE(ha)) {
 		qla82xx_start_iocbs(vha);
 	} else {
 		/* Adjust ring index. */
@@ -1844,7 +1844,7 @@ skip_cmd_array:
 	if (req->cnt < req_cnt) {
 		if (ha->mqenable || IS_QLA83XX(ha))
 			cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
-		else if (IS_QLA82XX(ha))
+		else if (IS_P3P_TYPE(ha))
 			cnt = RD_REG_DWORD(&reg->isp82.req_q_out);
 		else if (IS_FWI2_CAPABLE(ha))
 			cnt = RD_REG_DWORD(&reg->isp24.req_q_out);
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index e779506..b4fb8a6 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -691,7 +691,8 @@ skip_rio:
 	case MBA_LOOP_DOWN:		/* Loop Down Event */
 		mbx = (IS_QLA81XX(ha) || IS_QLA8031(ha))
 			? RD_REG_WORD(&reg24->mailbox4) : 0;
-		mbx = IS_QLA82XX(ha) ? RD_REG_WORD(&reg82->mailbox_out[4]) : mbx;
+		mbx = (IS_P3P_TYPE(ha)) ? RD_REG_WORD(&reg82->mailbox_out[4])
+			: mbx;
 		ql_dbg(ql_dbg_async, vha, 0x500b,
 		    "LOOP DOWN detected (%x %x %x %x).\n",
 		    mb[1], mb[2], mb[3], mbx);
@@ -740,7 +741,7 @@ skip_rio:
 		if (IS_QLA2100(ha))
 			break;
 
-		if (IS_QLA81XX(ha) || IS_QLA82XX(ha) || IS_QLA8031(ha)) {
+		if (IS_CNA_CAPABLE(ha)) {
 			ql_dbg(ql_dbg_async, vha, 0x500d,
 			    "DCBX Completed -- %04x %04x %04x.\n",
 			    mb[1], mb[2], mb[3]);
@@ -1002,7 +1003,7 @@ skip_rio:
 		    mb[1], mb[2], mb[3]);
 		break;
 	case MBA_IDC_NOTIFY:
-		if (IS_QLA8031(vha->hw)) {
+		if (IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
 			mb[4] = RD_REG_WORD(&reg24->mailbox4);
 			if (((mb[2] & 0x7fff) == MBC_PORT_RESET ||
 			    (mb[2] & 0x7fff) == MBC_SET_PORT_CONFIG) &&
@@ -1022,7 +1023,8 @@ skip_rio:
 			complete(&ha->lb_portup_comp);
 		/* Fallthru */
 	case MBA_IDC_TIME_EXT:
-		if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw))
+		if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) ||
+		    IS_QLA8044(ha))
 			qla81xx_idc_event(vha, mb[0], mb[1]);
 		break;
 
@@ -1063,7 +1065,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
 		ql_log(ql_log_warn, vha, 0x3014,
 		    "Invalid SCSI command index (%x).\n", index);
 
-		if (IS_QLA82XX(ha))
+		if (IS_P3P_TYPE(ha))
 			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
 		else
 			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -1080,7 +1082,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
 	} else {
 		ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.\n");
 
-		if (IS_QLA82XX(ha))
+		if (IS_P3P_TYPE(ha))
 			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
 		else
 			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -1100,7 +1102,7 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
 	if (index >= req->num_outstanding_cmds) {
 		ql_log(ql_log_warn, vha, 0x5031,
 		    "Invalid command index (%x).\n", index);
-		if (IS_QLA82XX(ha))
+		if (IS_P3P_TYPE(ha))
 			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
 		else
 			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -1949,7 +1951,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 		ql_dbg(ql_dbg_io, vha, 0x3017,
 		    "Invalid status handle (0x%x).\n", sts->handle);
 
-		if (IS_QLA82XX(ha))
+		if (IS_P3P_TYPE(ha))
 			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
 		else
 			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -2321,7 +2323,7 @@ fatal:
 	ql_log(ql_log_warn, vha, 0x5030,
 	    "Error entry - invalid handle/queue.\n");
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
 	else
 		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -2449,7 +2451,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
 	}
 
 	/* Adjust ring index */
-	if (IS_QLA82XX(ha)) {
+	if (IS_P3P_TYPE(ha)) {
 		struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;
 		WRT_REG_DWORD(&reg->rsp_q_out[0], rsp->ring_index);
 	} else
@@ -2862,7 +2864,7 @@ msix_failed:
 			ret = request_irq(qentry->vector,
 				qla83xx_msix_entries[i].handler,
 				0, qla83xx_msix_entries[i].name, rsp);
-		} else if (IS_QLA82XX(ha)) {
+		} else if (IS_P3P_TYPE(ha)) {
 			ret = request_irq(qentry->vector,
 				qla82xx_msix_entries[i].handler,
 				0, qla82xx_msix_entries[i].name, rsp);
@@ -2947,7 +2949,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
 skip_msix:
 
 	if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
-	    !IS_QLA8001(ha) && !IS_QLA82XX(ha) && !IS_QLAFX00(ha))
+	    !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha))
 		goto skip_msi;
 
 	ret = pci_enable_msi(ha->pdev);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 7257c3c..98e8a16 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -75,7 +75,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 		return QLA_FUNCTION_TIMEOUT;
 	}
 
-	if (IS_QLA82XX(ha) && ha->flags.isp82xx_fw_hung) {
+	if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
 		/* Setting Link-Down error */
 		mcp->mb[0] = MBS_LINK_DOWN_ERROR;
 		ql_log(ql_log_warn, vha, 0x1004,
@@ -106,9 +106,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
 	/* Load mailbox registers. */
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
-	else if (IS_FWI2_CAPABLE(ha) && !IS_QLA82XX(ha))
+	else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
 		optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
 	else
 		optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
@@ -159,7 +159,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
 		set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
 
-		if (IS_QLA82XX(ha)) {
+		if (IS_P3P_TYPE(ha)) {
 			if (RD_REG_DWORD(&reg->isp82.hint) &
 				HINT_MBX_INT_PENDING) {
 				spin_unlock_irqrestore(&ha->hardware_lock,
@@ -189,7 +189,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 		ql_dbg(ql_dbg_mbx, vha, 0x1011,
 		    "Cmd=%x Polling Mode.\n", command);
 
-		if (IS_QLA82XX(ha)) {
+		if (IS_P3P_TYPE(ha)) {
 			if (RD_REG_DWORD(&reg->isp82.hint) &
 				HINT_MBX_INT_PENDING) {
 				spin_unlock_irqrestore(&ha->hardware_lock,
@@ -236,7 +236,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 		ha->flags.mbox_int = 0;
 		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 
-		if ((IS_QLA82XX(ha) && ha->flags.isp82xx_fw_hung)) {
+		if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
 			ha->flags.mbox_busy = 0;
 			/* Setting Link-Down error */
 			mcp->mb[0] = MBS_LINK_DOWN_ERROR;
@@ -537,7 +537,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
 	mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
 	mcp->out_mb = MBX_0;
 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
-	if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha))
+	if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
 		mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
 	if (IS_FWI2_CAPABLE(ha))
 		mcp->in_mb |= MBX_17|MBX_16|MBX_15;
@@ -556,7 +556,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
 		ha->fw_memory_size = 0x1FFFF;		/* Defaults to 128KB. */
 	else
 		ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
-	if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw)) {
+	if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
 		ha->mpi_version[0] = mcp->mb[10] & 0xff;
 		ha->mpi_version[1] = mcp->mb[11] >> 8;
 		ha->mpi_version[2] = mcp->mb[11] & 0xff;
@@ -1201,7 +1201,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
 	    "Entered %s.\n", __func__);
 
-	if (IS_QLA82XX(ha) && ql2xdbwr)
+	if (IS_P3P_TYPE(ha) && ql2xdbwr)
 		qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
 			(0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
 
@@ -4407,7 +4407,7 @@ qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
 	    "Entered %s.\n", __func__);
 
-	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha))
 		return QLA_FUNCTION_FAILED;
 	mcp->mb[0] = MBC_GET_PORT_CONFIG;
 	mcp->out_mb = MBX_0;
@@ -4595,7 +4595,7 @@ qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
 	    "Entered %s.\n", __func__);
 
-	if (!IS_QLA82XX(ha))
+	if (!IS_P3P_TYPE(ha))
 		return QLA_FUNCTION_FAILED;
 
 	memset(mcp, 0, sizeof(mbx_cmd_t));
@@ -4713,6 +4713,60 @@ qla82xx_md_get_template(scsi_qla_host_t *vha)
 }
 
 int
+qla8044_md_get_template(scsi_qla_host_t *vha)
+{
+	struct qla_hw_data *ha = vha->hw;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+	int rval = QLA_FUNCTION_FAILED;
+	int offset = 0, size = MINIDUMP_SIZE_36K;
+	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
+	    "Entered %s.\n", __func__);
+
+	ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
+	   ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
+	if (!ha->md_tmplt_hdr) {
+		ql_log(ql_log_warn, vha, 0xb11b,
+		    "Unable to allocate memory for Minidump template.\n");
+		return rval;
+	}
+
+	memset(mcp->mb, 0 , sizeof(mcp->mb));
+	while (offset < ha->md_template_size) {
+		mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
+		mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
+		mcp->mb[2] = LSW(RQST_TMPLT);
+		mcp->mb[3] = MSW(RQST_TMPLT);
+		mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
+		mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
+		mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
+		mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
+		mcp->mb[8] = LSW(size);
+		mcp->mb[9] = MSW(size);
+		mcp->mb[10] = offset & 0x0000FFFF;
+		mcp->mb[11] = offset & 0xFFFF0000;
+		mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
+		mcp->tov = MBX_TOV_SECONDS;
+		mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
+			MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+		mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
+		rval = qla2x00_mailbox_command(vha, mcp);
+
+		if (rval != QLA_SUCCESS) {
+			ql_dbg(ql_dbg_mbx, vha, 0xb11c,
+				"mailbox command FAILED=0x%x, subcode=%x.\n",
+				((mcp->mb[1] << 16) | mcp->mb[0]),
+				((mcp->mb[3] << 16) | mcp->mb[2]));
+			return rval;
+		} else
+			ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
+				"Done %s.\n", __func__);
+		offset = offset + size;
+	}
+	return rval;
+}
+
+int
 qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
 {
 	int rval;
@@ -4808,7 +4862,7 @@ qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
 
-	if (!IS_QLA82XX(ha))
+	if (!IS_P3P_TYPE(ha))
 		return QLA_FUNCTION_FAILED;
 
 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index cce0cd0..01b72e0 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -848,7 +848,6 @@ qla82xx_rom_lock(struct qla_hw_data *ha)
 {
 	int done = 0, timeout = 0;
 	uint32_t lock_owner = 0;
-	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 
 	while (!done) {
 		/* acquire semaphore2 from PCI HW block */
@@ -857,9 +856,6 @@ qla82xx_rom_lock(struct qla_hw_data *ha)
 			break;
 		if (timeout >= qla82xx_rom_lock_timeout) {
 			lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);
-			ql_dbg(ql_dbg_p3p, vha, 0xb085,
-			    "Failed to acquire rom lock, acquired by %d.\n",
-			    lock_owner);
 			return -1;
 		}
 		timeout++;
@@ -1666,8 +1662,14 @@ qla82xx_iospace_config(struct qla_hw_data *ha)
 	}
 
 	/* Mapping of IO base pointer */
-	ha->iobase = (device_reg_t __iomem *)((uint8_t *)ha->nx_pcibase +
-	    0xbc000 + (ha->pdev->devfn << 11));
+	if (IS_QLA8044(ha)) {
+		ha->iobase =
+		    (device_reg_t __iomem *)((uint8_t *)ha->nx_pcibase);
+	} else if (IS_QLA82XX(ha)) {
+		ha->iobase =
+		    (device_reg_t __iomem *)((uint8_t *)ha->nx_pcibase +
+			0xbc000 + (ha->pdev->devfn << 11));
+	}
 
 	if (!ql2xdbwr) {
 		ha->nxdb_wr_ptr =
@@ -1967,7 +1969,7 @@ static struct qla82xx_legacy_intr_set legacy_intr[] = \
  * @ha: SCSI driver HA context
  * @mb0: Mailbox0 register
  */
-static void
+void
 qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
 {
 	uint16_t	cnt;
@@ -2247,7 +2249,10 @@ qla82xx_enable_intrs(struct qla_hw_data *ha)
 	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 	qla82xx_mbx_intr_enable(vha);
 	spin_lock_irq(&ha->hardware_lock);
-	qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
+	if (IS_QLA8044(ha))
+		qla8044_wr_reg(ha, LEG_INTR_MASK_OFFSET, 0);
+	else
+		qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
 	spin_unlock_irq(&ha->hardware_lock);
 	ha->interrupts_on = 1;
 }
@@ -2258,7 +2263,10 @@ qla82xx_disable_intrs(struct qla_hw_data *ha)
 	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 	qla82xx_mbx_intr_disable(vha);
 	spin_lock_irq(&ha->hardware_lock);
-	qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
+	if (IS_QLA8044(ha))
+		qla8044_wr_reg(ha, LEG_INTR_MASK_OFFSET, 1);
+	else
+		qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
 	spin_unlock_irq(&ha->hardware_lock);
 	ha->interrupts_on = 0;
 }
@@ -3008,6 +3016,9 @@ qla8xxx_dev_failed_handler(scsi_qla_host_t *vha)
 	if (IS_QLA82XX(ha)) {
 		qla82xx_clear_drv_active(ha);
 		qla82xx_idc_unlock(ha);
+	} else if (IS_QLA8044(ha)) {
+		qla8044_clear_drv_active(vha);
+		qla8044_idc_unlock(ha);
 	}
 
 	/* Set DEV_FAILED flag to disable timer */
@@ -3134,7 +3145,7 @@ qla82xx_check_md_needed(scsi_qla_host_t *vha)
 			if (fw_major_version != ha->fw_major_version ||
 			    fw_minor_version != ha->fw_minor_version ||
 			    fw_subminor_version != ha->fw_subminor_version) {
-				ql_log(ql_log_info, vha, 0xb02d,
+				ql_dbg(ql_dbg_p3p, vha, 0xb02d,
 				    "Firmware version differs "
 				    "Previous version: %d:%d:%d - "
 				    "New version: %d:%d:%d\n",
@@ -3423,8 +3434,18 @@ void qla82xx_watchdog(scsi_qla_host_t *vha)
 
 int qla82xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
 {
-	int rval;
-	rval = qla82xx_device_state_handler(vha);
+	int rval = -1;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (IS_QLA82XX(ha))
+		rval = qla82xx_device_state_handler(vha);
+	else if (IS_QLA8044(ha)) {
+		qla8044_idc_lock(ha);
+		/* Decide the reset ownership */
+		qla83xx_reset_ownership(vha);
+		qla8044_idc_unlock(ha);
+		rval = qla8044_device_state_handler(vha);
+	}
 	return rval;
 }
 
@@ -3432,17 +3453,25 @@ void
 qla82xx_set_reset_owner(scsi_qla_host_t *vha)
 {
 	struct qla_hw_data *ha = vha->hw;
-	uint32_t dev_state;
+	uint32_t dev_state = 0;
+
+	if (IS_QLA82XX(ha))
+		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+	else if (IS_QLA8044(ha))
+		dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
 
-	dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
 	if (dev_state == QLA8XXX_DEV_READY) {
 		ql_log(ql_log_info, vha, 0xb02f,
 		    "HW State: NEED RESET\n");
-		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-			QLA8XXX_DEV_NEED_RESET);
-		ha->flags.nic_core_reset_owner = 1;
-		ql_dbg(ql_dbg_p3p, vha, 0xb030,
-		    "reset_owner is 0x%x\n", ha->portnum);
+		if (IS_QLA82XX(ha)) {
+			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
+			    QLA8XXX_DEV_NEED_RESET);
+			ha->flags.nic_core_reset_owner = 1;
+			ql_dbg(ql_dbg_p3p, vha, 0xb030,
+			    "reset_owner is 0x%x\n", ha->portnum);
+		} else if (IS_QLA8044(ha))
+			qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
+			    QLA8XXX_DEV_NEED_RESET);
 	} else
 		ql_log(ql_log_info, vha, 0xb031,
 		    "Device state is 0x%x = %s.\n",
@@ -3463,7 +3492,7 @@ qla82xx_set_reset_owner(scsi_qla_host_t *vha)
 int
 qla82xx_abort_isp(scsi_qla_host_t *vha)
 {
-	int rval;
+	int rval = -1;
 	struct qla_hw_data *ha = vha->hw;
 
 	if (vha->device_flags & DFLG_DEV_FAILED) {
@@ -3477,7 +3506,15 @@ qla82xx_abort_isp(scsi_qla_host_t *vha)
 	qla82xx_set_reset_owner(vha);
 	qla82xx_idc_unlock(ha);
 
-	rval = qla82xx_device_state_handler(vha);
+	if (IS_QLA82XX(ha))
+		rval = qla82xx_device_state_handler(vha);
+	else if (IS_QLA8044(ha)) {
+		qla8044_idc_lock(ha);
+		/* Decide the reset ownership */
+		qla83xx_reset_ownership(vha);
+		qla8044_idc_unlock(ha);
+		rval = qla8044_device_state_handler(vha);
+	}
 
 	qla82xx_idc_lock(ha);
 	qla82xx_clear_rst_ready(ha);
@@ -3597,7 +3634,7 @@ int qla2x00_wait_for_fcoe_ctx_reset(scsi_qla_host_t *vha)
 void
 qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
 {
-	int i;
+	int i, fw_state = 0;
 	unsigned long flags;
 	struct qla_hw_data *ha = vha->hw;
 
@@ -3608,7 +3645,11 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
 	if (!ha->flags.isp82xx_fw_hung) {
 		for (i = 0; i < 2; i++) {
 			msleep(1000);
-			if (qla82xx_check_fw_alive(vha)) {
+			if (IS_QLA82XX(ha))
+				fw_state = qla82xx_check_fw_alive(vha);
+			else if (IS_QLA8044(ha))
+				fw_state = qla8044_check_fw_alive(vha);
+			if (fw_state) {
 				ha->flags.isp82xx_fw_hung = 1;
 				qla82xx_clear_pending_mbx(vha);
 				break;
@@ -4072,7 +4113,7 @@ qla82xx_minidump_process_rdmem(scsi_qla_host_t *vha,
 	return QLA_SUCCESS;
 }
 
-static int
+int
 qla82xx_validate_template_chksum(scsi_qla_host_t *vha)
 {
 	struct qla_hw_data *ha = vha->hw;
@@ -4384,7 +4425,11 @@ qla82xx_md_prep(scsi_qla_host_t *vha)
 		    ha->md_template_size / 1024);
 
 		/* Get Minidump template */
-		rval = qla82xx_md_get_template(vha);
+		if (IS_QLA8044(ha))
+			rval = qla8044_md_get_template(vha);
+		else
+			rval = qla82xx_md_get_template(vha);
+
 		if (rval == QLA_SUCCESS) {
 			ql_dbg(ql_dbg_p3p, vha, 0xb04b,
 			    "MiniDump Template obtained\n");
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h
index d268e84..1bb93db 100644
--- a/drivers/scsi/qla2xxx/qla_nx.h
+++ b/drivers/scsi/qla2xxx/qla_nx.h
@@ -589,6 +589,7 @@
  * The PCI VendorID and DeviceID for our board.
  */
 #define PCI_DEVICE_ID_QLOGIC_ISP8021		0x8021
+#define PCI_DEVICE_ID_QLOGIC_ISP8044		0x8044
 
 #define QLA82XX_MSIX_TBL_SPACE			8192
 #define QLA82XX_PCI_REG_MSIX_TBL		0x44
@@ -954,6 +955,11 @@ struct ct6_dsd {
 #define QLA82XX_CNTRL                  98
 #define QLA82XX_TLHDR                  99
 #define QLA82XX_RDEND                  255
+#define QLA8044_POLLRD			35
+#define QLA8044_RDMUX2			36
+#define QLA8044_L1DTG			8
+#define QLA8044_L1ITG			9
+#define QLA8044_POLLRDMWR		37
 
 /*
  * Opcodes for Control Entries.
@@ -1191,4 +1197,8 @@ enum {
 	QLA82XX_TEMP_WARN,	   /* Sound alert, temperature getting high */
 	QLA82XX_TEMP_PANIC	   /* Fatal error, hardware has shut down. */
 };
+
+#define LEG_INTR_PTR_OFFSET	0x38C0
+#define LEG_INTR_TRIG_OFFSET	0x38C4
+#define LEG_INTR_MASK_OFFSET	0x38C8
 #endif
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c
new file mode 100644
index 0000000..005cd6b
--- /dev/null
+++ b/drivers/scsi/qla2xxx/qla_nx2.c
@@ -0,0 +1,3708 @@
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2013 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
+
+#include <linux/vmalloc.h>
+
+#include "qla_def.h"
+#include "qla_gbl.h"
+
+#include <linux/delay.h>
+
+/* 8044 Flash Read/Write functions */
+uint32_t
+qla8044_rd_reg(struct qla_hw_data *ha, ulong addr)
+{
+	return readl((void __iomem *) (ha->nx_pcibase + addr));
+}
+
+void
+qla8044_wr_reg(struct qla_hw_data *ha, ulong addr, uint32_t val)
+{
+	writel(val, (void __iomem *)((ha)->nx_pcibase + addr));
+}
+
+int
+qla8044_rd_direct(struct scsi_qla_host *vha,
+	const uint32_t crb_reg)
+{
+	struct qla_hw_data *ha = vha->hw;
+
+	if (crb_reg < CRB_REG_INDEX_MAX)
+		return qla8044_rd_reg(ha, qla8044_reg_tbl[crb_reg]);
+	else
+		return QLA_FUNCTION_FAILED;
+}
+
+void
+qla8044_wr_direct(struct scsi_qla_host *vha,
+	const uint32_t crb_reg,
+	const uint32_t value)
+{
+	struct qla_hw_data *ha = vha->hw;
+
+	if (crb_reg < CRB_REG_INDEX_MAX)
+		qla8044_wr_reg(ha, qla8044_reg_tbl[crb_reg], value);
+}
+
+static int
+qla8044_set_win_base(scsi_qla_host_t *vha, uint32_t addr)
+{
+	uint32_t val;
+	int ret_val = QLA_SUCCESS;
+	struct qla_hw_data *ha = vha->hw;
+
+	qla8044_wr_reg(ha, QLA8044_CRB_WIN_FUNC(ha->portnum), addr);
+	val = qla8044_rd_reg(ha, QLA8044_CRB_WIN_FUNC(ha->portnum));
+
+	if (val != addr) {
+		ql_log(ql_log_warn, vha, 0xb087,
+		    "%s: Failed to set register window : "
+		    "addr written 0x%x, read 0x%x!\n",
+		    __func__, addr, val);
+		ret_val = QLA_FUNCTION_FAILED;
+	}
+	return ret_val;
+}
+
+static int
+qla8044_rd_reg_indirect(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
+{
+	int ret_val = QLA_SUCCESS;
+	struct qla_hw_data *ha = vha->hw;
+
+	ret_val = qla8044_set_win_base(vha, addr);
+	if (!ret_val)
+		*data = qla8044_rd_reg(ha, QLA8044_WILDCARD);
+	else
+		ql_log(ql_log_warn, vha, 0xb088,
+		    "%s: failed read of addr 0x%x!\n", __func__, addr);
+	return ret_val;
+}
+
+static int
+qla8044_wr_reg_indirect(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
+{
+	int ret_val = QLA_SUCCESS;
+	struct qla_hw_data *ha = vha->hw;
+
+	ret_val = qla8044_set_win_base(vha, addr);
+	if (!ret_val)
+		qla8044_wr_reg(ha, QLA8044_WILDCARD, data);
+	else
+		ql_log(ql_log_warn, vha, 0xb089,
+		    "%s: failed wrt to addr 0x%x, data 0x%x\n",
+		    __func__, addr, data);
+	return ret_val;
+}
+
+/*
+ * qla8044_read_write_crb_reg - Read from raddr and write value to waddr.
+ *
+ * @ha : Pointer to adapter structure
+ * @raddr : CRB address to read from
+ * @waddr : CRB address to write to
+ *
+ */
+static void
+qla8044_read_write_crb_reg(struct scsi_qla_host *vha,
+	uint32_t raddr, uint32_t waddr)
+{
+	uint32_t value;
+
+	qla8044_rd_reg_indirect(vha, raddr, &value);
+	qla8044_wr_reg_indirect(vha, waddr, value);
+}
+
+/*
+ * qla8044_rmw_crb_reg - Read value from raddr, AND with test_mask,
+ * Shift Left,Right/OR/XOR with values RMW header and write value to waddr.
+ *
+ * @vha : Pointer to adapter structure
+ * @raddr : CRB address to read from
+ * @waddr : CRB address to write to
+ * @p_rmw_hdr : header with shift/or/xor values.
+ *
+ */
+static void
+qla8044_rmw_crb_reg(struct scsi_qla_host *vha,
+	uint32_t raddr, uint32_t waddr,	struct qla8044_rmw *p_rmw_hdr)
+{
+	uint32_t value;
+
+	if (p_rmw_hdr->index_a)
+		value = vha->reset_tmplt.array[p_rmw_hdr->index_a];
+	else
+		qla8044_rd_reg_indirect(vha, raddr, &value);
+	value &= p_rmw_hdr->test_mask;
+	value <<= p_rmw_hdr->shl;
+	value >>= p_rmw_hdr->shr;
+	value |= p_rmw_hdr->or_value;
+	value ^= p_rmw_hdr->xor_value;
+	qla8044_wr_reg_indirect(vha, waddr, value);
+	return;
+}
+
+inline void
+qla8044_set_qsnt_ready(struct scsi_qla_host *vha)
+{
+	uint32_t qsnt_state;
+	struct qla_hw_data *ha = vha->hw;
+
+	qsnt_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
+	qsnt_state |= (1 << ha->portnum);
+	qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, qsnt_state);
+	ql_log(ql_log_info, vha, 0xb08e, "%s(%ld): qsnt_state: 0x%08x\n",
+	     __func__, vha->host_no, qsnt_state);
+}
+
+void
+qla8044_clear_qsnt_ready(struct scsi_qla_host *vha)
+{
+	uint32_t qsnt_state;
+	struct qla_hw_data *ha = vha->hw;
+
+	qsnt_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
+	qsnt_state &= ~(1 << ha->portnum);
+	qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, qsnt_state);
+	ql_log(ql_log_info, vha, 0xb08f, "%s(%ld): qsnt_state: 0x%08x\n",
+	    __func__, vha->host_no, qsnt_state);
+}
+
+/**
+ *
+ * qla8044_lock_recovery - Recovers the idc_lock.
+ * @ha : Pointer to adapter structure
+ *
+ * Lock Recovery Register
+ * 5-2	Lock recovery owner: Function ID of driver doing lock recovery,
+ *	valid if bits 1..0 are set by driver doing lock recovery.
+ * 1-0  1 - Driver intends to force unlock the IDC lock.
+ *	2 - Driver is moving forward to unlock the IDC lock. Driver clears
+ *	    this field after force unlocking the IDC lock.
+ *
+ * Lock Recovery process
+ * a. Read the IDC_LOCK_RECOVERY register. If the value in bits 1..0 is
+ *    greater than 0, then wait for the other driver to unlock otherwise
+ *    move to the next step.
+ * b. Indicate intent to force-unlock by writing 1h to the IDC_LOCK_RECOVERY
+ *    register bits 1..0 and also set the function# in bits 5..2.
+ * c. Read the IDC_LOCK_RECOVERY register again after a delay of 200ms.
+ *    Wait for the other driver to perform lock recovery if the function
+ *    number in bits 5..2 has changed, otherwise move to the next step.
+ * d. Write a value of 2h to the IDC_LOCK_RECOVERY register bits 1..0
+ *    leaving your function# in bits 5..2.
+ * e. Force unlock using the DRIVER_UNLOCK register and immediately clear
+ *    the IDC_LOCK_RECOVERY bits 5..0 by writing 0.
+ **/
+static int
+qla8044_lock_recovery(struct scsi_qla_host *vha)
+{
+	uint32_t lock = 0, lockid;
+	struct qla_hw_data *ha = vha->hw;
+
+	lockid = qla8044_rd_reg(ha, QLA8044_DRV_LOCKRECOVERY);
+
+	/* Check for other Recovery in progress, go wait */
+	if ((lockid & IDC_LOCK_RECOVERY_STATE_MASK) != 0)
+		return QLA_FUNCTION_FAILED;
+
+	/* Intent to Recover */
+	qla8044_wr_reg(ha, QLA8044_DRV_LOCKRECOVERY,
+	    (ha->portnum <<
+	     IDC_LOCK_RECOVERY_STATE_SHIFT_BITS) | INTENT_TO_RECOVER);
+	msleep(200);
+
+	/* Check Intent to Recover is advertised */
+	lockid = qla8044_rd_reg(ha, QLA8044_DRV_LOCKRECOVERY);
+	if ((lockid & IDC_LOCK_RECOVERY_OWNER_MASK) != (ha->portnum <<
+	    IDC_LOCK_RECOVERY_STATE_SHIFT_BITS))
+		return QLA_FUNCTION_FAILED;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb08B, "%s:%d: IDC Lock recovery initiated\n"
+	    , __func__, ha->portnum);
+
+	/* Proceed to Recover */
+	qla8044_wr_reg(ha, QLA8044_DRV_LOCKRECOVERY,
+	    (ha->portnum << IDC_LOCK_RECOVERY_STATE_SHIFT_BITS) |
+	    PROCEED_TO_RECOVER);
+
+	/* Force Unlock() */
+	qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, 0xFF);
+	qla8044_rd_reg(ha, QLA8044_DRV_UNLOCK);
+
+	/* Clear bits 0-5 in IDC_RECOVERY register*/
+	qla8044_wr_reg(ha, QLA8044_DRV_LOCKRECOVERY, 0);
+
+	/* Get lock() */
+	lock = qla8044_rd_reg(ha, QLA8044_DRV_LOCK);
+	if (lock) {
+		lockid = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
+		lockid = ((lockid + (1 << 8)) & ~0xFF) | ha->portnum;
+		qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, lockid);
+		return QLA_SUCCESS;
+	} else
+		return QLA_FUNCTION_FAILED;
+}
+
+int
+qla8044_idc_lock(struct qla_hw_data *ha)
+{
+	uint32_t ret_val = QLA_SUCCESS, timeout = 0, status = 0;
+	uint32_t lock_id, lock_cnt, func_num, tmo_owner = 0, first_owner = 0;
+	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
+
+	while (status == 0) {
+		/* acquire semaphore5 from PCI HW block */
+		status = qla8044_rd_reg(ha, QLA8044_DRV_LOCK);
+
+		if (status) {
+			/* Increment Counter (8-31) and update func_num (0-7) on
+			 * getting a successful lock  */
+			lock_id = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
+			lock_id = ((lock_id + (1 << 8)) & ~0xFF) | ha->portnum;
+			qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, lock_id);
+			break;
+		}
+
+		if (timeout == 0)
+			first_owner = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
+
+		if (++timeout >=
+		    (QLA8044_DRV_LOCK_TIMEOUT / QLA8044_DRV_LOCK_MSLEEP)) {
+			tmo_owner = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
+			func_num = tmo_owner & 0xFF;
+			lock_cnt = tmo_owner >> 8;
+			ql_log(ql_log_warn, vha, 0xb114,
+			    "%s: Lock by func %d failed after 2s, lock held "
+			    "by func %d, lock count %d, first_owner %d\n",
+			    __func__, ha->portnum, func_num, lock_cnt,
+			    (first_owner & 0xFF));
+			if (first_owner != tmo_owner) {
+				/* Some other driver got lock,
+				 * OR same driver got lock again (counter
+				 * value changed), when we were waiting for
+				 * lock. Retry for another 2 sec */
+				ql_dbg(ql_dbg_p3p, vha, 0xb115,
+				    "%s: %d: IDC lock failed\n",
+				    __func__, ha->portnum);
+				timeout = 0;
+			} else {
+				/* Same driver holding lock > 2sec.
+				 * Force Recovery */
+				if (qla8044_lock_recovery(vha) == QLA_SUCCESS) {
+					/* Recovered and got lock */
+					ret_val = QLA_SUCCESS;
+					ql_dbg(ql_dbg_p3p, vha, 0xb116,
+					    "%s:IDC lock Recovery by %d"
+					    "successful...\n", __func__,
+					     ha->portnum);
+				}
+				/* Recovery Failed, some other function
+				 * has the lock, wait for 2secs
+				 * and retry
+				 */
+				 ql_dbg(ql_dbg_p3p, vha, 0xb08a,
+				     "%s: IDC lock Recovery by %d "
+				     "failed, Retrying timout\n", __func__,
+				     ha->portnum);
+				 timeout = 0;
+			}
+		}
+		msleep(QLA8044_DRV_LOCK_MSLEEP);
+	}
+	return ret_val;
+}
+
+void
+qla8044_idc_unlock(struct qla_hw_data *ha)
+{
+	int id;
+	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
+
+	id = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
+
+	if ((id & 0xFF) != ha->portnum) {
+		ql_log(ql_log_warn, vha, 0xb118,
+		    "%s: IDC Unlock by %d failed, lock owner is %d!\n",
+		    __func__, ha->portnum, (id & 0xFF));
+		return;
+	}
+
+	/* Keep lock counter value, update the ha->func_num to 0xFF */
+	qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, (id | 0xFF));
+	qla8044_rd_reg(ha, QLA8044_DRV_UNLOCK);
+}
+
+/* 8044 Flash Lock/Unlock functions */
+static int
+qla8044_flash_lock(scsi_qla_host_t *vha)
+{
+	int lock_owner;
+	int timeout = 0;
+	uint32_t lock_status = 0;
+	int ret_val = QLA_SUCCESS;
+	struct qla_hw_data *ha = vha->hw;
+
+	while (lock_status == 0) {
+		lock_status = qla8044_rd_reg(ha, QLA8044_FLASH_LOCK);
+		if (lock_status)
+			break;
+
+		if (++timeout >= QLA8044_FLASH_LOCK_TIMEOUT / 20) {
+			lock_owner = qla8044_rd_reg(ha,
+			    QLA8044_FLASH_LOCK_ID);
+			ql_log(ql_log_warn, vha, 0xb113,
+			    "%s: flash lock by %d failed, held by %d\n",
+				__func__, ha->portnum, lock_owner);
+			ret_val = QLA_FUNCTION_FAILED;
+			break;
+		}
+		msleep(20);
+	}
+	qla8044_wr_reg(ha, QLA8044_FLASH_LOCK_ID, ha->portnum);
+	return ret_val;
+}
+
+static void
+qla8044_flash_unlock(scsi_qla_host_t *vha)
+{
+	int ret_val;
+	struct qla_hw_data *ha = vha->hw;
+
+	/* Reading FLASH_UNLOCK register unlocks the Flash */
+	qla8044_wr_reg(ha, QLA8044_FLASH_LOCK_ID, 0xFF);
+	ret_val = qla8044_rd_reg(ha, QLA8044_FLASH_UNLOCK);
+}
+
+
+static
+void qla8044_flash_lock_recovery(struct scsi_qla_host *vha)
+{
+
+	if (qla8044_flash_lock(vha)) {
+		/* Someone else is holding the lock. */
+		ql_log(ql_log_warn, vha, 0xb120, "Resetting flash_lock\n");
+	}
+
+	/*
+	 * Either we got the lock, or someone
+	 * else died while holding it.
+	 * In either case, unlock.
+	 */
+	qla8044_flash_unlock(vha);
+}
+
+/*
+ * Address and length are byte address
+ */
+static int
+qla8044_read_flash_data(scsi_qla_host_t *vha,  uint8_t *p_data,
+	uint32_t flash_addr, int u32_word_count)
+{
+	int i, ret_val = QLA_SUCCESS;
+	uint32_t u32_word;
+
+	if (qla8044_flash_lock(vha) != QLA_SUCCESS) {
+		ret_val = QLA_FUNCTION_FAILED;
+		goto exit_lock_error;
+	}
+
+	if (flash_addr & 0x03) {
+		ql_log(ql_log_warn, vha, 0xb117,
+		    "%s: Illegal addr = 0x%x\n", __func__, flash_addr);
+		ret_val = QLA_FUNCTION_FAILED;
+		goto exit_flash_read;
+	}
+
+	for (i = 0; i < u32_word_count; i++) {
+		if (qla8044_wr_reg_indirect(vha, QLA8044_FLASH_DIRECT_WINDOW,
+		    (flash_addr & 0xFFFF0000))) {
+			ql_log(ql_log_warn, vha, 0xb119,
+			    "%s: failed to write addr 0x%x to "
+			    "FLASH_DIRECT_WINDOW\n! ",
+			    __func__, flash_addr);
+			ret_val = QLA_FUNCTION_FAILED;
+			goto exit_flash_read;
+		}
+
+		ret_val = qla8044_rd_reg_indirect(vha,
+		    QLA8044_FLASH_DIRECT_DATA(flash_addr),
+		    &u32_word);
+		if (ret_val != QLA_SUCCESS) {
+			ql_log(ql_log_warn, vha, 0xb08c,
+			    "%s: failed to read addr 0x%x!\n",
+			    __func__, flash_addr);
+			goto exit_flash_read;
+		}
+
+		*(uint32_t *)p_data = u32_word;
+		p_data = p_data + 4;
+		flash_addr = flash_addr + 4;
+	}
+
+exit_flash_read:
+	qla8044_flash_unlock(vha);
+
+exit_lock_error:
+	return ret_val;
+}
+
+/*
+ * Address and length are byte address
+ */
+uint8_t *
+qla8044_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
+	uint32_t offset, uint32_t length)
+{
+	scsi_block_requests(vha->host);
+	if (qla8044_read_flash_data(vha, (uint8_t *)buf, offset, length / 4)
+	    != QLA_SUCCESS) {
+		ql_log(ql_log_warn, vha,  0xb08d,
+		    "%s: Failed to read from flash\n",
+		    __func__);
+	}
+	scsi_unblock_requests(vha->host);
+	return buf;
+}
+
+inline int
+qla8044_need_reset(struct scsi_qla_host *vha)
+{
+	uint32_t drv_state, drv_active;
+	int rval;
+	struct qla_hw_data *ha = vha->hw;
+
+	drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
+	drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
+
+	rval = drv_state & (1 << ha->portnum);
+
+	if (ha->flags.eeh_busy && drv_active)
+		rval = 1;
+	return rval;
+}
+
+/*
+ * qla8044_write_list - Write the value (p_entry->arg2) to address specified
+ * by p_entry->arg1 for all entries in header with delay of p_hdr->delay between
+ * entries.
+ *
+ * @vha : Pointer to adapter structure
+ * @p_hdr : reset_entry header for WRITE_LIST opcode.
+ *
+ */
+static void
+qla8044_write_list(struct scsi_qla_host *vha,
+	struct qla8044_reset_entry_hdr *p_hdr)
+{
+	struct qla8044_entry *p_entry;
+	uint32_t i;
+
+	p_entry = (struct qla8044_entry *)((char *)p_hdr +
+	    sizeof(struct qla8044_reset_entry_hdr));
+
+	for (i = 0; i < p_hdr->count; i++, p_entry++) {
+		qla8044_wr_reg_indirect(vha, p_entry->arg1, p_entry->arg2);
+		if (p_hdr->delay)
+			udelay((uint32_t)(p_hdr->delay));
+	}
+}
+
+/*
+ * qla8044_read_write_list - Read from address specified by p_entry->arg1,
+ * write value read to address specified by p_entry->arg2, for all entries in
+ * header with delay of p_hdr->delay between entries.
+ *
+ * @vha : Pointer to adapter structure
+ * @p_hdr : reset_entry header for READ_WRITE_LIST opcode.
+ *
+ */
+static void
+qla8044_read_write_list(struct scsi_qla_host *vha,
+	struct qla8044_reset_entry_hdr *p_hdr)
+{
+	struct qla8044_entry *p_entry;
+	uint32_t i;
+
+	p_entry = (struct qla8044_entry *)((char *)p_hdr +
+	    sizeof(struct qla8044_reset_entry_hdr));
+
+	for (i = 0; i < p_hdr->count; i++, p_entry++) {
+		qla8044_read_write_crb_reg(vha, p_entry->arg1,
+		    p_entry->arg2);
+		if (p_hdr->delay)
+			udelay((uint32_t)(p_hdr->delay));
+	}
+}
+
+/*
+ * qla8044_poll_reg - Poll the given CRB addr for duration msecs till
+ * value read ANDed with test_mask is equal to test_result.
+ *
+ * @ha : Pointer to adapter structure
+ * @addr : CRB register address
+ * @duration : Poll for total of "duration" msecs
+ * @test_mask : Mask value read with "test_mask"
+ * @test_result : Compare (value&test_mask) with test_result.
+ *
+ * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
+ */
+static int
+qla8044_poll_reg(struct scsi_qla_host *vha, uint32_t addr,
+	int duration, uint32_t test_mask, uint32_t test_result)
+{
+	uint32_t value;
+	int timeout_error;
+	uint8_t retries;
+	int ret_val = QLA_SUCCESS;
+
+	ret_val = qla8044_rd_reg_indirect(vha, addr, &value);
+	if (ret_val == QLA_FUNCTION_FAILED) {
+		timeout_error = 1;
+		goto exit_poll_reg;
+	}
+
+	/* poll every 1/10 of the total duration */
+	retries = duration/10;
+
+	do {
+		if ((value & test_mask) != test_result) {
+			timeout_error = 1;
+			msleep(duration/10);
+			ret_val = qla8044_rd_reg_indirect(vha, addr, &value);
+			if (ret_val == QLA_FUNCTION_FAILED) {
+				timeout_error = 1;
+				goto exit_poll_reg;
+			}
+		} else {
+			timeout_error = 0;
+			break;
+		}
+	} while (retries--);
+
+exit_poll_reg:
+	if (timeout_error) {
+		vha->reset_tmplt.seq_error++;
+		ql_log(ql_log_fatal, vha, 0xb090,
+		    "%s: Poll Failed: 0x%08x 0x%08x 0x%08x\n",
+		    __func__, value, test_mask, test_result);
+	}
+
+	return timeout_error;
+}
+
+/*
+ * qla8044_poll_list - For all entries in the POLL_LIST header, poll read CRB
+ * register specified by p_entry->arg1 and compare (value AND test_mask) with
+ * test_result to validate it. Wait for p_hdr->delay between processing entries.
+ *
+ * @ha : Pointer to adapter structure
+ * @p_hdr : reset_entry header for POLL_LIST opcode.
+ *
+ */
+static void
+qla8044_poll_list(struct scsi_qla_host *vha,
+	struct qla8044_reset_entry_hdr *p_hdr)
+{
+	long delay;
+	struct qla8044_entry *p_entry;
+	struct qla8044_poll *p_poll;
+	uint32_t i;
+	uint32_t value;
+
+	p_poll = (struct qla8044_poll *)
+		((char *)p_hdr + sizeof(struct qla8044_reset_entry_hdr));
+
+	/* Entries start after 8 byte qla8044_poll, poll header contains
+	 * the test_mask, test_value.
+	 */
+	p_entry = (struct qla8044_entry *)((char *)p_poll +
+	    sizeof(struct qla8044_poll));
+
+	delay = (long)p_hdr->delay;
+
+	if (!delay) {
+		for (i = 0; i < p_hdr->count; i++, p_entry++)
+			qla8044_poll_reg(vha, p_entry->arg1,
+			    delay, p_poll->test_mask, p_poll->test_value);
+	} else {
+		for (i = 0; i < p_hdr->count; i++, p_entry++) {
+			if (delay) {
+				if (qla8044_poll_reg(vha,
+				    p_entry->arg1, delay,
+				    p_poll->test_mask,
+				    p_poll->test_value)) {
+					/*If
+					* (data_read&test_mask != test_value)
+					* read TIMEOUT_ADDR (arg1) and
+					* ADDR (arg2) registers
+					*/
+					qla8044_rd_reg_indirect(vha,
+					    p_entry->arg1, &value);
+					qla8044_rd_reg_indirect(vha,
+					    p_entry->arg2, &value);
+				}
+			}
+		}
+	}
+}
+
+/*
+ * qla8044_poll_write_list - Write dr_value, ar_value to dr_addr/ar_addr,
+ * read ar_addr, if (value& test_mask != test_mask) re-read till timeout
+ * expires.
+ *
+ * @vha : Pointer to adapter structure
+ * @p_hdr : reset entry header for POLL_WRITE_LIST opcode.
+ *
+ */
+static void
+qla8044_poll_write_list(struct scsi_qla_host *vha,
+	struct qla8044_reset_entry_hdr *p_hdr)
+{
+	long delay;
+	struct qla8044_quad_entry *p_entry;
+	struct qla8044_poll *p_poll;
+	uint32_t i;
+
+	p_poll = (struct qla8044_poll *)((char *)p_hdr +
+	    sizeof(struct qla8044_reset_entry_hdr));
+
+	p_entry = (struct qla8044_quad_entry *)((char *)p_poll +
+	    sizeof(struct qla8044_poll));
+
+	delay = (long)p_hdr->delay;
+
+	for (i = 0; i < p_hdr->count; i++, p_entry++) {
+		qla8044_wr_reg_indirect(vha,
+		    p_entry->dr_addr, p_entry->dr_value);
+		qla8044_wr_reg_indirect(vha,
+		    p_entry->ar_addr, p_entry->ar_value);
+		if (delay) {
+			if (qla8044_poll_reg(vha,
+			    p_entry->ar_addr, delay,
+			    p_poll->test_mask,
+			    p_poll->test_value)) {
+				ql_dbg(ql_dbg_p3p, vha, 0xb091,
+				    "%s: Timeout Error: poll list, ",
+				    __func__);
+				ql_dbg(ql_dbg_p3p, vha, 0xb092,
+				    "item_num %d, entry_num %d\n", i,
+				    vha->reset_tmplt.seq_index);
+			}
+		}
+	}
+}
+
+/*
+ * qla8044_read_modify_write - Read value from p_entry->arg1, modify the
+ * value, write value to p_entry->arg2. Process entries with p_hdr->delay
+ * between entries.
+ *
+ * @vha : Pointer to adapter structure
+ * @p_hdr : header with shift/or/xor values.
+ *
+ */
+static void
+qla8044_read_modify_write(struct scsi_qla_host *vha,
+	struct qla8044_reset_entry_hdr *p_hdr)
+{
+	struct qla8044_entry *p_entry;
+	struct qla8044_rmw *p_rmw_hdr;
+	uint32_t i;
+
+	p_rmw_hdr = (struct qla8044_rmw *)((char *)p_hdr +
+	    sizeof(struct qla8044_reset_entry_hdr));
+
+	p_entry = (struct qla8044_entry *)((char *)p_rmw_hdr +
+	    sizeof(struct qla8044_rmw));
+
+	for (i = 0; i < p_hdr->count; i++, p_entry++) {
+		qla8044_rmw_crb_reg(vha, p_entry->arg1,
+		    p_entry->arg2, p_rmw_hdr);
+		if (p_hdr->delay)
+			udelay((uint32_t)(p_hdr->delay));
+	}
+}
+
+/*
+ * qla8044_pause - Wait for p_hdr->delay msecs, called between processing
+ * two entries of a sequence.
+ *
+ * @vha : Pointer to adapter structure
+ * @p_hdr : Common reset entry header.
+ *
+ */
+static
+void qla8044_pause(struct scsi_qla_host *vha,
+	struct qla8044_reset_entry_hdr *p_hdr)
+{
+	if (p_hdr->delay)
+		mdelay((uint32_t)((long)p_hdr->delay));
+}
+
+/*
+ * qla8044_template_end - Indicates end of reset sequence processing.
+ *
+ * @vha : Pointer to adapter structure
+ * @p_hdr : Common reset entry header.
+ *
+ */
+static void
+qla8044_template_end(struct scsi_qla_host *vha,
+	struct qla8044_reset_entry_hdr *p_hdr)
+{
+	vha->reset_tmplt.template_end = 1;
+
+	if (vha->reset_tmplt.seq_error == 0) {
+		ql_dbg(ql_dbg_p3p, vha, 0xb093,
+		    "%s: Reset sequence completed SUCCESSFULLY.\n", __func__);
+	} else {
+		ql_log(ql_log_fatal, vha, 0xb094,
+		    "%s: Reset sequence completed with some timeout "
+		    "errors.\n", __func__);
+	}
+}
+
+/*
+ * qla8044_poll_read_list - Write ar_value to ar_addr register, read ar_addr,
+ * if (value & test_mask != test_value) re-read till timeout value expires,
+ * read dr_addr register and assign to reset_tmplt.array.
+ *
+ * @vha : Pointer to adapter structure
+ * @p_hdr : Common reset entry header.
+ *
+ */
+static void
+qla8044_poll_read_list(struct scsi_qla_host *vha,
+	struct qla8044_reset_entry_hdr *p_hdr)
+{
+	long delay;
+	int index;
+	struct qla8044_quad_entry *p_entry;
+	struct qla8044_poll *p_poll;
+	uint32_t i;
+	uint32_t value;
+
+	p_poll = (struct qla8044_poll *)
+		((char *)p_hdr + sizeof(struct qla8044_reset_entry_hdr));
+
+	p_entry = (struct qla8044_quad_entry *)
+		((char *)p_poll + sizeof(struct qla8044_poll));
+
+	delay = (long)p_hdr->delay;
+
+	for (i = 0; i < p_hdr->count; i++, p_entry++) {
+		qla8044_wr_reg_indirect(vha, p_entry->ar_addr,
+		    p_entry->ar_value);
+		if (delay) {
+			if (qla8044_poll_reg(vha, p_entry->ar_addr, delay,
+			    p_poll->test_mask, p_poll->test_value)) {
+				ql_dbg(ql_dbg_p3p, vha, 0xb095,
+				    "%s: Timeout Error: poll "
+				    "list, ", __func__);
+				ql_dbg(ql_dbg_p3p, vha, 0xb096,
+				    "Item_num %d, "
+				    "entry_num %d\n", i,
+				    vha->reset_tmplt.seq_index);
+			} else {
+				index = vha->reset_tmplt.array_index;
+				qla8044_rd_reg_indirect(vha,
+				    p_entry->dr_addr, &value);
+				vha->reset_tmplt.array[index++] = value;
+				if (index == QLA8044_MAX_RESET_SEQ_ENTRIES)
+					vha->reset_tmplt.array_index = 1;
+			}
+		}
+	}
+}
+
+/*
+ * qla8031_process_reset_template - Process all entries in reset template
+ * till entry with SEQ_END opcode, which indicates end of the reset template
+ * processing. Each entry has a Reset Entry header, entry opcode/command, with
+ * size of the entry, number of entries in sub-sequence and delay in microsecs
+ * or timeout in millisecs.
+ *
+ * @ha : Pointer to adapter structure
+ * @p_buff : Common reset entry header.
+ *
+ */
+static void
+qla8044_process_reset_template(struct scsi_qla_host *vha,
+	char *p_buff)
+{
+	int index, entries;
+	struct qla8044_reset_entry_hdr *p_hdr;
+	char *p_entry = p_buff;
+
+	vha->reset_tmplt.seq_end = 0;
+	vha->reset_tmplt.template_end = 0;
+	entries = vha->reset_tmplt.hdr->entries;
+	index = vha->reset_tmplt.seq_index;
+
+	for (; (!vha->reset_tmplt.seq_end) && (index  < entries); index++) {
+		p_hdr = (struct qla8044_reset_entry_hdr *)p_entry;
+		switch (p_hdr->cmd) {
+		case OPCODE_NOP:
+			break;
+		case OPCODE_WRITE_LIST:
+			qla8044_write_list(vha, p_hdr);
+			break;
+		case OPCODE_READ_WRITE_LIST:
+			qla8044_read_write_list(vha, p_hdr);
+			break;
+		case OPCODE_POLL_LIST:
+			qla8044_poll_list(vha, p_hdr);
+			break;
+		case OPCODE_POLL_WRITE_LIST:
+			qla8044_poll_write_list(vha, p_hdr);
+			break;
+		case OPCODE_READ_MODIFY_WRITE:
+			qla8044_read_modify_write(vha, p_hdr);
+			break;
+		case OPCODE_SEQ_PAUSE:
+			qla8044_pause(vha, p_hdr);
+			break;
+		case OPCODE_SEQ_END:
+			vha->reset_tmplt.seq_end = 1;
+			break;
+		case OPCODE_TMPL_END:
+			qla8044_template_end(vha, p_hdr);
+			break;
+		case OPCODE_POLL_READ_LIST:
+			qla8044_poll_read_list(vha, p_hdr);
+			break;
+		default:
+			ql_log(ql_log_fatal, vha, 0xb097,
+			    "%s: Unknown command ==> 0x%04x on "
+			    "entry = %d\n", __func__, p_hdr->cmd, index);
+			break;
+		}
+		/*
+		 *Set pointer to next entry in the sequence.
+		*/
+		p_entry += p_hdr->size;
+	}
+	vha->reset_tmplt.seq_index = index;
+}
+
+static void
+qla8044_process_init_seq(struct scsi_qla_host *vha)
+{
+	qla8044_process_reset_template(vha,
+	    vha->reset_tmplt.init_offset);
+	if (vha->reset_tmplt.seq_end != 1)
+		ql_log(ql_log_fatal, vha, 0xb098,
+		    "%s: Abrupt INIT Sub-Sequence end.\n",
+		    __func__);
+}
+
+static void
+qla8044_process_stop_seq(struct scsi_qla_host *vha)
+{
+	vha->reset_tmplt.seq_index = 0;
+	qla8044_process_reset_template(vha, vha->reset_tmplt.stop_offset);
+	if (vha->reset_tmplt.seq_end != 1)
+		ql_log(ql_log_fatal, vha, 0xb099,
+		    "%s: Abrupt STOP Sub-Sequence end.\n", __func__);
+}
+
+static void
+qla8044_process_start_seq(struct scsi_qla_host *vha)
+{
+	qla8044_process_reset_template(vha, vha->reset_tmplt.start_offset);
+	if (vha->reset_tmplt.template_end != 1)
+		ql_log(ql_log_fatal, vha, 0xb09a,
+		    "%s: Abrupt START Sub-Sequence end.\n",
+		    __func__);
+}
+
+static int
+qla8044_lockless_flash_read_u32(struct scsi_qla_host *vha,
+	uint32_t flash_addr, uint8_t *p_data, int u32_word_count)
+{
+	uint32_t i;
+	uint32_t u32_word;
+	uint32_t flash_offset;
+	uint32_t addr = flash_addr;
+	int ret_val = QLA_SUCCESS;
+
+	flash_offset = addr & (QLA8044_FLASH_SECTOR_SIZE - 1);
+
+	if (addr & 0x3) {
+		ql_log(ql_log_fatal, vha, 0xb09b, "%s: Illegal addr = 0x%x\n",
+		    __func__, addr);
+		ret_val = QLA_FUNCTION_FAILED;
+		goto exit_lockless_read;
+	}
+
+	ret_val = qla8044_wr_reg_indirect(vha,
+	    QLA8044_FLASH_DIRECT_WINDOW, (addr));
+
+	if (ret_val != QLA_SUCCESS) {
+		ql_log(ql_log_fatal, vha, 0xb09c,
+		    "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
+		    __func__, addr);
+		goto exit_lockless_read;
+	}
+
+	/* Check if data is spread across multiple sectors  */
+	if ((flash_offset + (u32_word_count * sizeof(uint32_t))) >
+	    (QLA8044_FLASH_SECTOR_SIZE - 1)) {
+		/* Multi sector read */
+		for (i = 0; i < u32_word_count; i++) {
+			ret_val = qla8044_rd_reg_indirect(vha,
+			    QLA8044_FLASH_DIRECT_DATA(addr), &u32_word);
+			if (ret_val != QLA_SUCCESS) {
+				ql_log(ql_log_fatal, vha, 0xb09d,
+				    "%s: failed to read addr 0x%x!\n",
+				    __func__, addr);
+				goto exit_lockless_read;
+			}
+			*(uint32_t *)p_data  = u32_word;
+			p_data = p_data + 4;
+			addr = addr + 4;
+			flash_offset = flash_offset + 4;
+			if (flash_offset > (QLA8044_FLASH_SECTOR_SIZE - 1)) {
+				/* This write is needed once for each sector */
+				ret_val = qla8044_wr_reg_indirect(vha,
+				    QLA8044_FLASH_DIRECT_WINDOW, (addr));
+				if (ret_val != QLA_SUCCESS) {
+					ql_log(ql_log_fatal, vha, 0xb09f,
+					    "%s: failed to write addr "
+					    "0x%x to FLASH_DIRECT_WINDOW!\n",
+					    __func__, addr);
+					goto exit_lockless_read;
+				}
+				flash_offset = 0;
+			}
+		}
+	} else {
+		/* Single sector read */
+		for (i = 0; i < u32_word_count; i++) {
+			ret_val = qla8044_rd_reg_indirect(vha,
+			    QLA8044_FLASH_DIRECT_DATA(addr), &u32_word);
+			if (ret_val != QLA_SUCCESS) {
+				ql_log(ql_log_fatal, vha, 0xb0a0,
+				    "%s: failed to read addr 0x%x!\n",
+				    __func__, addr);
+				goto exit_lockless_read;
+			}
+			*(uint32_t *)p_data = u32_word;
+			p_data = p_data + 4;
+			addr = addr + 4;
+		}
+	}
+
+exit_lockless_read:
+	return ret_val;
+}
+
+/*
+ * qla8044_ms_mem_write_128b - Writes data to MS/off-chip memory
+ *
+ * @vha : Pointer to adapter structure
+ * addr : Flash address to write to
+ * data : Data to be written
+ * count : word_count to be written
+ *
+ * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
+ */
+static int
+qla8044_ms_mem_write_128b(struct scsi_qla_host *vha,
+	uint64_t addr, uint32_t *data, uint32_t count)
+{
+	int i, j, ret_val = QLA_SUCCESS;
+	uint32_t agt_ctrl;
+	unsigned long flags;
+	struct qla_hw_data *ha = vha->hw;
+
+	/* Only 128-bit aligned access */
+	if (addr & 0xF) {
+		ret_val = QLA_FUNCTION_FAILED;
+		goto exit_ms_mem_write;
+	}
+	write_lock_irqsave(&ha->hw_lock, flags);
+
+	/* Write address */
+	ret_val = qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_ADDR_HI, 0);
+	if (ret_val == QLA_FUNCTION_FAILED) {
+		ql_log(ql_log_fatal, vha, 0xb0a1,
+		    "%s: write to AGT_ADDR_HI failed!\n", __func__);
+		goto exit_ms_mem_write_unlock;
+	}
+
+	for (i = 0; i < count; i++, addr += 16) {
+		if (!((QLA8044_ADDR_IN_RANGE(addr, QLA8044_ADDR_QDR_NET,
+		    QLA8044_ADDR_QDR_NET_MAX)) ||
+		    (QLA8044_ADDR_IN_RANGE(addr, QLA8044_ADDR_DDR_NET,
+			QLA8044_ADDR_DDR_NET_MAX)))) {
+			ret_val = QLA_FUNCTION_FAILED;
+			goto exit_ms_mem_write_unlock;
+		}
+
+		ret_val = qla8044_wr_reg_indirect(vha,
+		    MD_MIU_TEST_AGT_ADDR_LO, addr);
+
+		/* Write data */
+		ret_val += qla8044_wr_reg_indirect(vha,
+		    MD_MIU_TEST_AGT_WRDATA_LO, *data++);
+		ret_val += qla8044_wr_reg_indirect(vha,
+		    MD_MIU_TEST_AGT_WRDATA_HI, *data++);
+		ret_val += qla8044_wr_reg_indirect(vha,
+		    MD_MIU_TEST_AGT_WRDATA_ULO, *data++);
+		ret_val += qla8044_wr_reg_indirect(vha,
+		    MD_MIU_TEST_AGT_WRDATA_UHI, *data++);
+		if (ret_val == QLA_FUNCTION_FAILED) {
+			ql_log(ql_log_fatal, vha, 0xb0a2,
+			    "%s: write to AGT_WRDATA failed!\n",
+			    __func__);
+			goto exit_ms_mem_write_unlock;
+		}
+
+		/* Check write status */
+		ret_val = qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL,
+		    MIU_TA_CTL_WRITE_ENABLE);
+		ret_val += qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL,
+		    MIU_TA_CTL_WRITE_START);
+		if (ret_val == QLA_FUNCTION_FAILED) {
+			ql_log(ql_log_fatal, vha, 0xb0a3,
+			    "%s: write to AGT_CTRL failed!\n", __func__);
+			goto exit_ms_mem_write_unlock;
+		}
+
+		for (j = 0; j < MAX_CTL_CHECK; j++) {
+			ret_val = qla8044_rd_reg_indirect(vha,
+			    MD_MIU_TEST_AGT_CTRL, &agt_ctrl);
+			if (ret_val == QLA_FUNCTION_FAILED) {
+				ql_log(ql_log_fatal, vha, 0xb0a4,
+				    "%s: failed to read "
+				    "MD_MIU_TEST_AGT_CTRL!\n", __func__);
+				goto exit_ms_mem_write_unlock;
+			}
+			if ((agt_ctrl & MIU_TA_CTL_BUSY) == 0)
+				break;
+		}
+
+		/* Status check failed */
+		if (j >= MAX_CTL_CHECK) {
+			ql_log(ql_log_fatal, vha, 0xb0a5,
+			    "%s: MS memory write failed!\n",
+			   __func__);
+			ret_val = QLA_FUNCTION_FAILED;
+			goto exit_ms_mem_write_unlock;
+		}
+	}
+
+exit_ms_mem_write_unlock:
+	write_unlock_irqrestore(&ha->hw_lock, flags);
+
+exit_ms_mem_write:
+	return ret_val;
+}
+
+static int
+qla8044_copy_bootloader(struct scsi_qla_host *vha)
+{
+	uint8_t *p_cache;
+	uint32_t src, count, size;
+	uint64_t dest;
+	int ret_val = QLA_SUCCESS;
+	struct qla_hw_data *ha = vha->hw;
+
+	src = QLA8044_BOOTLOADER_FLASH_ADDR;
+	dest = qla8044_rd_reg(ha, QLA8044_BOOTLOADER_ADDR);
+	size = qla8044_rd_reg(ha, QLA8044_BOOTLOADER_SIZE);
+
+	/* 128 bit alignment check */
+	if (size & 0xF)
+		size = (size + 16) & ~0xF;
+
+	/* 16 byte count */
+	count = size/16;
+
+	p_cache = vmalloc(size);
+	if (p_cache == NULL) {
+		ql_log(ql_log_fatal, vha, 0xb0a6,
+		    "%s: Failed to allocate memory for "
+		    "boot loader cache\n", __func__);
+		ret_val = QLA_FUNCTION_FAILED;
+		goto exit_copy_bootloader;
+	}
+
+	ret_val = qla8044_lockless_flash_read_u32(vha, src,
+	    p_cache, size/sizeof(uint32_t));
+	if (ret_val == QLA_FUNCTION_FAILED) {
+		ql_log(ql_log_fatal, vha, 0xb0a7,
+		    "%s: Error reading F/W from flash!!!\n", __func__);
+		goto exit_copy_error;
+	}
+	ql_dbg(ql_dbg_p3p, vha, 0xb0a8, "%s: Read F/W from flash!\n",
+	    __func__);
+
+	/* 128 bit/16 byte write to MS memory */
+	ret_val = qla8044_ms_mem_write_128b(vha, dest,
+	    (uint32_t *)p_cache, count);
+	if (ret_val == QLA_FUNCTION_FAILED) {
+		ql_log(ql_log_fatal, vha, 0xb0a9,
+		    "%s: Error writing F/W to MS !!!\n", __func__);
+		goto exit_copy_error;
+	}
+	ql_dbg(ql_dbg_p3p, vha, 0xb0aa,
+	    "%s: Wrote F/W (size %d) to MS !!!\n",
+	    __func__, size);
+
+exit_copy_error:
+	vfree(p_cache);
+
+exit_copy_bootloader:
+	return ret_val;
+}
+
+static int
+qla8044_restart(struct scsi_qla_host *vha)
+{
+	int ret_val = QLA_SUCCESS;
+	struct qla_hw_data *ha = vha->hw;
+
+	qla8044_process_stop_seq(vha);
+
+	/* Collect minidump */
+	if (ql2xmdenable)
+		qla8044_get_minidump(vha);
+	else
+		ql_log(ql_log_fatal, vha, 0xb14c,
+		    "Minidump disabled.\n");
+
+	qla8044_process_init_seq(vha);
+
+	if (qla8044_copy_bootloader(vha)) {
+		ql_log(ql_log_fatal, vha, 0xb0ab,
+		    "%s: Copy bootloader, firmware restart failed!\n",
+		    __func__);
+		ret_val = QLA_FUNCTION_FAILED;
+		goto exit_restart;
+	}
+
+	/*
+	 *  Loads F/W from flash
+	 */
+	qla8044_wr_reg(ha, QLA8044_FW_IMAGE_VALID, QLA8044_BOOT_FROM_FLASH);
+
+	qla8044_process_start_seq(vha);
+
+exit_restart:
+	return ret_val;
+}
+
+/*
+ * qla8044_check_cmd_peg_status - Check peg status to see if Peg is
+ * initialized.
+ *
+ * @ha : Pointer to adapter structure
+ *
+ * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
+ */
+static int
+qla8044_check_cmd_peg_status(struct scsi_qla_host *vha)
+{
+	uint32_t val, ret_val = QLA_FUNCTION_FAILED;
+	int retries = CRB_CMDPEG_CHECK_RETRY_COUNT;
+	struct qla_hw_data *ha = vha->hw;
+
+	do {
+		val = qla8044_rd_reg(ha, QLA8044_CMDPEG_STATE);
+		if (val == PHAN_INITIALIZE_COMPLETE) {
+			ql_dbg(ql_dbg_p3p, vha, 0xb0ac,
+			    "%s: Command Peg initialization "
+			    "complete! state=0x%x\n", __func__, val);
+			ret_val = QLA_SUCCESS;
+			break;
+		}
+		msleep(CRB_CMDPEG_CHECK_DELAY);
+	} while (--retries);
+
+	return ret_val;
+}
+
+static int
+qla8044_start_firmware(struct scsi_qla_host *vha)
+{
+	int ret_val = QLA_SUCCESS;
+
+	if (qla8044_restart(vha)) {
+		ql_log(ql_log_fatal, vha, 0xb0ad,
+		    "%s: Restart Error!!!, Need Reset!!!\n",
+		    __func__);
+		ret_val = QLA_FUNCTION_FAILED;
+		goto exit_start_fw;
+	} else
+		ql_dbg(ql_dbg_p3p, vha, 0xb0af,
+		    "%s: Restart done!\n", __func__);
+
+	ret_val = qla8044_check_cmd_peg_status(vha);
+	if (ret_val) {
+		ql_log(ql_log_fatal, vha, 0xb0b0,
+		    "%s: Peg not initialized!\n", __func__);
+		ret_val = QLA_FUNCTION_FAILED;
+	}
+
+exit_start_fw:
+	return ret_val;
+}
+
+void
+qla8044_clear_drv_active(struct scsi_qla_host *vha)
+{
+	uint32_t drv_active;
+	struct qla_hw_data *ha = vha->hw;
+
+	drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
+	drv_active &= ~(1 << (ha->portnum));
+
+	ql_log(ql_log_info, vha, 0xb0b1,
+	    "%s(%ld): drv_active: 0x%08x\n",
+	    __func__, vha->host_no, drv_active);
+
+	qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active);
+}
+
+/*
+ * qla8044_device_bootstrap - Initialize device, set DEV_READY, start fw
+ * @ha: pointer to adapter structure
+ *
+ * Note: IDC lock must be held upon entry
+ **/
+static int
+qla8044_device_bootstrap(struct scsi_qla_host *vha)
+{
+	int rval = QLA_FUNCTION_FAILED;
+	int i;
+	uint32_t old_count = 0, count = 0;
+	int need_reset = 0;
+	uint32_t idc_ctrl;
+	struct qla_hw_data *ha = vha->hw;
+
+	need_reset = qla8044_need_reset(vha);
+
+	if (!need_reset) {
+		old_count = qla8044_rd_direct(vha,
+		    QLA8044_PEG_ALIVE_COUNTER_INDEX);
+
+		for (i = 0; i < 10; i++) {
+			msleep(200);
+
+			count = qla8044_rd_direct(vha,
+			    QLA8044_PEG_ALIVE_COUNTER_INDEX);
+			if (count != old_count) {
+				rval = QLA_SUCCESS;
+				goto dev_ready;
+			}
+		}
+		qla8044_flash_lock_recovery(vha);
+	} else {
+		/* We are trying to perform a recovery here. */
+		if (ha->flags.isp82xx_fw_hung)
+			qla8044_flash_lock_recovery(vha);
+	}
+
+	/* set to DEV_INITIALIZING */
+	ql_log(ql_log_info, vha, 0xb0b2,
+	    "%s: HW State: INITIALIZING\n", __func__);
+	qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
+	    QLA8XXX_DEV_INITIALIZING);
+
+	qla8044_idc_unlock(ha);
+	rval = qla8044_start_firmware(vha);
+	qla8044_idc_lock(ha);
+
+	if (rval != QLA_SUCCESS) {
+		ql_log(ql_log_info, vha, 0xb0b3,
+		     "%s: HW State: FAILED\n", __func__);
+		qla8044_clear_drv_active(vha);
+		qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
+		    QLA8XXX_DEV_FAILED);
+		return rval;
+	}
+
+	/* For ISP8044, If IDC_CTRL GRACEFUL_RESET_BIT1 is set , reset it after
+	 * device goes to INIT state. */
+	idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
+	if (idc_ctrl & GRACEFUL_RESET_BIT1) {
+		qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL,
+		    (idc_ctrl & ~GRACEFUL_RESET_BIT1));
+		ha->fw_dumped = 0;
+	}
+
+dev_ready:
+	ql_log(ql_log_info, vha, 0xb0b4,
+	    "%s: HW State: READY\n", __func__);
+	qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX, QLA8XXX_DEV_READY);
+
+	return rval;
+}
+
+/*-------------------------Reset Sequence Functions-----------------------*/
+static void
+qla8044_dump_reset_seq_hdr(struct scsi_qla_host *vha)
+{
+	u8 *phdr;
+
+	if (!vha->reset_tmplt.buff) {
+		ql_log(ql_log_fatal, vha, 0xb0b5,
+		    "%s: Error Invalid reset_seq_template\n", __func__);
+		return;
+	}
+
+	phdr = vha->reset_tmplt.buff;
+	ql_dbg(ql_dbg_p3p, vha, 0xb0b6,
+	    "Reset Template :\n\t0x%X 0x%X 0x%X 0x%X"
+	    "0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n"
+	    "\t0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n\n",
+	    *phdr, *(phdr+1), *(phdr+2), *(phdr+3), *(phdr+4),
+	    *(phdr+5), *(phdr+6), *(phdr+7), *(phdr + 8),
+	    *(phdr+9), *(phdr+10), *(phdr+11), *(phdr+12),
+	    *(phdr+13), *(phdr+14), *(phdr+15));
+}
+
+/*
+ * qla8044_reset_seq_checksum_test - Validate Reset Sequence template.
+ *
+ * @ha : Pointer to adapter structure
+ *
+ * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
+ */
+static int
+qla8044_reset_seq_checksum_test(struct scsi_qla_host *vha)
+{
+	uint32_t sum =  0;
+	uint16_t *buff = (uint16_t *)vha->reset_tmplt.buff;
+	int u16_count =  vha->reset_tmplt.hdr->size / sizeof(uint16_t);
+
+	while (u16_count-- > 0)
+		sum += *buff++;
+
+	while (sum >> 16)
+		sum = (sum & 0xFFFF) +  (sum >> 16);
+
+	/* checksum of 0 indicates a valid template */
+	if (~sum) {
+		return QLA_SUCCESS;
+	} else {
+		ql_log(ql_log_fatal, vha, 0xb0b7,
+		    "%s: Reset seq checksum failed\n", __func__);
+		return QLA_FUNCTION_FAILED;
+	}
+}
+
+/*
+ * qla8044_read_reset_template - Read Reset Template from Flash, validate
+ * the template and store offsets of stop/start/init offsets in ha->reset_tmplt.
+ *
+ * @ha : Pointer to adapter structure
+ */
+void
+qla8044_read_reset_template(struct scsi_qla_host *vha)
+{
+	uint8_t *p_buff;
+	uint32_t addr, tmplt_hdr_def_size, tmplt_hdr_size;
+
+	vha->reset_tmplt.seq_error = 0;
+	vha->reset_tmplt.buff = vmalloc(QLA8044_RESTART_TEMPLATE_SIZE);
+	if (vha->reset_tmplt.buff == NULL) {
+		ql_log(ql_log_fatal, vha, 0xb0b8,
+		    "%s: Failed to allocate reset template resources\n",
+		    __func__);
+		goto exit_read_reset_template;
+	}
+
+	p_buff = vha->reset_tmplt.buff;
+	addr = QLA8044_RESET_TEMPLATE_ADDR;
+
+	tmplt_hdr_def_size =
+	    sizeof(struct qla8044_reset_template_hdr) / sizeof(uint32_t);
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0b9,
+	    "%s: Read template hdr size %d from Flash\n",
+	    __func__, tmplt_hdr_def_size);
+
+	/* Copy template header from flash */
+	if (qla8044_read_flash_data(vha, p_buff, addr, tmplt_hdr_def_size)) {
+		ql_log(ql_log_fatal, vha, 0xb0ba,
+		    "%s: Failed to read reset template\n", __func__);
+		goto exit_read_template_error;
+	}
+
+	vha->reset_tmplt.hdr =
+	 (struct qla8044_reset_template_hdr *) vha->reset_tmplt.buff;
+
+	/* Validate the template header size and signature */
+	tmplt_hdr_size = vha->reset_tmplt.hdr->hdr_size/sizeof(uint32_t);
+	if ((tmplt_hdr_size != tmplt_hdr_def_size) ||
+	    (vha->reset_tmplt.hdr->signature != RESET_TMPLT_HDR_SIGNATURE)) {
+		ql_log(ql_log_fatal, vha, 0xb0bb,
+		    "%s: Template Header size invalid %d "
+		    "tmplt_hdr_def_size %d!!!\n", __func__,
+		    tmplt_hdr_size, tmplt_hdr_def_size);
+		goto exit_read_template_error;
+	}
+
+	addr = QLA8044_RESET_TEMPLATE_ADDR + vha->reset_tmplt.hdr->hdr_size;
+	p_buff = vha->reset_tmplt.buff + vha->reset_tmplt.hdr->hdr_size;
+	tmplt_hdr_def_size = (vha->reset_tmplt.hdr->size -
+	    vha->reset_tmplt.hdr->hdr_size)/sizeof(uint32_t);
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0bc,
+	    "%s: Read rest of the template size %d\n",
+	    __func__, vha->reset_tmplt.hdr->size);
+
+	/* Copy rest of the template */
+	if (qla8044_read_flash_data(vha, p_buff, addr, tmplt_hdr_def_size)) {
+		ql_log(ql_log_fatal, vha, 0xb0bd,
+		    "%s: Failed to read reset tempelate\n", __func__);
+		goto exit_read_template_error;
+	}
+
+	/* Integrity check */
+	if (qla8044_reset_seq_checksum_test(vha)) {
+		ql_log(ql_log_fatal, vha, 0xb0be,
+		    "%s: Reset Seq checksum failed!\n", __func__);
+		goto exit_read_template_error;
+	}
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0bf,
+	    "%s: Reset Seq checksum passed! Get stop, "
+	    "start and init seq offsets\n", __func__);
+
+	/* Get STOP, START, INIT sequence offsets */
+	vha->reset_tmplt.init_offset = vha->reset_tmplt.buff +
+	    vha->reset_tmplt.hdr->init_seq_offset;
+
+	vha->reset_tmplt.start_offset = vha->reset_tmplt.buff +
+	    vha->reset_tmplt.hdr->start_seq_offset;
+
+	vha->reset_tmplt.stop_offset = vha->reset_tmplt.buff +
+	    vha->reset_tmplt.hdr->hdr_size;
+
+	qla8044_dump_reset_seq_hdr(vha);
+
+	goto exit_read_reset_template;
+
+exit_read_template_error:
+	vfree(vha->reset_tmplt.buff);
+
+exit_read_reset_template:
+	return;
+}
+
+void
+qla8044_set_idc_dontreset(struct scsi_qla_host *vha)
+{
+	uint32_t idc_ctrl;
+	struct qla_hw_data *ha = vha->hw;
+
+	idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
+	idc_ctrl |= DONTRESET_BIT0;
+	ql_dbg(ql_dbg_p3p, vha, 0xb0c0,
+	    "%s: idc_ctrl = %d\n", __func__, idc_ctrl);
+	qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL, idc_ctrl);
+}
+
+inline void
+qla8044_set_rst_ready(struct scsi_qla_host *vha)
+{
+	uint32_t drv_state;
+	struct qla_hw_data *ha = vha->hw;
+
+	drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
+
+	/* For ISP8044, drv_active register has 1 bit per function,
+	 * shift 1 by func_num to set a bit for the function.*/
+	drv_state |= (1 << ha->portnum);
+
+	ql_log(ql_log_info, vha, 0xb0c1,
+	    "%s(%ld): drv_state: 0x%08x\n",
+	    __func__, vha->host_no, drv_state);
+	qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, drv_state);
+}
+
+/**
+ * qla8044_need_reset_handler - Code to start reset sequence
+ * @ha: pointer to adapter structure
+ *
+ * Note: IDC lock must be held upon entry
+ **/
+static void
+qla8044_need_reset_handler(struct scsi_qla_host *vha)
+{
+	uint32_t dev_state = 0, drv_state, drv_active;
+	unsigned long reset_timeout, dev_init_timeout;
+	struct qla_hw_data *ha = vha->hw;
+
+	ql_log(ql_log_fatal, vha, 0xb0c2,
+	    "%s: Performing ISP error recovery\n", __func__);
+
+	if (vha->flags.online) {
+		qla8044_idc_unlock(ha);
+		qla2x00_abort_isp_cleanup(vha);
+		ha->isp_ops->get_flash_version(vha, vha->req->ring);
+		ha->isp_ops->nvram_config(vha);
+		qla8044_idc_lock(ha);
+	}
+
+	if (!ha->flags.nic_core_reset_owner) {
+		ql_dbg(ql_dbg_p3p, vha, 0xb0c3,
+		    "%s(%ld): reset acknowledged\n",
+		    __func__, vha->host_no);
+		qla8044_set_rst_ready(vha);
+
+		/* Non-reset owners ACK Reset and wait for device INIT state
+		 * as part of Reset Recovery by Reset Owner
+		 */
+		dev_init_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
+
+		do {
+			if (time_after_eq(jiffies, dev_init_timeout)) {
+				ql_log(ql_log_info, vha, 0xb0c4,
+				    "%s: Non Reset owner DEV INIT "
+				    "TIMEOUT!\n", __func__);
+				break;
+			}
+
+			qla8044_idc_unlock(ha);
+			msleep(1000);
+			qla8044_idc_lock(ha);
+
+			dev_state = qla8044_rd_direct(vha,
+					QLA8044_CRB_DEV_STATE_INDEX);
+		} while (dev_state == QLA8XXX_DEV_NEED_RESET);
+	} else {
+		qla8044_set_rst_ready(vha);
+
+		/* wait for 10 seconds for reset ack from all functions */
+		reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
+
+		drv_state = qla8044_rd_direct(vha,
+		    QLA8044_CRB_DRV_STATE_INDEX);
+		drv_active = qla8044_rd_direct(vha,
+		    QLA8044_CRB_DRV_ACTIVE_INDEX);
+
+		ql_log(ql_log_info, vha, 0xb0c5,
+		    "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
+		    __func__, vha->host_no, drv_state, drv_active);
+
+		while (drv_state != drv_active) {
+			if (time_after_eq(jiffies, reset_timeout)) {
+				ql_log(ql_log_info, vha, 0xb0c6,
+				    "%s: RESET TIMEOUT!"
+				    "drv_state: 0x%08x, drv_active: 0x%08x\n",
+				    QLA2XXX_DRIVER_NAME, drv_state, drv_active);
+				break;
+			}
+
+			qla8044_idc_unlock(ha);
+			msleep(1000);
+			qla8044_idc_lock(ha);
+
+			drv_state = qla8044_rd_direct(vha,
+			    QLA8044_CRB_DRV_STATE_INDEX);
+			drv_active = qla8044_rd_direct(vha,
+			    QLA8044_CRB_DRV_ACTIVE_INDEX);
+		}
+
+		if (drv_state != drv_active) {
+			ql_log(ql_log_info, vha, 0xb0c7,
+			    "%s(%ld): Reset_owner turning off drv_active "
+			    "of non-acking function 0x%x\n", __func__,
+			    vha->host_no, (drv_active ^ drv_state));
+			drv_active = drv_active & drv_state;
+			qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX,
+			    drv_active);
+		}
+
+		/*
+		* Clear RESET OWNER, will be set at next reset
+		* by next RST_OWNER
+		*/
+		ha->flags.nic_core_reset_owner = 0;
+
+		/* Start Reset Recovery */
+		qla8044_device_bootstrap(vha);
+	}
+}
+
+static void
+qla8044_set_drv_active(struct scsi_qla_host *vha)
+{
+	uint32_t drv_active;
+	struct qla_hw_data *ha = vha->hw;
+
+	drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
+
+	/* For ISP8044, drv_active register has 1 bit per function,
+	 * shift 1 by func_num to set a bit for the function.*/
+	drv_active |= (1 << ha->portnum);
+
+	ql_log(ql_log_info, vha, 0xb0c8,
+	    "%s(%ld): drv_active: 0x%08x\n",
+	    __func__, vha->host_no, drv_active);
+	qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active);
+}
+
+static void
+qla8044_clear_idc_dontreset(struct scsi_qla_host *vha)
+{
+	uint32_t idc_ctrl;
+	struct qla_hw_data *ha = vha->hw;
+
+	idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
+	idc_ctrl &= ~DONTRESET_BIT0;
+	ql_log(ql_log_info, vha, 0xb0c9,
+	    "%s: idc_ctrl = %d\n", __func__,
+	    idc_ctrl);
+	qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL, idc_ctrl);
+}
+
+static int
+qla8044_set_idc_ver(struct scsi_qla_host *vha)
+{
+	int idc_ver;
+	uint32_t drv_active;
+	int rval = QLA_SUCCESS;
+	struct qla_hw_data *ha = vha->hw;
+
+	drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
+	if (drv_active == (1 << ha->portnum)) {
+		idc_ver = qla8044_rd_direct(vha,
+		    QLA8044_CRB_DRV_IDC_VERSION_INDEX);
+		idc_ver &= (~0xFF);
+		idc_ver |= QLA8044_IDC_VER_MAJ_VALUE;
+		qla8044_wr_direct(vha, QLA8044_CRB_DRV_IDC_VERSION_INDEX,
+		    idc_ver);
+		ql_log(ql_log_info, vha, 0xb0ca,
+		    "%s: IDC version updated to %d\n",
+		    __func__, idc_ver);
+	} else {
+		idc_ver = qla8044_rd_direct(vha,
+		    QLA8044_CRB_DRV_IDC_VERSION_INDEX);
+		idc_ver &= 0xFF;
+		if (QLA8044_IDC_VER_MAJ_VALUE != idc_ver) {
+			ql_log(ql_log_info, vha, 0xb0cb,
+			    "%s: qla4xxx driver IDC version %d "
+			    "is not compatible with IDC version %d "
+			    "of other drivers!\n",
+			    __func__, QLA8044_IDC_VER_MAJ_VALUE,
+			    idc_ver);
+			rval = QLA_FUNCTION_FAILED;
+			goto exit_set_idc_ver;
+		}
+	}
+
+	/* Update IDC_MINOR_VERSION */
+	idc_ver = qla8044_rd_reg(ha, QLA8044_CRB_IDC_VER_MINOR);
+	idc_ver &= ~(0x03 << (ha->portnum * 2));
+	idc_ver |= (QLA8044_IDC_VER_MIN_VALUE << (ha->portnum * 2));
+	qla8044_wr_reg(ha, QLA8044_CRB_IDC_VER_MINOR, idc_ver);
+
+exit_set_idc_ver:
+	return rval;
+}
+
+static int
+qla8044_update_idc_reg(struct scsi_qla_host *vha)
+{
+	uint32_t drv_active;
+	int rval = QLA_SUCCESS;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (vha->flags.init_done)
+		goto exit_update_idc_reg;
+
+	qla8044_idc_lock(ha);
+	qla8044_set_drv_active(vha);
+
+	drv_active = qla8044_rd_direct(vha,
+	    QLA8044_CRB_DRV_ACTIVE_INDEX);
+
+	/* If we are the first driver to load and
+	 * ql2xdontresethba is not set, clear IDC_CTRL BIT0. */
+	if ((drv_active == (1 << ha->portnum)) && !ql2xdontresethba)
+		qla8044_clear_idc_dontreset(vha);
+
+	rval = qla8044_set_idc_ver(vha);
+	if (rval == QLA_FUNCTION_FAILED)
+		qla8044_clear_drv_active(vha);
+	qla8044_idc_unlock(ha);
+
+exit_update_idc_reg:
+	return rval;
+}
+
+/**
+ * qla8044_need_qsnt_handler - Code to start qsnt
+ * @ha: pointer to adapter structure
+ **/
+static void
+qla8044_need_qsnt_handler(struct scsi_qla_host *vha)
+{
+	unsigned long qsnt_timeout;
+	uint32_t drv_state, drv_active, dev_state;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (vha->flags.online)
+		qla2x00_quiesce_io(vha);
+	else
+		return;
+
+	qla8044_set_qsnt_ready(vha);
+
+	/* Wait for 30 secs for all functions to ack qsnt mode */
+	qsnt_timeout = jiffies + (QSNT_ACK_TOV * HZ);
+	drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
+	drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
+
+	/* Shift drv_active by 1 to match drv_state. As quiescent ready bit
+	   position is at bit 1 and drv active is at bit 0 */
+	drv_active = drv_active << 1;
+
+	while (drv_state != drv_active) {
+		if (time_after_eq(jiffies, qsnt_timeout)) {
+			/* Other functions did not ack, changing state to
+			 * DEV_READY
+			 */
+			clear_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
+			qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
+					    QLA8XXX_DEV_READY);
+			qla8044_clear_qsnt_ready(vha);
+			ql_log(ql_log_info, vha, 0xb0cc,
+			    "Timeout waiting for quiescent ack!!!\n");
+			return;
+		}
+		qla8044_idc_unlock(ha);
+		msleep(1000);
+		qla8044_idc_lock(ha);
+
+		drv_state = qla8044_rd_direct(vha,
+		    QLA8044_CRB_DRV_STATE_INDEX);
+		drv_active = qla8044_rd_direct(vha,
+		    QLA8044_CRB_DRV_ACTIVE_INDEX);
+		drv_active = drv_active << 1;
+	}
+
+	/* All functions have Acked. Set quiescent state */
+	dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
+
+	if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT) {
+		qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
+		    QLA8XXX_DEV_QUIESCENT);
+		ql_log(ql_log_info, vha, 0xb0cd,
+		    "%s: HW State: QUIESCENT\n", __func__);
+	}
+}
+
+/*
+ * qla8044_device_state_handler - Adapter state machine
+ * @ha: pointer to host adapter structure.
+ *
+ * Note: IDC lock must be UNLOCKED upon entry
+ **/
+int
+qla8044_device_state_handler(struct scsi_qla_host *vha)
+{
+	uint32_t dev_state;
+	int rval = QLA_SUCCESS;
+	unsigned long dev_init_timeout;
+	struct qla_hw_data *ha = vha->hw;
+
+	rval = qla8044_update_idc_reg(vha);
+	if (rval == QLA_FUNCTION_FAILED)
+		goto exit_error;
+
+	dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
+	ql_dbg(ql_dbg_p3p, vha, 0xb0ce,
+	    "Device state is 0x%x = %s\n",
+	    dev_state, dev_state < MAX_STATES ?
+	    qdev_state(dev_state) : "Unknown");
+
+	/* wait for 30 seconds for device to go ready */
+	dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout * HZ);
+
+	qla8044_idc_lock(ha);
+
+	while (1) {
+		if (time_after_eq(jiffies, dev_init_timeout)) {
+			ql_log(ql_log_warn, vha, 0xb0cf,
+			    "%s: Device Init Failed 0x%x = %s\n",
+			    QLA2XXX_DRIVER_NAME, dev_state,
+			    dev_state < MAX_STATES ?
+			    qdev_state(dev_state) : "Unknown");
+
+			qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
+			    QLA8XXX_DEV_FAILED);
+		}
+
+		dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
+		ql_log(ql_log_info, vha, 0xb0d0,
+		    "Device state is 0x%x = %s\n",
+		    dev_state, dev_state < MAX_STATES ?
+		    qdev_state(dev_state) : "Unknown");
+
+		/* NOTE: Make sure idc unlocked upon exit of switch statement */
+		switch (dev_state) {
+		case QLA8XXX_DEV_READY:
+			ha->flags.nic_core_reset_owner = 0;
+			goto exit;
+		case QLA8XXX_DEV_COLD:
+			rval = qla8044_device_bootstrap(vha);
+			goto exit;
+		case QLA8XXX_DEV_INITIALIZING:
+			qla8044_idc_unlock(ha);
+			msleep(1000);
+			qla8044_idc_lock(ha);
+			break;
+		case QLA8XXX_DEV_NEED_RESET:
+			/* For ISP8044, if NEED_RESET is set by any driver,
+			 * it should be honored, irrespective of IDC_CTRL
+			 * DONTRESET_BIT0 */
+			qla8044_need_reset_handler(vha);
+			break;
+		case QLA8XXX_DEV_NEED_QUIESCENT:
+			/* idc locked/unlocked in handler */
+			qla8044_need_qsnt_handler(vha);
+
+			/* Reset the init timeout after qsnt handler */
+			dev_init_timeout = jiffies +
+			    (ha->fcoe_reset_timeout * HZ);
+			break;
+		case QLA8XXX_DEV_QUIESCENT:
+			ql_log(ql_log_info, vha, 0xb0d1,
+			    "HW State: QUIESCENT\n");
+
+			qla8044_idc_unlock(ha);
+			msleep(1000);
+			qla8044_idc_lock(ha);
+
+			/* Reset the init timeout after qsnt handler */
+			dev_init_timeout = jiffies +
+			    (ha->fcoe_reset_timeout * HZ);
+			break;
+		case QLA8XXX_DEV_FAILED:
+			ha->flags.nic_core_reset_owner = 0;
+			qla8044_idc_unlock(ha);
+			qla8xxx_dev_failed_handler(vha);
+			rval = QLA_FUNCTION_FAILED;
+			qla8044_idc_lock(ha);
+			goto exit;
+		default:
+			qla8044_idc_unlock(ha);
+			qla8xxx_dev_failed_handler(vha);
+			rval = QLA_FUNCTION_FAILED;
+			qla8044_idc_lock(ha);
+			goto exit;
+		}
+	}
+exit:
+	qla8044_idc_unlock(ha);
+
+exit_error:
+	return rval;
+}
+
+/**
+ * qla4_8xxx_check_temp - Check the ISP82XX temperature.
+ * @ha: adapter block pointer.
+ *
+ * Note: The caller should not hold the idc lock.
+ **/
+static int
+qla8044_check_temp(struct scsi_qla_host *vha)
+{
+	uint32_t temp, temp_state, temp_val;
+	int status = QLA_SUCCESS;
+
+	temp = qla8044_rd_direct(vha, QLA8044_CRB_TEMP_STATE_INDEX);
+	temp_state = qla82xx_get_temp_state(temp);
+	temp_val = qla82xx_get_temp_val(temp);
+
+	if (temp_state == QLA82XX_TEMP_PANIC) {
+		ql_log(ql_log_warn, vha, 0xb0d2,
+		    "Device temperature %d degrees C"
+		    " exceeds maximum allowed. Hardware has been shut"
+		    " down\n", temp_val);
+		status = QLA_FUNCTION_FAILED;
+		return status;
+	} else if (temp_state == QLA82XX_TEMP_WARN) {
+		ql_log(ql_log_warn, vha, 0xb0d3,
+		    "Device temperature %d"
+		    " degrees C exceeds operating range."
+		    " Immediate action needed.\n", temp_val);
+	}
+	return 0;
+}
+
+/**
+ * qla8044_check_fw_alive  - Check firmware health
+ * @ha: Pointer to host adapter structure.
+ *
+ * Context: Interrupt
+ **/
+int
+qla8044_check_fw_alive(struct scsi_qla_host *vha)
+{
+	uint32_t fw_heartbeat_counter;
+	uint32_t halt_status1, halt_status2;
+	int status = QLA_SUCCESS;
+
+	fw_heartbeat_counter = qla8044_rd_direct(vha,
+	    QLA8044_PEG_ALIVE_COUNTER_INDEX);
+
+	/* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */
+	if (fw_heartbeat_counter == 0xffffffff) {
+		ql_dbg(ql_dbg_p3p, vha, 0xb0d4,
+		    "scsi%ld: %s: Device in frozen "
+		    "state, QLA82XX_PEG_ALIVE_COUNTER is 0xffffffff\n",
+		    vha->host_no, __func__);
+		return status;
+	}
+
+	if (vha->fw_heartbeat_counter == fw_heartbeat_counter) {
+		vha->seconds_since_last_heartbeat++;
+		/* FW not alive after 2 seconds */
+		if (vha->seconds_since_last_heartbeat == 2) {
+			vha->seconds_since_last_heartbeat = 0;
+			halt_status1 = qla8044_rd_direct(vha,
+			    QLA8044_PEG_HALT_STATUS1_INDEX);
+			halt_status2 = qla8044_rd_direct(vha,
+			    QLA8044_PEG_HALT_STATUS2_INDEX);
+
+			ql_log(ql_log_info, vha, 0xb0d5,
+			    "scsi(%ld): %s, ISP8044 "
+			    "Dumping hw/fw registers:\n"
+			    " PEG_HALT_STATUS1: 0x%x, "
+			    "PEG_HALT_STATUS2: 0x%x,\n",
+			    vha->host_no, __func__, halt_status1,
+			    halt_status2);
+			status = QLA_FUNCTION_FAILED;
+		}
+	} else
+		vha->seconds_since_last_heartbeat = 0;
+
+	vha->fw_heartbeat_counter = fw_heartbeat_counter;
+	return status;
+}
+
+void
+qla8044_watchdog(struct scsi_qla_host *vha)
+{
+	uint32_t dev_state, halt_status;
+	int halt_status_unrecoverable = 0;
+	struct qla_hw_data *ha = vha->hw;
+
+	/* don't poll if reset is going on or FW hang in quiescent state */
+	if (!(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
+	    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
+	    test_bit(ISP_ABORT_RETRY, &vha->dpc_flags) ||
+	    test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags))) {
+		dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
+
+		if (qla8044_check_temp(vha)) {
+			set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
+			ha->flags.isp82xx_fw_hung = 1;
+			qla2xxx_wake_dpc(vha);
+		} else if (dev_state == QLA8XXX_DEV_NEED_RESET &&
+			   !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) {
+			ql_log(ql_log_info, vha, 0xb0d6,
+			    "%s: HW State: NEED RESET!\n",
+			    __func__);
+			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+			qla2xxx_wake_dpc(vha);
+		} else if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT &&
+		    !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) {
+			ql_log(ql_log_info, vha, 0xb0d7,
+			    "%s: HW State: NEED QUIES detected!\n",
+			    __func__);
+			set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
+			qla2xxx_wake_dpc(vha);
+		} else  {
+			/* Check firmware health */
+			if (qla8044_check_fw_alive(vha)) {
+				halt_status = qla8044_rd_direct(vha,
+					QLA8044_PEG_HALT_STATUS1_INDEX);
+				if (halt_status &
+				    QLA8044_HALT_STATUS_FW_RESET) {
+					ql_log(ql_log_fatal, vha,
+					    0xb0d8, "%s: Firmware "
+					    "error detected device "
+					    "is being reset\n",
+					    __func__);
+				} else if (halt_status &
+					    QLA8044_HALT_STATUS_UNRECOVERABLE) {
+						halt_status_unrecoverable = 1;
+				}
+
+				/* Since we cannot change dev_state in interrupt
+				 * context, set appropriate DPC flag then wakeup
+				 *  DPC */
+				if (halt_status_unrecoverable) {
+					set_bit(ISP_UNRECOVERABLE,
+					    &vha->dpc_flags);
+				} else {
+					if (dev_state ==
+					    QLA8XXX_DEV_QUIESCENT) {
+						set_bit(FCOE_CTX_RESET_NEEDED,
+						    &vha->dpc_flags);
+						ql_log(ql_log_info, vha, 0xb0d9,
+						    "%s: FW CONTEXT Reset "
+						    "needed!\n", __func__);
+					} else {
+						ql_log(ql_log_info, vha,
+						    0xb0da, "%s: "
+						    "detect abort needed\n",
+						    __func__);
+						set_bit(ISP_ABORT_NEEDED,
+						    &vha->dpc_flags);
+						qla82xx_clear_pending_mbx(vha);
+					}
+				}
+				ha->flags.isp82xx_fw_hung = 1;
+				ql_log(ql_log_warn, vha, 0xb10a,
+				    "Firmware hung.\n");
+				qla2xxx_wake_dpc(vha);
+			}
+		}
+
+	}
+}
+
+static int
+qla8044_minidump_process_control(struct scsi_qla_host *vha,
+    struct qla8044_minidump_entry_hdr *entry_hdr)
+{
+	struct qla8044_minidump_entry_crb *crb_entry;
+	uint32_t read_value, opcode, poll_time, addr, index;
+	uint32_t crb_addr, rval = QLA_SUCCESS;
+	unsigned long wtime;
+	struct qla8044_minidump_template_hdr *tmplt_hdr;
+	int i;
+	struct qla_hw_data *ha = vha->hw;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0dd, "Entering fn: %s\n", __func__);
+	tmplt_hdr = (struct qla8044_minidump_template_hdr *)
+		ha->md_tmplt_hdr;
+	crb_entry = (struct qla8044_minidump_entry_crb *)entry_hdr;
+
+	crb_addr = crb_entry->addr;
+	for (i = 0; i < crb_entry->op_count; i++) {
+		opcode = crb_entry->crb_ctrl.opcode;
+
+		if (opcode & QLA82XX_DBG_OPCODE_WR) {
+			qla8044_wr_reg_indirect(vha, crb_addr,
+			    crb_entry->value_1);
+			opcode &= ~QLA82XX_DBG_OPCODE_WR;
+		}
+
+		if (opcode & QLA82XX_DBG_OPCODE_RW) {
+			qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
+			qla8044_wr_reg_indirect(vha, crb_addr, read_value);
+			opcode &= ~QLA82XX_DBG_OPCODE_RW;
+		}
+
+		if (opcode & QLA82XX_DBG_OPCODE_AND) {
+			qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
+			read_value &= crb_entry->value_2;
+			opcode &= ~QLA82XX_DBG_OPCODE_AND;
+			if (opcode & QLA82XX_DBG_OPCODE_OR) {
+				read_value |= crb_entry->value_3;
+				opcode &= ~QLA82XX_DBG_OPCODE_OR;
+			}
+			qla8044_wr_reg_indirect(vha, crb_addr, read_value);
+		}
+		if (opcode & QLA82XX_DBG_OPCODE_OR) {
+			qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
+			read_value |= crb_entry->value_3;
+			qla8044_wr_reg_indirect(vha, crb_addr, read_value);
+			opcode &= ~QLA82XX_DBG_OPCODE_OR;
+		}
+		if (opcode & QLA82XX_DBG_OPCODE_POLL) {
+			poll_time = crb_entry->crb_strd.poll_timeout;
+			wtime = jiffies + poll_time;
+			qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
+
+			do {
+				if ((read_value & crb_entry->value_2) ==
+				    crb_entry->value_1) {
+					break;
+				} else if (time_after_eq(jiffies, wtime)) {
+					/* capturing dump failed */
+					rval = QLA_FUNCTION_FAILED;
+					break;
+				} else {
+					qla8044_rd_reg_indirect(vha,
+					    crb_addr, &read_value);
+				}
+			} while (1);
+			opcode &= ~QLA82XX_DBG_OPCODE_POLL;
+		}
+
+		if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) {
+			if (crb_entry->crb_strd.state_index_a) {
+				index = crb_entry->crb_strd.state_index_a;
+				addr = tmplt_hdr->saved_state_array[index];
+			} else {
+				addr = crb_addr;
+			}
+
+			qla8044_rd_reg_indirect(vha, addr, &read_value);
+			index = crb_entry->crb_ctrl.state_index_v;
+			tmplt_hdr->saved_state_array[index] = read_value;
+			opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE;
+		}
+
+		if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) {
+			if (crb_entry->crb_strd.state_index_a) {
+				index = crb_entry->crb_strd.state_index_a;
+				addr = tmplt_hdr->saved_state_array[index];
+			} else {
+				addr = crb_addr;
+			}
+
+			if (crb_entry->crb_ctrl.state_index_v) {
+				index = crb_entry->crb_ctrl.state_index_v;
+				read_value =
+				    tmplt_hdr->saved_state_array[index];
+			} else {
+				read_value = crb_entry->value_1;
+			}
+
+			qla8044_wr_reg_indirect(vha, addr, read_value);
+			opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE;
+		}
+
+		if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) {
+			index = crb_entry->crb_ctrl.state_index_v;
+			read_value = tmplt_hdr->saved_state_array[index];
+			read_value <<= crb_entry->crb_ctrl.shl;
+			read_value >>= crb_entry->crb_ctrl.shr;
+			if (crb_entry->value_2)
+				read_value &= crb_entry->value_2;
+			read_value |= crb_entry->value_3;
+			read_value += crb_entry->value_1;
+			tmplt_hdr->saved_state_array[index] = read_value;
+			opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE;
+		}
+		crb_addr += crb_entry->crb_strd.addr_stride;
+	}
+	return rval;
+}
+
+static void
+qla8044_minidump_process_rdcrb(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
+{
+	uint32_t r_addr, r_stride, loop_cnt, i, r_value;
+	struct qla8044_minidump_entry_crb *crb_hdr;
+	uint32_t *data_ptr = *d_ptr;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0de, "Entering fn: %s\n", __func__);
+	crb_hdr = (struct qla8044_minidump_entry_crb *)entry_hdr;
+	r_addr = crb_hdr->addr;
+	r_stride = crb_hdr->crb_strd.addr_stride;
+	loop_cnt = crb_hdr->op_count;
+
+	for (i = 0; i < loop_cnt; i++) {
+		qla8044_rd_reg_indirect(vha, r_addr, &r_value);
+		*data_ptr++ = r_addr;
+		*data_ptr++ = r_value;
+		r_addr += r_stride;
+	}
+	*d_ptr = data_ptr;
+}
+
+static int
+qla8044_minidump_process_rdmem(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
+{
+	uint32_t r_addr, r_value, r_data;
+	uint32_t i, j, loop_cnt;
+	struct qla8044_minidump_entry_rdmem *m_hdr;
+	unsigned long flags;
+	uint32_t *data_ptr = *d_ptr;
+	struct qla_hw_data *ha = vha->hw;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0df, "Entering fn: %s\n", __func__);
+	m_hdr = (struct qla8044_minidump_entry_rdmem *)entry_hdr;
+	r_addr = m_hdr->read_addr;
+	loop_cnt = m_hdr->read_data_size/16;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0f0,
+	    "[%s]: Read addr: 0x%x, read_data_size: 0x%x\n",
+	    __func__, r_addr, m_hdr->read_data_size);
+
+	if (r_addr & 0xf) {
+		ql_dbg(ql_dbg_p3p, vha, 0xb0f1,
+		    "[%s]: Read addr 0x%x not 16 bytes alligned\n",
+		    __func__, r_addr);
+		return QLA_FUNCTION_FAILED;
+	}
+
+	if (m_hdr->read_data_size % 16) {
+		ql_dbg(ql_dbg_p3p, vha, 0xb0f2,
+		    "[%s]: Read data[0x%x] not multiple of 16 bytes\n",
+		    __func__, m_hdr->read_data_size);
+		return QLA_FUNCTION_FAILED;
+	}
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0f3,
+	    "[%s]: rdmem_addr: 0x%x, read_data_size: 0x%x, loop_cnt: 0x%x\n",
+	    __func__, r_addr, m_hdr->read_data_size, loop_cnt);
+
+	write_lock_irqsave(&ha->hw_lock, flags);
+	for (i = 0; i < loop_cnt; i++) {
+		qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_ADDR_LO, r_addr);
+		r_value = 0;
+		qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_ADDR_HI, r_value);
+		r_value = MIU_TA_CTL_ENABLE;
+		qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL, r_value);
+		r_value = MIU_TA_CTL_START_ENABLE;
+		qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL, r_value);
+
+		for (j = 0; j < MAX_CTL_CHECK; j++) {
+			qla8044_rd_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL,
+			    &r_value);
+			if ((r_value & MIU_TA_CTL_BUSY) == 0)
+				break;
+		}
+
+		if (j >= MAX_CTL_CHECK) {
+			printk_ratelimited(KERN_ERR
+			    "%s: failed to read through agent\n", __func__);
+			write_unlock_irqrestore(&ha->hw_lock, flags);
+			return QLA_SUCCESS;
+		}
+
+		for (j = 0; j < 4; j++) {
+			qla8044_rd_reg_indirect(vha, MD_MIU_TEST_AGT_RDDATA[j],
+			    &r_data);
+			*data_ptr++ = r_data;
+		}
+
+		r_addr += 16;
+	}
+	write_unlock_irqrestore(&ha->hw_lock, flags);
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0f4,
+	    "Leaving fn: %s datacount: 0x%x\n",
+	     __func__, (loop_cnt * 16));
+
+	*d_ptr = data_ptr;
+	return QLA_SUCCESS;
+}
+
+/* ISP83xx flash read for _RDROM _BOARD */
+static uint32_t
+qla8044_minidump_process_rdrom(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
+{
+	uint32_t fl_addr, u32_count, rval;
+	struct qla8044_minidump_entry_rdrom *rom_hdr;
+	uint32_t *data_ptr = *d_ptr;
+
+	rom_hdr = (struct qla8044_minidump_entry_rdrom *)entry_hdr;
+	fl_addr = rom_hdr->read_addr;
+	u32_count = (rom_hdr->read_data_size)/sizeof(uint32_t);
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0f5, "[%s]: fl_addr: 0x%x, count: 0x%x\n",
+	    __func__, fl_addr, u32_count);
+
+	rval = qla8044_lockless_flash_read_u32(vha, fl_addr,
+	    (u8 *)(data_ptr), u32_count);
+
+	if (rval != QLA_SUCCESS) {
+		ql_log(ql_log_fatal, vha, 0xb0f6,
+		    "%s: Flash Read Error,Count=%d\n", __func__, u32_count);
+		return QLA_FUNCTION_FAILED;
+	} else {
+		data_ptr += u32_count;
+		*d_ptr = data_ptr;
+		return QLA_SUCCESS;
+	}
+}
+
+static void
+qla8044_mark_entry_skipped(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr, int index)
+{
+	entry_hdr->d_ctrl.driver_flags |= QLA82XX_DBG_SKIPPED_FLAG;
+
+	ql_log(ql_log_info, vha, 0xb0f7,
+	    "scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n",
+	    vha->host_no, index, entry_hdr->entry_type,
+	    entry_hdr->d_ctrl.entry_capture_mask);
+}
+
+static int
+qla8044_minidump_process_l2tag(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr,
+				 uint32_t **d_ptr)
+{
+	uint32_t addr, r_addr, c_addr, t_r_addr;
+	uint32_t i, k, loop_count, t_value, r_cnt, r_value;
+	unsigned long p_wait, w_time, p_mask;
+	uint32_t c_value_w, c_value_r;
+	struct qla8044_minidump_entry_cache *cache_hdr;
+	int rval = QLA_FUNCTION_FAILED;
+	uint32_t *data_ptr = *d_ptr;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0f8, "Entering fn: %s\n", __func__);
+	cache_hdr = (struct qla8044_minidump_entry_cache *)entry_hdr;
+
+	loop_count = cache_hdr->op_count;
+	r_addr = cache_hdr->read_addr;
+	c_addr = cache_hdr->control_addr;
+	c_value_w = cache_hdr->cache_ctrl.write_value;
+
+	t_r_addr = cache_hdr->tag_reg_addr;
+	t_value = cache_hdr->addr_ctrl.init_tag_value;
+	r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
+	p_wait = cache_hdr->cache_ctrl.poll_wait;
+	p_mask = cache_hdr->cache_ctrl.poll_mask;
+
+	for (i = 0; i < loop_count; i++) {
+		qla8044_wr_reg_indirect(vha, t_r_addr, t_value);
+		if (c_value_w)
+			qla8044_wr_reg_indirect(vha, c_addr, c_value_w);
+
+		if (p_mask) {
+			w_time = jiffies + p_wait;
+			do {
+				qla8044_rd_reg_indirect(vha, c_addr,
+				    &c_value_r);
+				if ((c_value_r & p_mask) == 0) {
+					break;
+				} else if (time_after_eq(jiffies, w_time)) {
+					/* capturing dump failed */
+					return rval;
+				}
+			} while (1);
+		}
+
+		addr = r_addr;
+		for (k = 0; k < r_cnt; k++) {
+			qla8044_rd_reg_indirect(vha, addr, &r_value);
+			*data_ptr++ = r_value;
+			addr += cache_hdr->read_ctrl.read_addr_stride;
+		}
+		t_value += cache_hdr->addr_ctrl.tag_value_stride;
+	}
+	*d_ptr = data_ptr;
+	return QLA_SUCCESS;
+}
+
+static void
+qla8044_minidump_process_l1cache(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
+{
+	uint32_t addr, r_addr, c_addr, t_r_addr;
+	uint32_t i, k, loop_count, t_value, r_cnt, r_value;
+	uint32_t c_value_w;
+	struct qla8044_minidump_entry_cache *cache_hdr;
+	uint32_t *data_ptr = *d_ptr;
+
+	cache_hdr = (struct qla8044_minidump_entry_cache *)entry_hdr;
+	loop_count = cache_hdr->op_count;
+	r_addr = cache_hdr->read_addr;
+	c_addr = cache_hdr->control_addr;
+	c_value_w = cache_hdr->cache_ctrl.write_value;
+
+	t_r_addr = cache_hdr->tag_reg_addr;
+	t_value = cache_hdr->addr_ctrl.init_tag_value;
+	r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
+
+	for (i = 0; i < loop_count; i++) {
+		qla8044_wr_reg_indirect(vha, t_r_addr, t_value);
+		qla8044_wr_reg_indirect(vha, c_addr, c_value_w);
+		addr = r_addr;
+		for (k = 0; k < r_cnt; k++) {
+			qla8044_rd_reg_indirect(vha, addr, &r_value);
+			*data_ptr++ = r_value;
+			addr += cache_hdr->read_ctrl.read_addr_stride;
+		}
+		t_value += cache_hdr->addr_ctrl.tag_value_stride;
+	}
+	*d_ptr = data_ptr;
+}
+
+static void
+qla8044_minidump_process_rdocm(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
+{
+	uint32_t r_addr, r_stride, loop_cnt, i, r_value;
+	struct qla8044_minidump_entry_rdocm *ocm_hdr;
+	uint32_t *data_ptr = *d_ptr;
+	struct qla_hw_data *ha = vha->hw;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0f9, "Entering fn: %s\n", __func__);
+
+	ocm_hdr = (struct qla8044_minidump_entry_rdocm *)entry_hdr;
+	r_addr = ocm_hdr->read_addr;
+	r_stride = ocm_hdr->read_addr_stride;
+	loop_cnt = ocm_hdr->op_count;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0fa,
+	    "[%s]: r_addr: 0x%x, r_stride: 0x%x, loop_cnt: 0x%x\n",
+	    __func__, r_addr, r_stride, loop_cnt);
+
+	for (i = 0; i < loop_cnt; i++) {
+		r_value = readl((void __iomem *)(r_addr + ha->nx_pcibase));
+		*data_ptr++ = r_value;
+		r_addr += r_stride;
+	}
+	ql_dbg(ql_dbg_p3p, vha, 0xb0fb, "Leaving fn: %s datacount: 0x%lx\n",
+	    __func__, (long unsigned int) (loop_cnt * sizeof(uint32_t)));
+
+	*d_ptr = data_ptr;
+}
+
+static void
+qla8044_minidump_process_rdmux(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr,
+	uint32_t **d_ptr)
+{
+	uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value;
+	struct qla8044_minidump_entry_mux *mux_hdr;
+	uint32_t *data_ptr = *d_ptr;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0fc, "Entering fn: %s\n", __func__);
+
+	mux_hdr = (struct qla8044_minidump_entry_mux *)entry_hdr;
+	r_addr = mux_hdr->read_addr;
+	s_addr = mux_hdr->select_addr;
+	s_stride = mux_hdr->select_value_stride;
+	s_value = mux_hdr->select_value;
+	loop_cnt = mux_hdr->op_count;
+
+	for (i = 0; i < loop_cnt; i++) {
+		qla8044_wr_reg_indirect(vha, s_addr, s_value);
+		qla8044_rd_reg_indirect(vha, r_addr, &r_value);
+		*data_ptr++ = s_value;
+		*data_ptr++ = r_value;
+		s_value += s_stride;
+	}
+	*d_ptr = data_ptr;
+}
+
+static void
+qla8044_minidump_process_queue(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr,
+	uint32_t **d_ptr)
+{
+	uint32_t s_addr, r_addr;
+	uint32_t r_stride, r_value, r_cnt, qid = 0;
+	uint32_t i, k, loop_cnt;
+	struct qla8044_minidump_entry_queue *q_hdr;
+	uint32_t *data_ptr = *d_ptr;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb0fd, "Entering fn: %s\n", __func__);
+	q_hdr = (struct qla8044_minidump_entry_queue *)entry_hdr;
+	s_addr = q_hdr->select_addr;
+	r_cnt = q_hdr->rd_strd.read_addr_cnt;
+	r_stride = q_hdr->rd_strd.read_addr_stride;
+	loop_cnt = q_hdr->op_count;
+
+	for (i = 0; i < loop_cnt; i++) {
+		qla8044_wr_reg_indirect(vha, s_addr, qid);
+		r_addr = q_hdr->read_addr;
+		for (k = 0; k < r_cnt; k++) {
+			qla8044_rd_reg_indirect(vha, r_addr, &r_value);
+			*data_ptr++ = r_value;
+			r_addr += r_stride;
+		}
+		qid += q_hdr->q_strd.queue_id_stride;
+	}
+	*d_ptr = data_ptr;
+}
+
+/* ISP83xx functions to process new minidump entries... */
+static uint32_t
+qla8044_minidump_process_pollrd(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr,
+	uint32_t **d_ptr)
+{
+	uint32_t r_addr, s_addr, s_value, r_value, poll_wait, poll_mask;
+	uint16_t s_stride, i;
+	struct qla8044_minidump_entry_pollrd *pollrd_hdr;
+	uint32_t *data_ptr = *d_ptr;
+
+	pollrd_hdr = (struct qla8044_minidump_entry_pollrd *) entry_hdr;
+	s_addr = pollrd_hdr->select_addr;
+	r_addr = pollrd_hdr->read_addr;
+	s_value = pollrd_hdr->select_value;
+	s_stride = pollrd_hdr->select_value_stride;
+
+	poll_wait = pollrd_hdr->poll_wait;
+	poll_mask = pollrd_hdr->poll_mask;
+
+	for (i = 0; i < pollrd_hdr->op_count; i++) {
+		qla8044_wr_reg_indirect(vha, s_addr, s_value);
+		poll_wait = pollrd_hdr->poll_wait;
+		while (1) {
+			qla8044_rd_reg_indirect(vha, s_addr, &r_value);
+			if ((r_value & poll_mask) != 0) {
+				break;
+			} else {
+				usleep_range(1000, 1100);
+				if (--poll_wait == 0) {
+					ql_log(ql_log_fatal, vha, 0xb0fe,
+					    "%s: TIMEOUT\n", __func__);
+					goto error;
+				}
+			}
+		}
+		qla8044_rd_reg_indirect(vha, r_addr, &r_value);
+		*data_ptr++ = s_value;
+		*data_ptr++ = r_value;
+
+		s_value += s_stride;
+	}
+	*d_ptr = data_ptr;
+	return QLA_SUCCESS;
+
+error:
+	return QLA_FUNCTION_FAILED;
+}
+
+static void
+qla8044_minidump_process_rdmux2(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
+{
+	uint32_t sel_val1, sel_val2, t_sel_val, data, i;
+	uint32_t sel_addr1, sel_addr2, sel_val_mask, read_addr;
+	struct qla8044_minidump_entry_rdmux2 *rdmux2_hdr;
+	uint32_t *data_ptr = *d_ptr;
+
+	rdmux2_hdr = (struct qla8044_minidump_entry_rdmux2 *) entry_hdr;
+	sel_val1 = rdmux2_hdr->select_value_1;
+	sel_val2 = rdmux2_hdr->select_value_2;
+	sel_addr1 = rdmux2_hdr->select_addr_1;
+	sel_addr2 = rdmux2_hdr->select_addr_2;
+	sel_val_mask = rdmux2_hdr->select_value_mask;
+	read_addr = rdmux2_hdr->read_addr;
+
+	for (i = 0; i < rdmux2_hdr->op_count; i++) {
+		qla8044_wr_reg_indirect(vha, sel_addr1, sel_val1);
+		t_sel_val = sel_val1 & sel_val_mask;
+		*data_ptr++ = t_sel_val;
+
+		qla8044_wr_reg_indirect(vha, sel_addr2, t_sel_val);
+		qla8044_rd_reg_indirect(vha, read_addr, &data);
+
+		*data_ptr++ = data;
+
+		qla8044_wr_reg_indirect(vha, sel_addr1, sel_val2);
+		t_sel_val = sel_val2 & sel_val_mask;
+		*data_ptr++ = t_sel_val;
+
+		qla8044_wr_reg_indirect(vha, sel_addr2, t_sel_val);
+		qla8044_rd_reg_indirect(vha, read_addr, &data);
+
+		*data_ptr++ = data;
+
+		sel_val1 += rdmux2_hdr->select_value_stride;
+		sel_val2 += rdmux2_hdr->select_value_stride;
+	}
+
+	*d_ptr = data_ptr;
+}
+
+static uint32_t
+qla8044_minidump_process_pollrdmwr(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr,
+	uint32_t **d_ptr)
+{
+	uint32_t poll_wait, poll_mask, r_value, data;
+	uint32_t addr_1, addr_2, value_1, value_2;
+	struct qla8044_minidump_entry_pollrdmwr *poll_hdr;
+	uint32_t *data_ptr = *d_ptr;
+
+	poll_hdr = (struct qla8044_minidump_entry_pollrdmwr *) entry_hdr;
+	addr_1 = poll_hdr->addr_1;
+	addr_2 = poll_hdr->addr_2;
+	value_1 = poll_hdr->value_1;
+	value_2 = poll_hdr->value_2;
+	poll_mask = poll_hdr->poll_mask;
+
+	qla8044_wr_reg_indirect(vha, addr_1, value_1);
+
+	poll_wait = poll_hdr->poll_wait;
+	while (1) {
+		qla8044_rd_reg_indirect(vha, addr_1, &r_value);
+
+		if ((r_value & poll_mask) != 0) {
+			break;
+		} else {
+			usleep_range(1000, 1100);
+			if (--poll_wait == 0) {
+				ql_log(ql_log_fatal, vha, 0xb0ff,
+				    "%s: TIMEOUT\n", __func__);
+				goto error;
+			}
+		}
+	}
+
+	qla8044_rd_reg_indirect(vha, addr_2, &data);
+	data &= poll_hdr->modify_mask;
+	qla8044_wr_reg_indirect(vha, addr_2, data);
+	qla8044_wr_reg_indirect(vha, addr_1, value_2);
+
+	poll_wait = poll_hdr->poll_wait;
+	while (1) {
+		qla8044_rd_reg_indirect(vha, addr_1, &r_value);
+
+		if ((r_value & poll_mask) != 0) {
+			break;
+		} else {
+			usleep_range(1000, 1100);
+			if (--poll_wait == 0) {
+				ql_log(ql_log_fatal, vha, 0xb100,
+				    "%s: TIMEOUT2\n", __func__);
+				goto error;
+			}
+		}
+	}
+
+	*data_ptr++ = addr_2;
+	*data_ptr++ = data;
+
+	*d_ptr = data_ptr;
+
+	return QLA_SUCCESS;
+
+error:
+	return QLA_FUNCTION_FAILED;
+}
+
+#define ISP8044_PEX_DMA_ENGINE_INDEX		8
+#define ISP8044_PEX_DMA_BASE_ADDRESS		0x77320000
+#define ISP8044_PEX_DMA_NUM_OFFSET		0x10000
+#define ISP8044_PEX_DMA_CMD_ADDR_LOW		0x0
+#define ISP8044_PEX_DMA_CMD_ADDR_HIGH		0x04
+#define ISP8044_PEX_DMA_CMD_STS_AND_CNTRL	0x08
+
+#define ISP8044_PEX_DMA_READ_SIZE	(16 * 1024)
+#define ISP8044_PEX_DMA_MAX_WAIT	(100 * 100) /* Max wait of 100 msecs */
+
+static int
+qla8044_check_dma_engine_state(struct scsi_qla_host *vha)
+{
+	struct qla_hw_data *ha = vha->hw;
+	int rval = QLA_SUCCESS;
+	uint32_t dma_eng_num = 0, cmd_sts_and_cntrl = 0;
+	uint64_t dma_base_addr = 0;
+	struct qla8044_minidump_template_hdr *tmplt_hdr = NULL;
+
+	tmplt_hdr = ha->md_tmplt_hdr;
+	dma_eng_num =
+	    tmplt_hdr->saved_state_array[ISP8044_PEX_DMA_ENGINE_INDEX];
+	dma_base_addr = ISP8044_PEX_DMA_BASE_ADDRESS +
+		(dma_eng_num * ISP8044_PEX_DMA_NUM_OFFSET);
+
+	/* Read the pex-dma's command-status-and-control register. */
+	rval = qla8044_rd_reg_indirect(vha,
+	    (dma_base_addr + ISP8044_PEX_DMA_CMD_STS_AND_CNTRL),
+	    &cmd_sts_and_cntrl);
+	if (rval)
+		return QLA_FUNCTION_FAILED;
+
+	/* Check if requested pex-dma engine is available. */
+	if (cmd_sts_and_cntrl & BIT_31)
+		return QLA_SUCCESS;
+
+	return QLA_FUNCTION_FAILED;
+}
+
+static int
+qla8044_start_pex_dma(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_rdmem_pex_dma *m_hdr)
+{
+	struct qla_hw_data *ha = vha->hw;
+	int rval = QLA_SUCCESS, wait = 0;
+	uint32_t dma_eng_num = 0, cmd_sts_and_cntrl = 0;
+	uint64_t dma_base_addr = 0;
+	struct qla8044_minidump_template_hdr *tmplt_hdr = NULL;
+
+	tmplt_hdr = ha->md_tmplt_hdr;
+	dma_eng_num =
+	    tmplt_hdr->saved_state_array[ISP8044_PEX_DMA_ENGINE_INDEX];
+	dma_base_addr = ISP8044_PEX_DMA_BASE_ADDRESS +
+		(dma_eng_num * ISP8044_PEX_DMA_NUM_OFFSET);
+
+	rval = qla8044_wr_reg_indirect(vha,
+	    dma_base_addr + ISP8044_PEX_DMA_CMD_ADDR_LOW,
+	    m_hdr->desc_card_addr);
+	if (rval)
+		goto error_exit;
+
+	rval = qla8044_wr_reg_indirect(vha,
+	    dma_base_addr + ISP8044_PEX_DMA_CMD_ADDR_HIGH, 0);
+	if (rval)
+		goto error_exit;
+
+	rval = qla8044_wr_reg_indirect(vha,
+	    dma_base_addr + ISP8044_PEX_DMA_CMD_STS_AND_CNTRL,
+	    m_hdr->start_dma_cmd);
+	if (rval)
+		goto error_exit;
+
+	/* Wait for dma operation to complete. */
+	for (wait = 0; wait < ISP8044_PEX_DMA_MAX_WAIT; wait++) {
+		rval = qla8044_rd_reg_indirect(vha,
+		    (dma_base_addr + ISP8044_PEX_DMA_CMD_STS_AND_CNTRL),
+		    &cmd_sts_and_cntrl);
+		if (rval)
+			goto error_exit;
+
+		if ((cmd_sts_and_cntrl & BIT_1) == 0)
+			break;
+
+		udelay(10);
+	}
+
+	/* Wait a max of 100 ms, otherwise fallback to rdmem entry read */
+	if (wait >= ISP8044_PEX_DMA_MAX_WAIT) {
+		rval = QLA_FUNCTION_FAILED;
+		goto error_exit;
+	}
+
+error_exit:
+	return rval;
+}
+
+static int
+qla8044_minidump_pex_dma_read(struct scsi_qla_host *vha,
+	struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
+{
+	struct qla_hw_data *ha = vha->hw;
+	int rval = QLA_SUCCESS;
+	struct qla8044_minidump_entry_rdmem_pex_dma *m_hdr = NULL;
+	uint32_t chunk_size, read_size;
+	uint8_t *data_ptr = (uint8_t *)*d_ptr;
+	void *rdmem_buffer = NULL;
+	dma_addr_t rdmem_dma;
+	struct qla8044_pex_dma_descriptor dma_desc;
+
+	rval = qla8044_check_dma_engine_state(vha);
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_p3p, vha, 0xb147,
+		    "DMA engine not available. Fallback to rdmem-read.\n");
+		return QLA_FUNCTION_FAILED;
+	}
+
+	m_hdr = (void *)entry_hdr;
+
+	rdmem_buffer = dma_alloc_coherent(&ha->pdev->dev,
+	    ISP8044_PEX_DMA_READ_SIZE, &rdmem_dma, GFP_KERNEL);
+	if (!rdmem_buffer) {
+		ql_dbg(ql_dbg_p3p, vha, 0xb148,
+		    "Unable to allocate rdmem dma buffer\n");
+		return QLA_FUNCTION_FAILED;
+	}
+
+	/* Prepare pex-dma descriptor to be written to MS memory. */
+	/* dma-desc-cmd layout:
+	 *		0-3: dma-desc-cmd 0-3
+	 *		4-7: pcid function number
+	 *		8-15: dma-desc-cmd 8-15
+	 * dma_bus_addr: dma buffer address
+	 * cmd.read_data_size: amount of data-chunk to be read.
+	 */
+	dma_desc.cmd.dma_desc_cmd = (m_hdr->dma_desc_cmd & 0xff0f);
+	dma_desc.cmd.dma_desc_cmd |=
+	    ((PCI_FUNC(ha->pdev->devfn) & 0xf) << 0x4);
+
+	dma_desc.dma_bus_addr = rdmem_dma;
+	dma_desc.cmd.read_data_size = chunk_size = ISP8044_PEX_DMA_READ_SIZE;
+	read_size = 0;
+
+	/*
+	 * Perform rdmem operation using pex-dma.
+	 * Prepare dma in chunks of ISP8044_PEX_DMA_READ_SIZE.
+	 */
+	while (read_size < m_hdr->read_data_size) {
+		if (m_hdr->read_data_size - read_size <
+		    ISP8044_PEX_DMA_READ_SIZE) {
+			chunk_size = (m_hdr->read_data_size - read_size);
+			dma_desc.cmd.read_data_size = chunk_size;
+		}
+
+		dma_desc.src_addr = m_hdr->read_addr + read_size;
+
+		/* Prepare: Write pex-dma descriptor to MS memory. */
+		rval = qla8044_ms_mem_write_128b(vha,
+		    m_hdr->desc_card_addr, (void *)&dma_desc,
+		    (sizeof(struct qla8044_pex_dma_descriptor)/16));
+		if (rval) {
+			ql_log(ql_log_warn, vha, 0xb14a,
+			    "%s: Error writing rdmem-dma-init to MS !!!\n",
+			    __func__);
+			goto error_exit;
+		}
+		ql_dbg(ql_dbg_p3p, vha, 0xb14b,
+		    "%s: Dma-descriptor: Instruct for rdmem dma "
+		    "(chunk_size 0x%x).\n", __func__, chunk_size);
+
+		/* Execute: Start pex-dma operation. */
+		rval = qla8044_start_pex_dma(vha, m_hdr);
+		if (rval)
+			goto error_exit;
+
+		memcpy(data_ptr, rdmem_buffer, chunk_size);
+		data_ptr += chunk_size;
+		read_size += chunk_size;
+	}
+
+	*d_ptr = (void *)data_ptr;
+
+error_exit:
+	if (rdmem_buffer)
+		dma_free_coherent(&ha->pdev->dev, ISP8044_PEX_DMA_READ_SIZE,
+		    rdmem_buffer, rdmem_dma);
+
+	return rval;
+}
+
+/*
+ *
+ * qla8044_collect_md_data - Retrieve firmware minidump data.
+ * @ha: pointer to adapter structure
+ **/
+int
+qla8044_collect_md_data(struct scsi_qla_host *vha)
+{
+	int num_entry_hdr = 0;
+	struct qla8044_minidump_entry_hdr *entry_hdr;
+	struct qla8044_minidump_template_hdr *tmplt_hdr;
+	uint32_t *data_ptr;
+	uint32_t data_collected = 0, f_capture_mask;
+	int i, rval = QLA_FUNCTION_FAILED;
+	uint64_t now;
+	uint32_t timestamp, idc_control;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (!ha->md_dump) {
+		ql_log(ql_log_info, vha, 0xb101,
+		    "%s(%ld) No buffer to dump\n",
+		    __func__, vha->host_no);
+		return rval;
+	}
+
+	if (ha->fw_dumped) {
+		ql_log(ql_log_warn, vha, 0xb10d,
+		    "Firmware has been previously dumped (%p) "
+		    "-- ignoring request.\n", ha->fw_dump);
+		goto md_failed;
+	}
+
+	ha->fw_dumped = 0;
+
+	if (!ha->md_tmplt_hdr || !ha->md_dump) {
+		ql_log(ql_log_warn, vha, 0xb10e,
+		    "Memory not allocated for minidump capture\n");
+		goto md_failed;
+	}
+
+	qla8044_idc_lock(ha);
+	idc_control = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
+	if (idc_control & GRACEFUL_RESET_BIT1) {
+		ql_log(ql_log_warn, vha, 0xb112,
+		    "Forced reset from application, "
+		    "ignore minidump capture\n");
+		qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL,
+		    (idc_control & ~GRACEFUL_RESET_BIT1));
+		qla8044_idc_unlock(ha);
+
+		goto md_failed;
+	}
+	qla8044_idc_unlock(ha);
+
+	if (qla82xx_validate_template_chksum(vha)) {
+		ql_log(ql_log_info, vha, 0xb109,
+		    "Template checksum validation error\n");
+		goto md_failed;
+	}
+
+	tmplt_hdr = (struct qla8044_minidump_template_hdr *)
+		ha->md_tmplt_hdr;
+	data_ptr = (uint32_t *)((uint8_t *)ha->md_dump);
+	num_entry_hdr = tmplt_hdr->num_of_entries;
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb11a,
+	    "Capture Mask obtained: 0x%x\n", tmplt_hdr->capture_debug_level);
+
+	f_capture_mask = tmplt_hdr->capture_debug_level & 0xFF;
+
+	/* Validate whether required debug level is set */
+	if ((f_capture_mask & 0x3) != 0x3) {
+		ql_log(ql_log_warn, vha, 0xb10f,
+		    "Minimum required capture mask[0x%x] level not set\n",
+		    f_capture_mask);
+
+	}
+	tmplt_hdr->driver_capture_mask = ql2xmdcapmask;
+	ql_log(ql_log_info, vha, 0xb102,
+	    "[%s]: starting data ptr: %p\n",
+	   __func__, data_ptr);
+	ql_log(ql_log_info, vha, 0xb10b,
+	   "[%s]: no of entry headers in Template: 0x%x\n",
+	   __func__, num_entry_hdr);
+	ql_log(ql_log_info, vha, 0xb10c,
+	    "[%s]: Total_data_size 0x%x, %d obtained\n",
+	   __func__, ha->md_dump_size, ha->md_dump_size);
+
+	/* Update current timestamp before taking dump */
+	now = get_jiffies_64();
+	timestamp = (u32)(jiffies_to_msecs(now) / 1000);
+	tmplt_hdr->driver_timestamp = timestamp;
+
+	entry_hdr = (struct qla8044_minidump_entry_hdr *)
+		(((uint8_t *)ha->md_tmplt_hdr) + tmplt_hdr->first_entry_offset);
+	tmplt_hdr->saved_state_array[QLA8044_SS_OCM_WNDREG_INDEX] =
+	    tmplt_hdr->ocm_window_reg[ha->portnum];
+
+	/* Walk through the entry headers - validate/perform required action */
+	for (i = 0; i < num_entry_hdr; i++) {
+		if (data_collected > ha->md_dump_size) {
+			ql_log(ql_log_info, vha, 0xb103,
+			    "Data collected: [0x%x], "
+			    "Total Dump size: [0x%x]\n",
+			    data_collected, ha->md_dump_size);
+			return rval;
+		}
+
+		if (!(entry_hdr->d_ctrl.entry_capture_mask &
+		      ql2xmdcapmask)) {
+			entry_hdr->d_ctrl.driver_flags |=
+			    QLA82XX_DBG_SKIPPED_FLAG;
+			goto skip_nxt_entry;
+		}
+
+		ql_dbg(ql_dbg_p3p, vha, 0xb104,
+		    "Data collected: [0x%x], Dump size left:[0x%x]\n",
+		    data_collected,
+		    (ha->md_dump_size - data_collected));
+
+		/* Decode the entry type and take required action to capture
+		 * debug data
+		 */
+		switch (entry_hdr->entry_type) {
+		case QLA82XX_RDEND:
+			qla8044_mark_entry_skipped(vha, entry_hdr, i);
+			break;
+		case QLA82XX_CNTRL:
+			rval = qla8044_minidump_process_control(vha,
+			    entry_hdr);
+			if (rval != QLA_SUCCESS) {
+				qla8044_mark_entry_skipped(vha, entry_hdr, i);
+				goto md_failed;
+			}
+			break;
+		case QLA82XX_RDCRB:
+			qla8044_minidump_process_rdcrb(vha,
+			    entry_hdr, &data_ptr);
+			break;
+		case QLA82XX_RDMEM:
+			rval = qla8044_minidump_pex_dma_read(vha,
+			    entry_hdr, &data_ptr);
+			if (rval != QLA_SUCCESS) {
+				rval = qla8044_minidump_process_rdmem(vha,
+				    entry_hdr, &data_ptr);
+				if (rval != QLA_SUCCESS) {
+					qla8044_mark_entry_skipped(vha,
+					    entry_hdr, i);
+					goto md_failed;
+				}
+			}
+			break;
+		case QLA82XX_BOARD:
+		case QLA82XX_RDROM:
+			rval = qla8044_minidump_process_rdrom(vha,
+			    entry_hdr, &data_ptr);
+			if (rval != QLA_SUCCESS) {
+				qla8044_mark_entry_skipped(vha,
+				    entry_hdr, i);
+			}
+			break;
+		case QLA82XX_L2DTG:
+		case QLA82XX_L2ITG:
+		case QLA82XX_L2DAT:
+		case QLA82XX_L2INS:
+			rval = qla8044_minidump_process_l2tag(vha,
+			    entry_hdr, &data_ptr);
+			if (rval != QLA_SUCCESS) {
+				qla8044_mark_entry_skipped(vha, entry_hdr, i);
+				goto md_failed;
+			}
+			break;
+		case QLA8044_L1DTG:
+		case QLA8044_L1ITG:
+		case QLA82XX_L1DAT:
+		case QLA82XX_L1INS:
+			qla8044_minidump_process_l1cache(vha,
+			    entry_hdr, &data_ptr);
+			break;
+		case QLA82XX_RDOCM:
+			qla8044_minidump_process_rdocm(vha,
+			    entry_hdr, &data_ptr);
+			break;
+		case QLA82XX_RDMUX:
+			qla8044_minidump_process_rdmux(vha,
+			    entry_hdr, &data_ptr);
+			break;
+		case QLA82XX_QUEUE:
+			qla8044_minidump_process_queue(vha,
+			    entry_hdr, &data_ptr);
+			break;
+		case QLA8044_POLLRD:
+			rval = qla8044_minidump_process_pollrd(vha,
+			    entry_hdr, &data_ptr);
+			if (rval != QLA_SUCCESS)
+				qla8044_mark_entry_skipped(vha, entry_hdr, i);
+			break;
+		case QLA8044_RDMUX2:
+			qla8044_minidump_process_rdmux2(vha,
+			    entry_hdr, &data_ptr);
+			break;
+		case QLA8044_POLLRDMWR:
+			rval = qla8044_minidump_process_pollrdmwr(vha,
+			    entry_hdr, &data_ptr);
+			if (rval != QLA_SUCCESS)
+				qla8044_mark_entry_skipped(vha, entry_hdr, i);
+			break;
+		case QLA82XX_RDNOP:
+		default:
+			qla8044_mark_entry_skipped(vha, entry_hdr, i);
+			break;
+		}
+
+		data_collected = (uint8_t *)data_ptr -
+		    (uint8_t *)((uint8_t *)ha->md_dump);
+skip_nxt_entry:
+		/*
+		 * next entry in the template
+		 */
+		entry_hdr = (struct qla8044_minidump_entry_hdr *)
+		    (((uint8_t *)entry_hdr) + entry_hdr->entry_size);
+	}
+
+	if (data_collected != ha->md_dump_size) {
+		ql_log(ql_log_info, vha, 0xb105,
+		    "Dump data mismatch: Data collected: "
+		    "[0x%x], total_data_size:[0x%x]\n",
+		    data_collected, ha->md_dump_size);
+		goto md_failed;
+	}
+
+	ql_log(ql_log_info, vha, 0xb110,
+	    "Firmware dump saved to temp buffer (%ld/%p %ld/%p).\n",
+	    vha->host_no, ha->md_tmplt_hdr, vha->host_no, ha->md_dump);
+	ha->fw_dumped = 1;
+	qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
+
+
+	ql_log(ql_log_info, vha, 0xb106,
+	    "Leaving fn: %s Last entry: 0x%x\n",
+	    __func__, i);
+md_failed:
+	return rval;
+}
+
+void
+qla8044_get_minidump(struct scsi_qla_host *vha)
+{
+	struct qla_hw_data *ha = vha->hw;
+
+	if (!qla8044_collect_md_data(vha)) {
+		ha->fw_dumped = 1;
+	} else {
+		ql_log(ql_log_fatal, vha, 0xb0db,
+		    "%s: Unable to collect minidump\n",
+		    __func__);
+	}
+}
+
+static int
+qla8044_poll_flash_status_reg(struct scsi_qla_host *vha)
+{
+	uint32_t flash_status;
+	int retries = QLA8044_FLASH_READ_RETRY_COUNT;
+	int ret_val = QLA_SUCCESS;
+
+	while (retries--) {
+		ret_val = qla8044_rd_reg_indirect(vha, QLA8044_FLASH_STATUS,
+		    &flash_status);
+		if (ret_val) {
+			ql_log(ql_log_warn, vha, 0xb120,
+			    "%s: Failed to read FLASH_STATUS reg.\n",
+			    __func__);
+			break;
+		}
+		if ((flash_status & QLA8044_FLASH_STATUS_READY) ==
+		    QLA8044_FLASH_STATUS_READY)
+			break;
+		msleep(QLA8044_FLASH_STATUS_REG_POLL_DELAY);
+	}
+
+	if (!retries)
+		ret_val = QLA_FUNCTION_FAILED;
+
+	return ret_val;
+}
+
+static int
+qla8044_write_flash_status_reg(struct scsi_qla_host *vha,
+    uint32_t data)
+{
+	int ret_val = QLA_SUCCESS;
+	uint32_t cmd;
+
+	cmd = vha->hw->fdt_wrt_sts_reg_cmd;
+
+	ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
+	    QLA8044_FLASH_STATUS_WRITE_DEF_SIG | cmd);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb125,
+		    "%s: Failed to write to FLASH_ADDR.\n", __func__);
+		goto exit_func;
+	}
+
+	ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, data);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb126,
+		    "%s: Failed to write to FLASH_WRDATA.\n", __func__);
+		goto exit_func;
+	}
+
+	ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
+	    QLA8044_FLASH_SECOND_ERASE_MS_VAL);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb127,
+		    "%s: Failed to write to FLASH_CONTROL.\n", __func__);
+		goto exit_func;
+	}
+
+	ret_val = qla8044_poll_flash_status_reg(vha);
+	if (ret_val)
+		ql_log(ql_log_warn, vha, 0xb128,
+		    "%s: Error polling flash status reg.\n", __func__);
+
+exit_func:
+	return ret_val;
+}
+
+/*
+ * This function assumes that the flash lock is held.
+ */
+static int
+qla8044_unprotect_flash(scsi_qla_host_t *vha)
+{
+	int ret_val;
+	struct qla_hw_data *ha = vha->hw;
+
+	ret_val = qla8044_write_flash_status_reg(vha, ha->fdt_wrt_enable);
+	if (ret_val)
+		ql_log(ql_log_warn, vha, 0xb139,
+		    "%s: Write flash status failed.\n", __func__);
+
+	return ret_val;
+}
+
+/*
+ * This function assumes that the flash lock is held.
+ */
+static int
+qla8044_protect_flash(scsi_qla_host_t *vha)
+{
+	int ret_val;
+	struct qla_hw_data *ha = vha->hw;
+
+	ret_val = qla8044_write_flash_status_reg(vha, ha->fdt_wrt_disable);
+	if (ret_val)
+		ql_log(ql_log_warn, vha, 0xb13b,
+		    "%s: Write flash status failed.\n", __func__);
+
+	return ret_val;
+}
+
+
+static int
+qla8044_erase_flash_sector(struct scsi_qla_host *vha,
+    uint32_t sector_start_addr)
+{
+	uint32_t reversed_addr;
+	int ret_val = QLA_SUCCESS;
+
+	ret_val = qla8044_poll_flash_status_reg(vha);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb12e,
+		    "%s: Poll flash status after erase failed..\n", __func__);
+	}
+
+	reversed_addr = (((sector_start_addr & 0xFF) << 16) |
+	    (sector_start_addr & 0xFF00) |
+	    ((sector_start_addr & 0xFF0000) >> 16));
+
+	ret_val = qla8044_wr_reg_indirect(vha,
+	    QLA8044_FLASH_WRDATA, reversed_addr);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb12f,
+		    "%s: Failed to write to FLASH_WRDATA.\n", __func__);
+	}
+	ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
+	   QLA8044_FLASH_ERASE_SIG | vha->hw->fdt_erase_cmd);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb130,
+		    "%s: Failed to write to FLASH_ADDR.\n", __func__);
+	}
+	ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
+	    QLA8044_FLASH_LAST_ERASE_MS_VAL);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb131,
+		    "%s: Failed write to FLASH_CONTROL.\n", __func__);
+	}
+	ret_val = qla8044_poll_flash_status_reg(vha);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb132,
+		    "%s: Poll flash status failed.\n", __func__);
+	}
+
+
+	return ret_val;
+}
+
+/*
+ * qla8044_flash_write_u32 - Write data to flash
+ *
+ * @ha : Pointer to adapter structure
+ * addr : Flash address to write to
+ * p_data : Data to be written
+ *
+ * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
+ *
+ * NOTE: Lock should be held on entry
+ */
+static int
+qla8044_flash_write_u32(struct scsi_qla_host *vha, uint32_t addr,
+    uint32_t *p_data)
+{
+	int ret_val = QLA_SUCCESS;
+
+	ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
+	    0x00800000 | (addr >> 2));
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb134,
+		    "%s: Failed write to FLASH_ADDR.\n", __func__);
+		goto exit_func;
+	}
+	ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, *p_data);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb135,
+		    "%s: Failed write to FLASH_WRDATA.\n", __func__);
+		goto exit_func;
+	}
+	ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL, 0x3D);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb136,
+		    "%s: Failed write to FLASH_CONTROL.\n", __func__);
+		goto exit_func;
+	}
+	ret_val = qla8044_poll_flash_status_reg(vha);
+	if (ret_val) {
+		ql_log(ql_log_warn, vha, 0xb137,
+		    "%s: Poll flash status failed.\n", __func__);
+	}
+
+exit_func:
+	return ret_val;
+}
+
+static int
+qla8044_write_flash_buffer_mode(scsi_qla_host_t *vha, uint32_t *dwptr,
+    uint32_t faddr, uint32_t dwords)
+{
+	int ret = QLA_FUNCTION_FAILED;
+	uint32_t spi_val;
+
+	if (dwords < QLA8044_MIN_OPTROM_BURST_DWORDS ||
+	    dwords > QLA8044_MAX_OPTROM_BURST_DWORDS) {
+		ql_dbg(ql_dbg_user, vha, 0xb123,
+		    "Got unsupported dwords = 0x%x.\n",
+		    dwords);
+		return QLA_FUNCTION_FAILED;
+	}
+
+	qla8044_rd_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL, &spi_val);
+	qla8044_wr_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL,
+	    spi_val | QLA8044_FLASH_SPI_CTL);
+	qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
+	    QLA8044_FLASH_FIRST_TEMP_VAL);
+
+	/* First DWORD write to FLASH_WRDATA */
+	ret = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA,
+	    *dwptr++);
+	qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
+	    QLA8044_FLASH_FIRST_MS_PATTERN);
+
+	ret = qla8044_poll_flash_status_reg(vha);
+	if (ret) {
+		ql_log(ql_log_warn, vha, 0xb124,
+		    "%s: Failed.\n", __func__);
+		goto exit_func;
+	}
+
+	dwords--;
+
+	qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
+	    QLA8044_FLASH_SECOND_TEMP_VAL);
+
+
+	/* Second to N-1 DWORDS writes */
+	while (dwords != 1) {
+		qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, *dwptr++);
+		qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
+		    QLA8044_FLASH_SECOND_MS_PATTERN);
+		ret = qla8044_poll_flash_status_reg(vha);
+		if (ret) {
+			ql_log(ql_log_warn, vha, 0xb129,
+			    "%s: Failed.\n", __func__);
+			goto exit_func;
+		}
+		dwords--;
+	}
+
+	qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
+	    QLA8044_FLASH_FIRST_TEMP_VAL | (faddr >> 2));
+
+	/* Last DWORD write */
+	qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, *dwptr++);
+	qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
+	    QLA8044_FLASH_LAST_MS_PATTERN);
+	ret = qla8044_poll_flash_status_reg(vha);
+	if (ret) {
+		ql_log(ql_log_warn, vha, 0xb12a,
+		    "%s: Failed.\n", __func__);
+		goto exit_func;
+	}
+	qla8044_rd_reg_indirect(vha, QLA8044_FLASH_SPI_STATUS, &spi_val);
+
+	if ((spi_val & QLA8044_FLASH_SPI_CTL) == QLA8044_FLASH_SPI_CTL) {
+		ql_log(ql_log_warn, vha, 0xb12b,
+		    "%s: Failed.\n", __func__);
+		spi_val = 0;
+		/* Operation failed, clear error bit. */
+		qla8044_rd_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL,
+		    &spi_val);
+		qla8044_wr_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL,
+		    spi_val | QLA8044_FLASH_SPI_CTL);
+	}
+exit_func:
+	return ret;
+}
+
+static int
+qla8044_write_flash_dword_mode(scsi_qla_host_t *vha, uint32_t *dwptr,
+    uint32_t faddr, uint32_t dwords)
+{
+	int ret = QLA_FUNCTION_FAILED;
+	uint32_t liter;
+
+	for (liter = 0; liter < dwords; liter++, faddr += 4, dwptr++) {
+		ret = qla8044_flash_write_u32(vha, faddr, dwptr);
+		if (ret) {
+			ql_dbg(ql_dbg_p3p, vha, 0xb141,
+			    "%s: flash address=%x data=%x.\n", __func__,
+			     faddr, *dwptr);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+int
+qla8044_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
+    uint32_t offset, uint32_t length)
+{
+	int rval = QLA_FUNCTION_FAILED, i, burst_iter_count;
+	int dword_count, erase_sec_count;
+	uint32_t erase_offset;
+	uint8_t *p_cache, *p_src;
+
+	erase_offset = offset;
+
+	p_cache = kcalloc(length, sizeof(uint8_t), GFP_KERNEL);
+	if (!p_cache)
+		return QLA_FUNCTION_FAILED;
+
+	memcpy(p_cache, buf, length);
+	p_src = p_cache;
+	dword_count = length / sizeof(uint32_t);
+	/* Since the offset and legth are sector aligned, it will be always
+	 * multiple of burst_iter_count (64)
+	 */
+	burst_iter_count = dword_count / QLA8044_MAX_OPTROM_BURST_DWORDS;
+	erase_sec_count = length / QLA8044_SECTOR_SIZE;
+
+	/* Suspend HBA. */
+	scsi_block_requests(vha->host);
+	/* Lock and enable write for whole operation. */
+	qla8044_flash_lock(vha);
+	qla8044_unprotect_flash(vha);
+
+	/* Erasing the sectors */
+	for (i = 0; i < erase_sec_count; i++) {
+		rval = qla8044_erase_flash_sector(vha, erase_offset);
+		ql_dbg(ql_dbg_user, vha, 0xb138,
+		    "Done erase of sector=0x%x.\n",
+		    erase_offset);
+		if (rval) {
+			ql_log(ql_log_warn, vha, 0xb121,
+			    "Failed to erase the sector having address: "
+			    "0x%x.\n", erase_offset);
+			goto out;
+		}
+		erase_offset += QLA8044_SECTOR_SIZE;
+	}
+	ql_dbg(ql_dbg_user, vha, 0xb139,
+	    "Got write for addr = 0x%x length=0x%x.\n",
+	    offset, length);
+
+	for (i = 0; i < burst_iter_count; i++) {
+
+		/* Go with write. */
+		rval = qla8044_write_flash_buffer_mode(vha, (uint32_t *)p_src,
+		    offset, QLA8044_MAX_OPTROM_BURST_DWORDS);
+		if (rval) {
+			/* Buffer Mode failed skip to dword mode */
+			ql_log(ql_log_warn, vha, 0xb122,
+			    "Failed to write flash in buffer mode, "
+			    "Reverting to slow-write.\n");
+			rval = qla8044_write_flash_dword_mode(vha,
+			    (uint32_t *)p_src, offset,
+			    QLA8044_MAX_OPTROM_BURST_DWORDS);
+		}
+		p_src +=  sizeof(uint32_t) * QLA8044_MAX_OPTROM_BURST_DWORDS;
+		offset += sizeof(uint32_t) * QLA8044_MAX_OPTROM_BURST_DWORDS;
+	}
+	ql_dbg(ql_dbg_user, vha, 0xb133,
+	    "Done writing.\n");
+
+out:
+	qla8044_protect_flash(vha);
+	qla8044_flash_unlock(vha);
+	scsi_unblock_requests(vha->host);
+	kfree(p_cache);
+
+	return rval;
+}
+
+#define LEG_INT_PTR_B31		(1 << 31)
+#define LEG_INT_PTR_B30		(1 << 30)
+#define PF_BITS_MASK		(0xF << 16)
+/**
+ * qla8044_intr_handler() - Process interrupts for the ISP8044
+ * @irq:
+ * @dev_id: SCSI driver HA context
+ *
+ * Called by system whenever the host adapter generates an interrupt.
+ *
+ * Returns handled flag.
+ */
+irqreturn_t
+qla8044_intr_handler(int irq, void *dev_id)
+{
+	scsi_qla_host_t	*vha;
+	struct qla_hw_data *ha;
+	struct rsp_que *rsp;
+	struct device_reg_82xx __iomem *reg;
+	int		status = 0;
+	unsigned long	flags;
+	unsigned long	iter;
+	uint32_t	stat;
+	uint16_t	mb[4];
+	uint32_t leg_int_ptr = 0, pf_bit;
+
+	rsp = (struct rsp_que *) dev_id;
+	if (!rsp) {
+		ql_log(ql_log_info, NULL, 0xb143,
+		    "%s(): NULL response queue pointer\n", __func__);
+		return IRQ_NONE;
+	}
+	ha = rsp->hw;
+	vha = pci_get_drvdata(ha->pdev);
+
+	if (unlikely(pci_channel_offline(ha->pdev)))
+		return IRQ_HANDLED;
+
+	leg_int_ptr = qla8044_rd_reg(ha, LEG_INTR_PTR_OFFSET);
+
+	/* Legacy interrupt is valid if bit31 of leg_int_ptr is set */
+	if (!(leg_int_ptr & (LEG_INT_PTR_B31))) {
+		ql_dbg(ql_dbg_p3p, vha, 0xb144,
+		    "%s: Legacy Interrupt Bit 31 not set, "
+		    "spurious interrupt!\n", __func__);
+		return IRQ_NONE;
+	}
+
+	pf_bit = ha->portnum << 16;
+	/* Validate the PCIE function ID set in leg_int_ptr bits [19..16] */
+	if ((leg_int_ptr & (PF_BITS_MASK)) != pf_bit) {
+		ql_dbg(ql_dbg_p3p, vha, 0xb145,
+		    "%s: Incorrect function ID 0x%x in "
+		    "legacy interrupt register, "
+		    "ha->pf_bit = 0x%x\n", __func__,
+		    (leg_int_ptr & (PF_BITS_MASK)), pf_bit);
+		return IRQ_NONE;
+	}
+
+	/* To de-assert legacy interrupt, write 0 to Legacy Interrupt Trigger
+	 * Control register and poll till Legacy Interrupt Pointer register
+	 * bit32 is 0.
+	 */
+	qla8044_wr_reg(ha, LEG_INTR_TRIG_OFFSET, 0);
+	do {
+		leg_int_ptr = qla8044_rd_reg(ha, LEG_INTR_PTR_OFFSET);
+		if ((leg_int_ptr & (PF_BITS_MASK)) != pf_bit)
+			break;
+	} while (leg_int_ptr & (LEG_INT_PTR_B30));
+
+	reg = &ha->iobase->isp82;
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	for (iter = 1; iter--; ) {
+
+		if (RD_REG_DWORD(&reg->host_int)) {
+			stat = RD_REG_DWORD(&reg->host_status);
+			if ((stat & HSRX_RISC_INT) == 0)
+				break;
+
+			switch (stat & 0xff) {
+			case 0x1:
+			case 0x2:
+			case 0x10:
+			case 0x11:
+				qla82xx_mbx_completion(vha, MSW(stat));
+				status |= MBX_INTERRUPT;
+				break;
+			case 0x12:
+				mb[0] = MSW(stat);
+				mb[1] = RD_REG_WORD(&reg->mailbox_out[1]);
+				mb[2] = RD_REG_WORD(&reg->mailbox_out[2]);
+				mb[3] = RD_REG_WORD(&reg->mailbox_out[3]);
+				qla2x00_async_event(vha, rsp, mb);
+				break;
+			case 0x13:
+				qla24xx_process_response_queue(vha, rsp);
+				break;
+			default:
+				ql_dbg(ql_dbg_p3p, vha, 0xb146,
+				    "Unrecognized interrupt type "
+				    "(%d).\n", stat & 0xff);
+				break;
+			}
+		}
+		WRT_REG_DWORD(&reg->host_int, 0);
+	}
+
+	qla2x00_handle_mbx_completion(ha, status);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static int
+qla8044_idc_dontreset(struct qla_hw_data *ha)
+{
+	uint32_t idc_ctrl;
+
+	idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
+	return idc_ctrl & DONTRESET_BIT0;
+}
+
+static void
+qla8044_clear_rst_ready(scsi_qla_host_t *vha)
+{
+	uint32_t drv_state;
+
+	drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
+
+	/*
+	 * For ISP8044, drv_active register has 1 bit per function,
+	 * shift 1 by func_num to set a bit for the function.
+	 * For ISP82xx, drv_active has 4 bits per function
+	 */
+	drv_state &= ~(1 << vha->hw->portnum);
+
+	ql_dbg(ql_dbg_p3p, vha, 0xb143,
+	    "drv_state: 0x%08x\n", drv_state);
+	qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, drv_state);
+}
+
+int
+qla8044_abort_isp(scsi_qla_host_t *vha)
+{
+	int rval;
+	uint32_t dev_state;
+	struct qla_hw_data *ha = vha->hw;
+
+	qla8044_idc_lock(ha);
+	dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
+
+	if (ql2xdontresethba)
+		qla8044_set_idc_dontreset(vha);
+
+	/* If device_state is NEED_RESET, go ahead with
+	 * Reset,irrespective of ql2xdontresethba. This is to allow a
+	 * non-reset-owner to force a reset. Non-reset-owner sets
+	 * the IDC_CTRL BIT0 to prevent Reset-owner from doing a Reset
+	 * and then forces a Reset by setting device_state to
+	 * NEED_RESET. */
+	if (dev_state == QLA8XXX_DEV_READY) {
+		/* If IDC_CTRL DONTRESETHBA_BIT0 is set don't do reset
+		 * recovery */
+		if (qla8044_idc_dontreset(ha) == DONTRESET_BIT0) {
+			ql_dbg(ql_dbg_p3p, vha, 0xb144,
+			    "Reset recovery disabled\n");
+			rval = QLA_FUNCTION_FAILED;
+			goto exit_isp_reset;
+		}
+
+		ql_dbg(ql_dbg_p3p, vha, 0xb145,
+		    "HW State: NEED RESET\n");
+		qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
+		    QLA8XXX_DEV_NEED_RESET);
+	}
+
+	/* For ISP8044, Reset owner is NIC, iSCSI or FCOE based on priority
+	 * and which drivers are present. Unlike ISP82XX, the function setting
+	 * NEED_RESET, may not be the Reset owner. */
+	qla83xx_reset_ownership(vha);
+
+	qla8044_idc_unlock(ha);
+	rval = qla8044_device_state_handler(vha);
+	qla8044_idc_lock(ha);
+	qla8044_clear_rst_ready(vha);
+
+exit_isp_reset:
+	qla8044_idc_unlock(ha);
+	if (rval == QLA_SUCCESS) {
+		ha->flags.isp82xx_fw_hung = 0;
+		ha->flags.nic_core_reset_hdlr_active = 0;
+		rval = qla82xx_restart_isp(vha);
+	}
+
+	return rval;
+}
+
diff --git a/drivers/scsi/qla2xxx/qla_nx2.h b/drivers/scsi/qla2xxx/qla_nx2.h
new file mode 100644
index 0000000..2ab2eab
--- /dev/null
+++ b/drivers/scsi/qla2xxx/qla_nx2.h
@@ -0,0 +1,551 @@
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2013 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
+
+#ifndef __QLA_NX2_H
+#define __QLA_NX2_H
+
+#define QSNT_ACK_TOV				30
+#define INTENT_TO_RECOVER			0x01
+#define PROCEED_TO_RECOVER			0x02
+#define IDC_LOCK_RECOVERY_OWNER_MASK		0x3C
+#define IDC_LOCK_RECOVERY_STATE_MASK		0x3
+#define IDC_LOCK_RECOVERY_STATE_SHIFT_BITS	2
+
+#define QLA8044_DRV_LOCK_MSLEEP		200
+#define QLA8044_ADDR_DDR_NET		(0x0000000000000000ULL)
+#define QLA8044_ADDR_DDR_NET_MAX	(0x000000000fffffffULL)
+
+#define MD_MIU_TEST_AGT_WRDATA_LO		0x410000A0
+#define MD_MIU_TEST_AGT_WRDATA_HI		0x410000A4
+#define MD_MIU_TEST_AGT_WRDATA_ULO		0x410000B0
+#define MD_MIU_TEST_AGT_WRDATA_UHI		0x410000B4
+#define MD_MIU_TEST_AGT_RDDATA_LO		0x410000A8
+#define MD_MIU_TEST_AGT_RDDATA_HI		0x410000AC
+#define MD_MIU_TEST_AGT_RDDATA_ULO		0x410000B8
+#define MD_MIU_TEST_AGT_RDDATA_UHI		0x410000BC
+
+/* MIU_TEST_AGT_CTRL flags. work for SIU as well */
+#define MIU_TA_CTL_WRITE_ENABLE	(MIU_TA_CTL_WRITE | MIU_TA_CTL_ENABLE)
+#define MIU_TA_CTL_WRITE_START	(MIU_TA_CTL_WRITE | MIU_TA_CTL_ENABLE |	\
+				 MIU_TA_CTL_START)
+#define MIU_TA_CTL_START_ENABLE	(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE)
+
+/* Imbus address bit used to indicate a host address. This bit is
+ * eliminated by the pcie bar and bar select before presentation
+ * over pcie. */
+/* host memory via IMBUS */
+#define QLA8044_P2_ADDR_PCIE	(0x0000000800000000ULL)
+#define QLA8044_P3_ADDR_PCIE	(0x0000008000000000ULL)
+#define QLA8044_ADDR_PCIE_MAX	(0x0000000FFFFFFFFFULL)
+#define QLA8044_ADDR_OCM0	(0x0000000200000000ULL)
+#define QLA8044_ADDR_OCM0_MAX	(0x00000002000fffffULL)
+#define QLA8044_ADDR_OCM1	(0x0000000200400000ULL)
+#define QLA8044_ADDR_OCM1_MAX	(0x00000002004fffffULL)
+#define QLA8044_ADDR_QDR_NET	(0x0000000300000000ULL)
+#define QLA8044_P2_ADDR_QDR_NET_MAX	(0x00000003001fffffULL)
+#define QLA8044_P3_ADDR_QDR_NET_MAX	(0x0000000303ffffffULL)
+#define QLA8044_ADDR_QDR_NET_MAX	(0x0000000307ffffffULL)
+#define QLA8044_PCI_CRBSPACE		((unsigned long)0x06000000)
+#define QLA8044_PCI_DIRECT_CRB		((unsigned long)0x04400000)
+#define QLA8044_PCI_CAMQM		((unsigned long)0x04800000)
+#define QLA8044_PCI_CAMQM_MAX		((unsigned long)0x04ffffff)
+#define QLA8044_PCI_DDR_NET		((unsigned long)0x00000000)
+#define QLA8044_PCI_QDR_NET		((unsigned long)0x04000000)
+#define QLA8044_PCI_QDR_NET_MAX		((unsigned long)0x043fffff)
+
+/*  PCI Windowing for DDR regions.  */
+#define QLA8044_ADDR_IN_RANGE(addr, low, high)		\
+	(((addr) <= (high)) && ((addr) >= (low)))
+
+/* Indirectly Mapped Registers */
+#define QLA8044_FLASH_SPI_STATUS	0x2808E010
+#define QLA8044_FLASH_SPI_CONTROL	0x2808E014
+#define QLA8044_FLASH_STATUS		0x42100004
+#define QLA8044_FLASH_CONTROL		0x42110004
+#define QLA8044_FLASH_ADDR		0x42110008
+#define QLA8044_FLASH_WRDATA		0x4211000C
+#define QLA8044_FLASH_RDDATA		0x42110018
+#define QLA8044_FLASH_DIRECT_WINDOW	0x42110030
+#define QLA8044_FLASH_DIRECT_DATA(DATA) (0x42150000 | (0x0000FFFF&DATA))
+
+/* Flash access regs */
+#define QLA8044_FLASH_LOCK		0x3850
+#define QLA8044_FLASH_UNLOCK		0x3854
+#define QLA8044_FLASH_LOCK_ID		0x3500
+
+/* Driver Lock regs */
+#define QLA8044_DRV_LOCK		0x3868
+#define QLA8044_DRV_UNLOCK		0x386C
+#define QLA8044_DRV_LOCK_ID		0x3504
+#define QLA8044_DRV_LOCKRECOVERY	0x379C
+
+/* IDC version */
+#define QLA8044_IDC_VER_MAJ_VALUE       0x1
+#define QLA8044_IDC_VER_MIN_VALUE       0x0
+
+/* IDC Registers : Driver Coexistence Defines */
+#define QLA8044_CRB_IDC_VER_MAJOR	0x3780
+#define QLA8044_CRB_IDC_VER_MINOR	0x3798
+#define QLA8044_IDC_DRV_AUDIT		0x3794
+#define QLA8044_SRE_SHIM_CONTROL	0x0D200284
+#define QLA8044_PORT0_RXB_PAUSE_THRS	0x0B2003A4
+#define QLA8044_PORT1_RXB_PAUSE_THRS	0x0B2013A4
+#define QLA8044_PORT0_RXB_TC_MAX_CELL	0x0B200388
+#define QLA8044_PORT1_RXB_TC_MAX_CELL	0x0B201388
+#define QLA8044_PORT0_RXB_TC_STATS	0x0B20039C
+#define QLA8044_PORT1_RXB_TC_STATS	0x0B20139C
+#define QLA8044_PORT2_IFB_PAUSE_THRS	0x0B200704
+#define QLA8044_PORT3_IFB_PAUSE_THRS	0x0B201704
+
+/* set value to pause threshold value */
+#define QLA8044_SET_PAUSE_VAL		0x0
+#define QLA8044_SET_TC_MAX_CELL_VAL	0x03FF03FF
+#define QLA8044_PEG_HALT_STATUS1	0x34A8
+#define QLA8044_PEG_HALT_STATUS2	0x34AC
+#define QLA8044_PEG_ALIVE_COUNTER	0x34B0 /* FW_HEARTBEAT */
+#define QLA8044_FW_CAPABILITIES		0x3528
+#define QLA8044_CRB_DRV_ACTIVE		0x3788 /* IDC_DRV_PRESENCE */
+#define QLA8044_CRB_DEV_STATE		0x3784 /* IDC_DEV_STATE */
+#define QLA8044_CRB_DRV_STATE		0x378C /* IDC_DRV_ACK */
+#define QLA8044_CRB_DRV_SCRATCH		0x3548
+#define QLA8044_CRB_DEV_PART_INFO1	0x37E0
+#define QLA8044_CRB_DEV_PART_INFO2	0x37E4
+#define QLA8044_FW_VER_MAJOR		0x3550
+#define QLA8044_FW_VER_MINOR		0x3554
+#define QLA8044_FW_VER_SUB		0x3558
+#define QLA8044_NPAR_STATE		0x359C
+#define QLA8044_FW_IMAGE_VALID		0x35FC
+#define QLA8044_CMDPEG_STATE		0x3650
+#define QLA8044_ASIC_TEMP		0x37B4
+#define QLA8044_FW_API			0x356C
+#define QLA8044_DRV_OP_MODE		0x3570
+#define QLA8044_CRB_WIN_BASE		0x3800
+#define QLA8044_CRB_WIN_FUNC(f)		(QLA8044_CRB_WIN_BASE+((f)*4))
+#define QLA8044_SEM_LOCK_BASE		0x3840
+#define QLA8044_SEM_UNLOCK_BASE		0x3844
+#define QLA8044_SEM_LOCK_FUNC(f)	(QLA8044_SEM_LOCK_BASE+((f)*8))
+#define QLA8044_SEM_UNLOCK_FUNC(f)	(QLA8044_SEM_UNLOCK_BASE+((f)*8))
+#define QLA8044_LINK_STATE(f)		(0x3698+((f) > 7 ? 4 : 0))
+#define QLA8044_LINK_SPEED(f)		(0x36E0+(((f) >> 2) * 4))
+#define QLA8044_MAX_LINK_SPEED(f)       (0x36F0+(((f) / 4) * 4))
+#define QLA8044_LINK_SPEED_FACTOR	10
+
+/* FLASH API Defines */
+#define QLA8044_FLASH_MAX_WAIT_USEC	100
+#define QLA8044_FLASH_LOCK_TIMEOUT	10000
+#define QLA8044_FLASH_SECTOR_SIZE	65536
+#define QLA8044_DRV_LOCK_TIMEOUT	2000
+#define QLA8044_FLASH_SECTOR_ERASE_CMD	0xdeadbeef
+#define QLA8044_FLASH_WRITE_CMD		0xdacdacda
+#define QLA8044_FLASH_BUFFER_WRITE_CMD	0xcadcadca
+#define QLA8044_FLASH_READ_RETRY_COUNT	2000
+#define QLA8044_FLASH_STATUS_READY	0x6
+#define QLA8044_FLASH_BUFFER_WRITE_MIN	2
+#define QLA8044_FLASH_BUFFER_WRITE_MAX	64
+#define QLA8044_FLASH_STATUS_REG_POLL_DELAY 1
+#define QLA8044_ERASE_MODE		1
+#define QLA8044_WRITE_MODE		2
+#define QLA8044_DWORD_WRITE_MODE	3
+#define QLA8044_GLOBAL_RESET		0x38CC
+#define QLA8044_WILDCARD		0x38F0
+#define QLA8044_INFORMANT		0x38FC
+#define QLA8044_HOST_MBX_CTRL		0x3038
+#define QLA8044_FW_MBX_CTRL		0x303C
+#define QLA8044_BOOTLOADER_ADDR		0x355C
+#define QLA8044_BOOTLOADER_SIZE		0x3560
+#define QLA8044_FW_IMAGE_ADDR		0x3564
+#define QLA8044_MBX_INTR_ENABLE		0x1000
+#define QLA8044_MBX_INTR_MASK		0x1200
+
+/* IDC Control Register bit defines */
+#define DONTRESET_BIT0		0x1
+#define GRACEFUL_RESET_BIT1	0x2
+
+/* ISP8044 PEG_HALT_STATUS1 bits */
+#define QLA8044_HALT_STATUS_INFORMATIONAL (0x1 << 29)
+#define QLA8044_HALT_STATUS_FW_RESET	  (0x2 << 29)
+#define QLA8044_HALT_STATUS_UNRECOVERABLE (0x4 << 29)
+
+/* Firmware image definitions */
+#define QLA8044_BOOTLOADER_FLASH_ADDR	0x10000
+#define QLA8044_BOOT_FROM_FLASH		0
+#define QLA8044_IDC_PARAM_ADDR		0x3e8020
+
+/* FLASH related definitions */
+#define QLA8044_OPTROM_BURST_SIZE		0x100
+#define QLA8044_MAX_OPTROM_BURST_DWORDS		(QLA8044_OPTROM_BURST_SIZE / 4)
+#define QLA8044_MIN_OPTROM_BURST_DWORDS		2
+#define QLA8044_SECTOR_SIZE			(64 * 1024)
+
+#define QLA8044_FLASH_SPI_CTL			0x4
+#define QLA8044_FLASH_FIRST_TEMP_VAL		0x00800000
+#define QLA8044_FLASH_SECOND_TEMP_VAL		0x00800001
+#define QLA8044_FLASH_FIRST_MS_PATTERN		0x43
+#define QLA8044_FLASH_SECOND_MS_PATTERN		0x7F
+#define QLA8044_FLASH_LAST_MS_PATTERN		0x7D
+#define QLA8044_FLASH_STATUS_WRITE_DEF_SIG	0xFD0100
+#define QLA8044_FLASH_SECOND_ERASE_MS_VAL	0x5
+#define QLA8044_FLASH_ERASE_SIG			0xFD0300
+#define QLA8044_FLASH_LAST_ERASE_MS_VAL		0x3D
+
+/* Reset template definitions */
+#define QLA8044_MAX_RESET_SEQ_ENTRIES	16
+#define QLA8044_RESTART_TEMPLATE_SIZE	0x2000
+#define QLA8044_RESET_TEMPLATE_ADDR	0x4F0000
+#define QLA8044_RESET_SEQ_VERSION	0x0101
+
+/* Reset template entry opcodes */
+#define OPCODE_NOP			0x0000
+#define OPCODE_WRITE_LIST		0x0001
+#define OPCODE_READ_WRITE_LIST		0x0002
+#define OPCODE_POLL_LIST		0x0004
+#define OPCODE_POLL_WRITE_LIST		0x0008
+#define OPCODE_READ_MODIFY_WRITE	0x0010
+#define OPCODE_SEQ_PAUSE		0x0020
+#define OPCODE_SEQ_END			0x0040
+#define OPCODE_TMPL_END			0x0080
+#define OPCODE_POLL_READ_LIST		0x0100
+
+/* Template Header */
+#define RESET_TMPLT_HDR_SIGNATURE	0xCAFE
+#define QLA8044_IDC_DRV_CTRL            0x3790
+#define AF_8044_NO_FW_DUMP              27 /* 0x08000000 */
+
+#define MINIDUMP_SIZE_36K		36864
+
+struct qla8044_reset_template_hdr {
+	uint16_t	version;
+	uint16_t	signature;
+	uint16_t	size;
+	uint16_t	entries;
+	uint16_t	hdr_size;
+	uint16_t	checksum;
+	uint16_t	init_seq_offset;
+	uint16_t	start_seq_offset;
+} __packed;
+
+/* Common Entry Header. */
+struct qla8044_reset_entry_hdr {
+	uint16_t cmd;
+	uint16_t size;
+	uint16_t count;
+	uint16_t delay;
+} __packed;
+
+/* Generic poll entry type. */
+struct qla8044_poll {
+	uint32_t  test_mask;
+	uint32_t  test_value;
+} __packed;
+
+/* Read modify write entry type. */
+struct qla8044_rmw {
+	uint32_t test_mask;
+	uint32_t xor_value;
+	uint32_t  or_value;
+	uint8_t shl;
+	uint8_t shr;
+	uint8_t index_a;
+	uint8_t rsvd;
+} __packed;
+
+/* Generic Entry Item with 2 DWords. */
+struct qla8044_entry {
+	uint32_t arg1;
+	uint32_t arg2;
+} __packed;
+
+/* Generic Entry Item with 4 DWords.*/
+struct qla8044_quad_entry {
+	uint32_t dr_addr;
+	uint32_t dr_value;
+	uint32_t ar_addr;
+	uint32_t ar_value;
+} __packed;
+
+struct qla8044_reset_template {
+	int seq_index;
+	int seq_error;
+	int array_index;
+	uint32_t array[QLA8044_MAX_RESET_SEQ_ENTRIES];
+	uint8_t *buff;
+	uint8_t *stop_offset;
+	uint8_t *start_offset;
+	uint8_t *init_offset;
+	struct qla8044_reset_template_hdr *hdr;
+	uint8_t seq_end;
+	uint8_t template_end;
+};
+
+/* Driver_code is for driver to write some info about the entry
+ * currently not used.
+ */
+struct qla8044_minidump_entry_hdr {
+	uint32_t entry_type;
+	uint32_t entry_size;
+	uint32_t entry_capture_size;
+	struct {
+		uint8_t entry_capture_mask;
+		uint8_t entry_code;
+		uint8_t driver_code;
+		uint8_t driver_flags;
+	} d_ctrl;
+} __packed;
+
+/*  Read CRB entry header */
+struct qla8044_minidump_entry_crb {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t addr;
+	struct {
+		uint8_t addr_stride;
+		uint8_t state_index_a;
+		uint16_t poll_timeout;
+	} crb_strd;
+	uint32_t data_size;
+	uint32_t op_count;
+
+	struct {
+		uint8_t opcode;
+		uint8_t state_index_v;
+		uint8_t shl;
+		uint8_t shr;
+	} crb_ctrl;
+
+	uint32_t value_1;
+	uint32_t value_2;
+	uint32_t value_3;
+} __packed;
+
+struct qla8044_minidump_entry_cache {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t tag_reg_addr;
+	struct {
+		uint16_t tag_value_stride;
+		uint16_t init_tag_value;
+	} addr_ctrl;
+	uint32_t data_size;
+	uint32_t op_count;
+	uint32_t control_addr;
+	struct {
+		uint16_t write_value;
+		uint8_t poll_mask;
+		uint8_t poll_wait;
+	} cache_ctrl;
+	uint32_t read_addr;
+	struct {
+		uint8_t read_addr_stride;
+		uint8_t read_addr_cnt;
+		uint16_t rsvd_1;
+	} read_ctrl;
+} __packed;
+
+/* Read OCM */
+struct qla8044_minidump_entry_rdocm {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t rsvd_0;
+	uint32_t rsvd_1;
+	uint32_t data_size;
+	uint32_t op_count;
+	uint32_t rsvd_2;
+	uint32_t rsvd_3;
+	uint32_t read_addr;
+	uint32_t read_addr_stride;
+} __packed;
+
+/* Read Memory */
+struct qla8044_minidump_entry_rdmem {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t rsvd[6];
+	uint32_t read_addr;
+	uint32_t read_data_size;
+};
+
+/* Read Memory: For Pex-DMA */
+struct qla8044_minidump_entry_rdmem_pex_dma {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t desc_card_addr;
+	uint16_t dma_desc_cmd;
+	uint8_t rsvd[2];
+	uint32_t start_dma_cmd;
+	uint8_t rsvd2[12];
+	uint32_t read_addr;
+	uint32_t read_data_size;
+} __packed;
+
+/* Read ROM */
+struct qla8044_minidump_entry_rdrom {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t rsvd[6];
+	uint32_t read_addr;
+	uint32_t read_data_size;
+} __packed;
+
+/* Mux entry */
+struct qla8044_minidump_entry_mux {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t select_addr;
+	uint32_t rsvd_0;
+	uint32_t data_size;
+	uint32_t op_count;
+	uint32_t select_value;
+	uint32_t select_value_stride;
+	uint32_t read_addr;
+	uint32_t rsvd_1;
+} __packed;
+
+/* Queue entry */
+struct qla8044_minidump_entry_queue {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t select_addr;
+	struct {
+		uint16_t queue_id_stride;
+		uint16_t rsvd_0;
+	} q_strd;
+	uint32_t data_size;
+	uint32_t op_count;
+	uint32_t rsvd_1;
+	uint32_t rsvd_2;
+	uint32_t read_addr;
+	struct {
+		uint8_t read_addr_stride;
+		uint8_t read_addr_cnt;
+		uint16_t rsvd_3;
+	} rd_strd;
+} __packed;
+
+/* POLLRD Entry */
+struct qla8044_minidump_entry_pollrd {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t select_addr;
+	uint32_t read_addr;
+	uint32_t select_value;
+	uint16_t select_value_stride;
+	uint16_t op_count;
+	uint32_t poll_wait;
+	uint32_t poll_mask;
+	uint32_t data_size;
+	uint32_t rsvd_1;
+} __packed;
+
+/* RDMUX2 Entry */
+struct qla8044_minidump_entry_rdmux2 {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t select_addr_1;
+	uint32_t select_addr_2;
+	uint32_t select_value_1;
+	uint32_t select_value_2;
+	uint32_t op_count;
+	uint32_t select_value_mask;
+	uint32_t read_addr;
+	uint8_t select_value_stride;
+	uint8_t data_size;
+	uint8_t rsvd[2];
+} __packed;
+
+/* POLLRDMWR Entry */
+struct qla8044_minidump_entry_pollrdmwr {
+	struct qla8044_minidump_entry_hdr h;
+	uint32_t addr_1;
+	uint32_t addr_2;
+	uint32_t value_1;
+	uint32_t value_2;
+	uint32_t poll_wait;
+	uint32_t poll_mask;
+	uint32_t modify_mask;
+	uint32_t data_size;
+} __packed;
+
+/* IDC additional information */
+struct qla8044_idc_information {
+	uint32_t request_desc;  /* IDC request descriptor */
+	uint32_t info1; /* IDC additional info */
+	uint32_t info2; /* IDC additional info */
+	uint32_t info3; /* IDC additional info */
+} __packed;
+
+enum qla_regs {
+	QLA8044_PEG_HALT_STATUS1_INDEX = 0,
+	QLA8044_PEG_HALT_STATUS2_INDEX,
+	QLA8044_PEG_ALIVE_COUNTER_INDEX,
+	QLA8044_CRB_DRV_ACTIVE_INDEX,
+	QLA8044_CRB_DEV_STATE_INDEX,
+	QLA8044_CRB_DRV_STATE_INDEX,
+	QLA8044_CRB_DRV_SCRATCH_INDEX,
+	QLA8044_CRB_DEV_PART_INFO_INDEX,
+	QLA8044_CRB_DRV_IDC_VERSION_INDEX,
+	QLA8044_FW_VERSION_MAJOR_INDEX,
+	QLA8044_FW_VERSION_MINOR_INDEX,
+	QLA8044_FW_VERSION_SUB_INDEX,
+	QLA8044_CRB_CMDPEG_STATE_INDEX,
+	QLA8044_CRB_TEMP_STATE_INDEX,
+} __packed;
+
+#define CRB_REG_INDEX_MAX	14
+#define CRB_CMDPEG_CHECK_RETRY_COUNT    60
+#define CRB_CMDPEG_CHECK_DELAY          500
+
+static const uint32_t qla8044_reg_tbl[] = {
+	QLA8044_PEG_HALT_STATUS1,
+	QLA8044_PEG_HALT_STATUS2,
+	QLA8044_PEG_ALIVE_COUNTER,
+	QLA8044_CRB_DRV_ACTIVE,
+	QLA8044_CRB_DEV_STATE,
+	QLA8044_CRB_DRV_STATE,
+	QLA8044_CRB_DRV_SCRATCH,
+	QLA8044_CRB_DEV_PART_INFO1,
+	QLA8044_CRB_IDC_VER_MAJOR,
+	QLA8044_FW_VER_MAJOR,
+	QLA8044_FW_VER_MINOR,
+	QLA8044_FW_VER_SUB,
+	QLA8044_CMDPEG_STATE,
+	QLA8044_ASIC_TEMP,
+};
+
+/* MiniDump Structures */
+
+/* Driver_code is for driver to write some info about the entry
+ * currently not used.
+ */
+#define QLA8044_SS_OCM_WNDREG_INDEX             3
+#define QLA8044_DBG_STATE_ARRAY_LEN             16
+#define QLA8044_DBG_CAP_SIZE_ARRAY_LEN          8
+#define QLA8044_DBG_RSVD_ARRAY_LEN              8
+#define QLA8044_DBG_OCM_WNDREG_ARRAY_LEN        16
+#define QLA8044_SS_PCI_INDEX                    0
+
+struct qla8044_minidump_template_hdr {
+	uint32_t entry_type;
+	uint32_t first_entry_offset;
+	uint32_t size_of_template;
+	uint32_t capture_debug_level;
+	uint32_t num_of_entries;
+	uint32_t version;
+	uint32_t driver_timestamp;
+	uint32_t checksum;
+
+	uint32_t driver_capture_mask;
+	uint32_t driver_info_word2;
+	uint32_t driver_info_word3;
+	uint32_t driver_info_word4;
+
+	uint32_t saved_state_array[QLA8044_DBG_STATE_ARRAY_LEN];
+	uint32_t capture_size_array[QLA8044_DBG_CAP_SIZE_ARRAY_LEN];
+	uint32_t ocm_window_reg[QLA8044_DBG_OCM_WNDREG_ARRAY_LEN];
+};
+
+struct qla8044_pex_dma_descriptor {
+	struct {
+		uint32_t read_data_size; /* 0-23: size, 24-31: rsvd */
+		uint8_t rsvd[2];
+		uint16_t dma_desc_cmd;
+	} cmd;
+	uint64_t src_addr;
+	uint64_t dma_bus_addr; /*0-3: desc-cmd, 4-7: pci-func, 8-15: desc-cmd*/
+	uint8_t rsvd[24];
+} __packed;
+
+#endif
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 9207aeb..f92b22b 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1247,7 +1247,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
 		if (qla2x00_vp_abort_isp(vha))
 			goto eh_host_reset_lock;
 	} else {
-		if (IS_QLA82XX(vha->hw)) {
+		if (IS_P3P_TYPE(vha->hw)) {
 			if (!qla82xx_fcoe_ctx_reset(vha)) {
 				/* Ctx reset success */
 				ret = SUCCESS;
@@ -1911,7 +1911,7 @@ static struct isp_operations qla2300_isp_ops = {
 	.get_flash_version	= qla2x00_get_flash_version,
 	.start_scsi		= qla2x00_start_scsi,
 	.abort_isp		= qla2x00_abort_isp,
-	.iospace_config     	= qla2x00_iospace_config,
+	.iospace_config		= qla2x00_iospace_config,
 	.initialize_adapter	= qla2x00_initialize_adapter,
 };
 
@@ -1949,7 +1949,7 @@ static struct isp_operations qla24xx_isp_ops = {
 	.get_flash_version	= qla24xx_get_flash_version,
 	.start_scsi		= qla24xx_start_scsi,
 	.abort_isp		= qla2x00_abort_isp,
-	.iospace_config     	= qla2x00_iospace_config,
+	.iospace_config		= qla2x00_iospace_config,
 	.initialize_adapter	= qla2x00_initialize_adapter,
 };
 
@@ -1987,7 +1987,7 @@ static struct isp_operations qla25xx_isp_ops = {
 	.get_flash_version	= qla24xx_get_flash_version,
 	.start_scsi		= qla24xx_dif_start_scsi,
 	.abort_isp		= qla2x00_abort_isp,
-	.iospace_config     	= qla2x00_iospace_config,
+	.iospace_config		= qla2x00_iospace_config,
 	.initialize_adapter	= qla2x00_initialize_adapter,
 };
 
@@ -2025,7 +2025,7 @@ static struct isp_operations qla81xx_isp_ops = {
 	.get_flash_version	= qla24xx_get_flash_version,
 	.start_scsi		= qla24xx_dif_start_scsi,
 	.abort_isp		= qla2x00_abort_isp,
-	.iospace_config     	= qla2x00_iospace_config,
+	.iospace_config		= qla2x00_iospace_config,
 	.initialize_adapter	= qla2x00_initialize_adapter,
 };
 
@@ -2060,13 +2060,51 @@ static struct isp_operations qla82xx_isp_ops = {
 	.beacon_blink		= NULL,
 	.read_optrom		= qla82xx_read_optrom_data,
 	.write_optrom		= qla82xx_write_optrom_data,
-	.get_flash_version	= qla24xx_get_flash_version,
+	.get_flash_version	= qla82xx_get_flash_version,
 	.start_scsi             = qla82xx_start_scsi,
 	.abort_isp		= qla82xx_abort_isp,
 	.iospace_config     	= qla82xx_iospace_config,
 	.initialize_adapter	= qla2x00_initialize_adapter,
 };
 
+static struct isp_operations qla8044_isp_ops = {
+	.pci_config		= qla82xx_pci_config,
+	.reset_chip		= qla82xx_reset_chip,
+	.chip_diag		= qla24xx_chip_diag,
+	.config_rings		= qla82xx_config_rings,
+	.reset_adapter		= qla24xx_reset_adapter,
+	.nvram_config		= qla81xx_nvram_config,
+	.update_fw_options	= qla24xx_update_fw_options,
+	.load_risc		= qla82xx_load_risc,
+	.pci_info_str		= qla24xx_pci_info_str,
+	.fw_version_str		= qla24xx_fw_version_str,
+	.intr_handler		= qla8044_intr_handler,
+	.enable_intrs		= qla82xx_enable_intrs,
+	.disable_intrs		= qla82xx_disable_intrs,
+	.abort_command		= qla24xx_abort_command,
+	.target_reset		= qla24xx_abort_target,
+	.lun_reset		= qla24xx_lun_reset,
+	.fabric_login		= qla24xx_login_fabric,
+	.fabric_logout		= qla24xx_fabric_logout,
+	.calc_req_entries	= NULL,
+	.build_iocbs		= NULL,
+	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
+	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
+	.read_nvram		= NULL,
+	.write_nvram		= NULL,
+	.fw_dump		= qla24xx_fw_dump,
+	.beacon_on		= qla82xx_beacon_on,
+	.beacon_off		= qla82xx_beacon_off,
+	.beacon_blink		= NULL,
+	.read_optrom		= qla82xx_read_optrom_data,
+	.write_optrom		= qla8044_write_optrom_data,
+	.get_flash_version	= qla82xx_get_flash_version,
+	.start_scsi             = qla82xx_start_scsi,
+	.abort_isp		= qla8044_abort_isp,
+	.iospace_config		= qla82xx_iospace_config,
+	.initialize_adapter	= qla2x00_initialize_adapter,
+};
+
 static struct isp_operations qla83xx_isp_ops = {
 	.pci_config		= qla25xx_pci_config,
 	.reset_chip		= qla24xx_reset_chip,
@@ -2237,6 +2275,14 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha)
 		/* Initialize 82XX ISP flags */
 		qla82xx_init_flags(ha);
 		break;
+	 case PCI_DEVICE_ID_QLOGIC_ISP8044:
+		ha->device_type |= DT_ISP8044;
+		ha->device_type |= DT_ZIO_SUPPORTED;
+		ha->device_type |= DT_FWI2;
+		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
+		/* Initialize 82XX ISP flags */
+		qla82xx_init_flags(ha);
+		break;
 	case PCI_DEVICE_ID_QLOGIC_ISP2031:
 		ha->device_type |= DT_ISP2031;
 		ha->device_type |= DT_ZIO_SUPPORTED;
@@ -2317,7 +2363,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	uint16_t req_length = 0, rsp_length = 0;
 	struct req_que *req = NULL;
 	struct rsp_que *rsp = NULL;
-
 	bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
 	sht = &qla2xxx_driver_template;
 	if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
@@ -2330,7 +2375,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8021 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2031 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 ||
-	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001) {
+	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 ||
+	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044) {
 		bars = pci_select_bars(pdev, IORESOURCE_MEM);
 		mem_only = 1;
 		ql_dbg_pci(ql_dbg_init, pdev, 0x0007,
@@ -2484,6 +2530,21 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
 		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
 		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
+	} else if (IS_QLA8044(ha)) {
+		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
+		ha->mbx_count = MAILBOX_REGISTER_COUNT;
+		req_length = REQUEST_ENTRY_CNT_82XX;
+		rsp_length = RESPONSE_ENTRY_CNT_82XX;
+		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
+		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
+		ha->gid_list_info_size = 8;
+		ha->optrom_size = OPTROM_SIZE_83XX;
+		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
+		ha->isp_ops = &qla8044_isp_ops;
+		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
+		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
+		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
+		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
 	} else if (IS_QLA83XX(ha)) {
 		ha->portnum = PCI_FUNC(ha->pdev->devfn);
 		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
@@ -2676,7 +2737,7 @@ que_init:
 		rsp->rsp_q_out = &ha->iobase->ispfx00.rsp_q_out;
 	}
 
-	if (IS_QLA82XX(ha)) {
+	if (IS_P3P_TYPE(ha)) {
 		req->req_q_out = &ha->iobase->isp82.req_q_out[0];
 		rsp->rsp_q_in = &ha->iobase->isp82.rsp_q_in[0];
 		rsp->rsp_q_out = &ha->iobase->isp82.rsp_q_out[0];
@@ -2709,6 +2770,14 @@ que_init:
 			qla82xx_idc_unlock(ha);
 			ql_log(ql_log_fatal, base_vha, 0x00d7,
 			    "HW State: FAILED.\n");
+		} else if (IS_QLA8044(ha)) {
+			qla8044_idc_lock(ha);
+			qla8044_wr_direct(base_vha,
+				QLA8044_CRB_DEV_STATE_INDEX,
+				QLA8XXX_DEV_FAILED);
+			qla8044_idc_unlock(ha);
+			ql_log(ql_log_fatal, base_vha, 0x0150,
+			    "HW State: FAILED.\n");
 		}
 
 		ret = -ENODEV;
@@ -2881,8 +2950,13 @@ probe_hw_failed:
 		qla82xx_clear_drv_active(ha);
 		qla82xx_idc_unlock(ha);
 	}
+	if (IS_QLA8044(ha)) {
+		qla8044_idc_lock(ha);
+		qla8044_clear_drv_active(base_vha);
+		qla8044_idc_unlock(ha);
+	}
 iospace_config_failed:
-	if (IS_QLA82XX(ha)) {
+	if (IS_P3P_TYPE(ha)) {
 		if (!ha->nx_pcibase)
 			iounmap((device_reg_t __iomem *)ha->nx_pcibase);
 		if (!ql2xdbwr)
@@ -3061,6 +3135,11 @@ qla2x00_remove_one(struct pci_dev *pdev)
 
 	scsi_host_put(base_vha->host);
 
+	if (IS_QLA8044(ha)) {
+		qla8044_idc_lock(ha);
+		qla8044_clear_drv_active(base_vha);
+		qla8044_idc_unlock(ha);
+	}
 	if (IS_QLA82XX(ha)) {
 		qla82xx_idc_lock(ha);
 		qla82xx_clear_drv_active(ha);
@@ -3284,7 +3363,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
 	if (!ha->srb_mempool)
 		goto fail_free_gid_list;
 
-	if (IS_QLA82XX(ha)) {
+	if (IS_P3P_TYPE(ha)) {
 		/* Allocate cache for CT6 Ctx. */
 		if (!ctx_cachep) {
 			ctx_cachep = kmem_cache_create("qla2xxx_ctx",
@@ -3318,7 +3397,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
 	    "init_cb=%p gid_list=%p, srb_mempool=%p s_dma_pool=%p.\n",
 	    ha->init_cb, ha->gid_list, ha->srb_mempool, ha->s_dma_pool);
 
-	if (IS_QLA82XX(ha) || ql2xenabledif) {
+	if (IS_P3P_TYPE(ha) || ql2xenabledif) {
 		ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev,
 			DSD_LIST_DMA_POOL_SIZE, 8, 0);
 		if (!ha->dl_dma_pool) {
@@ -3526,7 +3605,7 @@ fail:
 *	Frees fw dump stuff.
 *
 * Input:
-*	ha = adapter block pointer.
+*	ha = adapter block pointer
 */
 static void
 qla2x00_free_fw_dump(struct qla_hw_data *ha)
@@ -4693,17 +4772,33 @@ qla2x00_do_dpc(void *data)
 
 		qla2x00_do_work(base_vha);
 
-		if (IS_QLA82XX(ha)) {
-			if (test_and_clear_bit(ISP_UNRECOVERABLE,
-				&base_vha->dpc_flags)) {
-				qla82xx_idc_lock(ha);
-				qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-					QLA8XXX_DEV_FAILED);
-				qla82xx_idc_unlock(ha);
-				ql_log(ql_log_info, base_vha, 0x4004,
-				    "HW State: FAILED.\n");
-				qla82xx_device_state_handler(base_vha);
-				continue;
+		if (IS_P3P_TYPE(ha)) {
+			if (IS_QLA8044(ha)) {
+				if (test_and_clear_bit(ISP_UNRECOVERABLE,
+					&base_vha->dpc_flags)) {
+					qla8044_idc_lock(ha);
+					qla8044_wr_direct(base_vha,
+						QLA8044_CRB_DEV_STATE_INDEX,
+						QLA8XXX_DEV_FAILED);
+					qla8044_idc_unlock(ha);
+					ql_log(ql_log_info, base_vha, 0x4004,
+						"HW State: FAILED.\n");
+					qla8044_device_state_handler(base_vha);
+					continue;
+				}
+
+			} else {
+				if (test_and_clear_bit(ISP_UNRECOVERABLE,
+					&base_vha->dpc_flags)) {
+					qla82xx_idc_lock(ha);
+					qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
+						QLA8XXX_DEV_FAILED);
+					qla82xx_idc_unlock(ha);
+					ql_log(ql_log_info, base_vha, 0x0151,
+						"HW State: FAILED.\n");
+					qla82xx_device_state_handler(base_vha);
+					continue;
+				}
 			}
 
 			if (test_and_clear_bit(FCOE_CTX_RESET_NEEDED,
@@ -4803,16 +4898,26 @@ qla2x00_do_dpc(void *data)
 		if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) {
 			ql_dbg(ql_dbg_dpc, base_vha, 0x4009,
 			    "Quiescence mode scheduled.\n");
-			if (IS_QLA82XX(ha)) {
-				qla82xx_device_state_handler(base_vha);
+			if (IS_P3P_TYPE(ha)) {
+				if (IS_QLA82XX(ha))
+					qla82xx_device_state_handler(base_vha);
+				if (IS_QLA8044(ha))
+					qla8044_device_state_handler(base_vha);
 				clear_bit(ISP_QUIESCE_NEEDED,
 				    &base_vha->dpc_flags);
 				if (!ha->flags.quiesce_owner) {
 					qla2x00_perform_loop_resync(base_vha);
-
-					qla82xx_idc_lock(ha);
-					qla82xx_clear_qsnt_ready(base_vha);
-					qla82xx_idc_unlock(ha);
+					if (IS_QLA82XX(ha)) {
+						qla82xx_idc_lock(ha);
+						qla82xx_clear_qsnt_ready(
+						    base_vha);
+						qla82xx_idc_unlock(ha);
+					} else if (IS_QLA8044(ha)) {
+						qla8044_idc_lock(ha);
+						qla8044_clear_qsnt_ready(
+						    base_vha);
+						qla8044_idc_unlock(ha);
+					}
 				}
 			} else {
 				clear_bit(ISP_QUIESCE_NEEDED,
@@ -4986,10 +5091,13 @@ qla2x00_timer(scsi_qla_host_t *vha)
 		pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
 
 	/* Make sure qla82xx_watchdog is run only for physical port */
-	if (!vha->vp_idx && IS_QLA82XX(ha)) {
+	if (!vha->vp_idx && IS_P3P_TYPE(ha)) {
 		if (test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags))
 			start_dpc++;
-		qla82xx_watchdog(vha);
+		if (IS_QLA82XX(ha))
+			qla82xx_watchdog(vha);
+		else if (IS_QLA8044(ha))
+			qla8044_watchdog(vha);
 	}
 
 	if (!vha->vp_idx && IS_QLAFX00(ha))
@@ -5069,7 +5177,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
 	/* Check if beacon LED needs to be blinked for physical host only */
 	if (!vha->vp_idx && (ha->beacon_blink_led == 1)) {
 		/* There is no beacon_blink function for ISP82xx */
-		if (!IS_QLA82XX(ha)) {
+		if (!IS_P3P_TYPE(ha)) {
 			set_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags);
 			start_dpc++;
 		}
@@ -5513,6 +5621,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8021) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8031) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) },
 	{ 0 },
 };
 MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 3bef673..2f2e029 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -565,7 +565,7 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
 		*start = FA_FLASH_LAYOUT_ADDR;
 	else if (IS_QLA81XX(ha))
 		*start = FA_FLASH_LAYOUT_ADDR_81;
-	else if (IS_QLA82XX(ha)) {
+	else if (IS_P3P_TYPE(ha)) {
 		*start = FA_FLASH_LAYOUT_ADDR_82;
 		goto end;
 	} else if (IS_QLA83XX(ha)) {
@@ -719,7 +719,7 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 		start = le32_to_cpu(region->start) >> 2;
 		ql_dbg(ql_dbg_init, vha, 0x0049,
 		    "FLT[%02x]: start=0x%x "
-		    "end=0x%x size=0x%x.\n", le32_to_cpu(region->code),
+		    "end=0x%x size=0x%x.\n", le32_to_cpu(region->code) & 0xff,
 		    start, le32_to_cpu(region->end) >> 2,
 		    le32_to_cpu(region->size));
 
@@ -741,13 +741,13 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 			if (IS_QLA8031(ha))
 				break;
 			ha->flt_region_vpd_nvram = start;
-			if (IS_QLA82XX(ha))
+			if (IS_P3P_TYPE(ha))
 				break;
 			if (ha->flags.port0)
 				ha->flt_region_vpd = start;
 			break;
 		case FLT_REG_VPD_1:
-			if (IS_QLA82XX(ha) || IS_QLA8031(ha))
+			if (IS_P3P_TYPE(ha) || IS_QLA8031(ha))
 				break;
 			if (!ha->flags.port0)
 				ha->flt_region_vpd = start;
@@ -789,9 +789,17 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 		case FLT_REG_BOOT_CODE_82XX:
 			ha->flt_region_boot = start;
 			break;
+		case FLT_REG_BOOT_CODE_8044:
+			if (IS_QLA8044(ha))
+				ha->flt_region_boot = start;
+			break;
 		case FLT_REG_FW_82XX:
 			ha->flt_region_fw = start;
 			break;
+		case FLT_REG_CNA_FW:
+			if (IS_CNA_CAPABLE(ha))
+				ha->flt_region_fw = start;
+			break;
 		case FLT_REG_GOLD_FW_82XX:
 			ha->flt_region_gold_fw = start;
 			break;
@@ -803,13 +811,13 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 				ha->flt_region_vpd = start;
 			break;
 		case FLT_REG_FCOE_NVRAM_0:
-			if (!IS_QLA8031(ha))
+			if (!(IS_QLA8031(ha) || IS_QLA8044(ha)))
 				break;
 			if (ha->flags.port0)
 				ha->flt_region_nvram = start;
 			break;
 		case FLT_REG_FCOE_NVRAM_1:
-			if (!IS_QLA8031(ha))
+			if (!(IS_QLA8031(ha) || IS_QLA8044(ha)))
 				break;
 			if (!ha->flags.port0)
 				ha->flt_region_nvram = start;
@@ -883,7 +891,13 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha)
 	mid = le16_to_cpu(fdt->man_id);
 	fid = le16_to_cpu(fdt->id);
 	ha->fdt_wrt_disable = fdt->wrt_disable_bits;
-	ha->fdt_erase_cmd = flash_conf_addr(ha, 0x0300 | fdt->erase_cmd);
+	ha->fdt_wrt_enable = fdt->wrt_enable_bits;
+	ha->fdt_wrt_sts_reg_cmd = fdt->wrt_sts_reg_cmd;
+	if (IS_QLA8044(ha))
+		ha->fdt_erase_cmd = fdt->erase_cmd;
+	else
+		ha->fdt_erase_cmd =
+		    flash_conf_addr(ha, 0x0300 | fdt->erase_cmd);
 	ha->fdt_block_size = le32_to_cpu(fdt->block_size);
 	if (fdt->unprotect_sec_cmd) {
 		ha->fdt_unprotect_sec_cmd = flash_conf_addr(ha, 0x0300 |
@@ -895,7 +909,7 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha)
 	goto done;
 no_flash_data:
 	loc = locations[0];
-	if (IS_QLA82XX(ha)) {
+	if (IS_P3P_TYPE(ha)) {
 		ha->fdt_block_size = FLASH_BLK_SIZE_64K;
 		goto done;
 	}
@@ -946,7 +960,7 @@ qla2xxx_get_idc_param(scsi_qla_host_t *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req = ha->req_q_map[0];
 
-	if (!IS_QLA82XX(ha))
+	if (!(IS_P3P_TYPE(ha)))
 		return;
 
 	wptr = (uint32_t *)req->ring;
@@ -1008,6 +1022,9 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha)
 	if (ha->flags.nic_core_reset_hdlr_active)
 		return;
 
+	if (IS_QLA8044(ha))
+		return;
+
 	ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr,
 	    ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header));
 	if (hdr.version == __constant_cpu_to_le16(0xffff))
@@ -1302,7 +1319,7 @@ qla24xx_read_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr,
 	uint32_t *dwptr;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return  buf;
 
 	/* Dword reads to flash. */
@@ -1360,7 +1377,7 @@ qla24xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr,
 
 	ret = QLA_SUCCESS;
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return ret;
 
 	/* Enable flash write. */
@@ -1474,7 +1491,7 @@ qla2x00_beacon_blink(struct scsi_qla_host *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return;
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -1752,7 +1769,7 @@ qla24xx_beacon_on(struct scsi_qla_host *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return QLA_SUCCESS;
 
 	if (IS_QLA8031(ha) || IS_QLA81XX(ha))
@@ -1804,7 +1821,7 @@ qla24xx_beacon_off(struct scsi_qla_host *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return QLA_SUCCESS;
 
 	ha->beacon_blink_led = 0;
@@ -2822,6 +2839,121 @@ qla2x00_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
 }
 
 int
+qla82xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
+{
+	int ret = QLA_SUCCESS;
+	uint32_t pcihdr, pcids;
+	uint32_t *dcode;
+	uint8_t *bcode;
+	uint8_t code_type, last_image;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (!mbuf)
+		return QLA_FUNCTION_FAILED;
+
+	memset(ha->bios_revision, 0, sizeof(ha->bios_revision));
+	memset(ha->efi_revision, 0, sizeof(ha->efi_revision));
+	memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision));
+	memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
+
+	dcode = mbuf;
+
+	/* Begin with first PCI expansion ROM header. */
+	pcihdr = ha->flt_region_boot << 2;
+	last_image = 1;
+	do {
+		/* Verify PCI expansion ROM header. */
+		ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, pcihdr,
+		    0x20 * 4);
+		bcode = mbuf + (pcihdr % 4);
+		if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa) {
+			/* No signature */
+			ql_log(ql_log_fatal, vha, 0x0154,
+			    "No matching ROM signature.\n");
+			ret = QLA_FUNCTION_FAILED;
+			break;
+		}
+
+		/* Locate PCI data structure. */
+		pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
+
+		ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, pcids,
+		    0x20 * 4);
+		bcode = mbuf + (pcihdr % 4);
+
+		/* Validate signature of PCI data structure. */
+		if (bcode[0x0] != 'P' || bcode[0x1] != 'C' ||
+		    bcode[0x2] != 'I' || bcode[0x3] != 'R') {
+			/* Incorrect header. */
+			ql_log(ql_log_fatal, vha, 0x0155,
+			    "PCI data struct not found pcir_adr=%x.\n", pcids);
+			ret = QLA_FUNCTION_FAILED;
+			break;
+		}
+
+		/* Read version */
+		code_type = bcode[0x14];
+		switch (code_type) {
+		case ROM_CODE_TYPE_BIOS:
+			/* Intel x86, PC-AT compatible. */
+			ha->bios_revision[0] = bcode[0x12];
+			ha->bios_revision[1] = bcode[0x13];
+			ql_dbg(ql_dbg_init, vha, 0x0156,
+			    "Read BIOS %d.%d.\n",
+			    ha->bios_revision[1], ha->bios_revision[0]);
+			break;
+		case ROM_CODE_TYPE_FCODE:
+			/* Open Firmware standard for PCI (FCode). */
+			ha->fcode_revision[0] = bcode[0x12];
+			ha->fcode_revision[1] = bcode[0x13];
+			ql_dbg(ql_dbg_init, vha, 0x0157,
+			    "Read FCODE %d.%d.\n",
+			    ha->fcode_revision[1], ha->fcode_revision[0]);
+			break;
+		case ROM_CODE_TYPE_EFI:
+			/* Extensible Firmware Interface (EFI). */
+			ha->efi_revision[0] = bcode[0x12];
+			ha->efi_revision[1] = bcode[0x13];
+			ql_dbg(ql_dbg_init, vha, 0x0158,
+			    "Read EFI %d.%d.\n",
+			    ha->efi_revision[1], ha->efi_revision[0]);
+			break;
+		default:
+			ql_log(ql_log_warn, vha, 0x0159,
+			    "Unrecognized code type %x at pcids %x.\n",
+			    code_type, pcids);
+			break;
+		}
+
+		last_image = bcode[0x15] & BIT_7;
+
+		/* Locate next PCI expansion ROM. */
+		pcihdr += ((bcode[0x11] << 8) | bcode[0x10]) * 512;
+	} while (!last_image);
+
+	/* Read firmware image information. */
+	memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
+	dcode = mbuf;
+	ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, ha->flt_region_fw << 2,
+	    0x20);
+	bcode = mbuf + (pcihdr % 4);
+
+	/* Validate signature of PCI data structure. */
+	if (bcode[0x0] == 0x3 && bcode[0x1] == 0x0 &&
+	    bcode[0x2] == 0x40 && bcode[0x3] == 0x40) {
+		ha->fw_revision[0] = bcode[0x4];
+		ha->fw_revision[1] = bcode[0x5];
+		ha->fw_revision[2] = bcode[0x6];
+		ql_dbg(ql_dbg_init, vha, 0x015a,
+		    "Firmware revision %d.%d.%d\n",
+		    ha->fw_revision[0], ha->fw_revision[1],
+		    ha->fw_revision[2]);
+	}
+
+	return ret;
+}
+
+int
 qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
 {
 	int ret = QLA_SUCCESS;
@@ -2832,7 +2964,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
 	int i;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (IS_QLA82XX(ha))
+	if (IS_P3P_TYPE(ha))
 		return ret;
 
 	if (!mbuf)
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 03/29] qla2xxx: Fix incorrect test after list_for_each_entry() exits.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 01/29] qla2xxx: Print some variables to hexadecimal string via %*phN format Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 02/29] qla2xxx: Add support for ISP8044 Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 04/29] qla2xxx: Correct multiqueue offset calculations Saurav Kashyap
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Joe Carnuccio <joe.carnuccio@qlogic.com>

list_for_each_entry() never leaves the iterator pointing to null.

Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_bsg.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index ffcad26..fb5bd6e 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1266,6 +1266,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
 	int rval = 0;
 	struct qla_port_param *port_param = NULL;
 	fc_port_t *fcport = NULL;
+	int found = 0;
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
 	uint8_t *rsp_ptr = NULL;
 
@@ -1288,10 +1289,12 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
 		if (memcmp(port_param->fc_scsi_addr.dest_addr.wwpn,
 			fcport->port_name, sizeof(fcport->port_name)))
 			continue;
+
+		found = 1;
 		break;
 	}
 
-	if (!fcport) {
+	if (!found) {
 		ql_log(ql_log_warn, vha, 0x7049,
 		    "Failed to find port.\n");
 		return -EINVAL;
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 04/29] qla2xxx: Correct multiqueue offset calculations.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (2 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 03/29] qla2xxx: Fix incorrect test after list_for_each_entry() exits Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 05/29] qla2xxx: Set factory reset recovery timeout to 10 min. for ISPFX00 Saurav Kashyap
                   ` (25 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Andrew Vasquez <andrew.vasquez@qlogic.com>

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c |   17 ++++++++++-------
 drivers/scsi/qla2xxx/qla_def.h |    5 ++---
 drivers/scsi/qla2xxx/qla_mbx.c |   18 ++++--------------
 drivers/scsi/qla2xxx/qla_mid.c |    2 ++
 4 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 6ed98f9..aa10109 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -527,7 +527,7 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
 	uint32_t cnt, que_idx;
 	uint8_t que_cnt;
 	struct qla2xxx_mq_chain *mq = ptr;
-	struct device_reg_25xxmq __iomem *reg;
+	device_reg_t __iomem *reg;
 
 	if (!ha->mqenable || IS_QLA83XX(ha))
 		return ptr;
@@ -541,13 +541,16 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
 		ha->max_req_queues : ha->max_rsp_queues;
 	mq->count = htonl(que_cnt);
 	for (cnt = 0; cnt < que_cnt; cnt++) {
-		reg = (struct device_reg_25xxmq __iomem *)
-			(ha->mqiobase + cnt * QLA_QUE_PAGE);
+		reg = ISP_QUE_REG(ha, cnt);
 		que_idx = cnt * 4;
-		mq->qregs[que_idx] = htonl(RD_REG_DWORD(&reg->req_q_in));
-		mq->qregs[que_idx+1] = htonl(RD_REG_DWORD(&reg->req_q_out));
-		mq->qregs[que_idx+2] = htonl(RD_REG_DWORD(&reg->rsp_q_in));
-		mq->qregs[que_idx+3] = htonl(RD_REG_DWORD(&reg->rsp_q_out));
+		mq->qregs[que_idx] =
+		    htonl(RD_REG_DWORD(&reg->isp25mq.req_q_in));
+		mq->qregs[que_idx+1] =
+		    htonl(RD_REG_DWORD(&reg->isp25mq.req_q_out));
+		mq->qregs[que_idx+2] =
+		    htonl(RD_REG_DWORD(&reg->isp25mq.rsp_q_in));
+		mq->qregs[que_idx+3] =
+		    htonl(RD_REG_DWORD(&reg->isp25mq.rsp_q_out));
 	}
 
 	return ptr + sizeof(struct qla2xxx_mq_chain);
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index c0a1a71..d675860 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2671,9 +2671,8 @@ struct bidi_statistics {
 #define QLA_MAX_QUEUES 256
 #define ISP_QUE_REG(ha, id) \
 	((ha->mqenable || IS_QLA83XX(ha)) ? \
-	((device_reg_t __iomem *)(ha->mqiobase) +\
-	(QLA_QUE_PAGE * id)) :\
-	((device_reg_t __iomem *)(ha->iobase)))
+	 ((void __iomem *)ha->mqiobase + (QLA_QUE_PAGE * id)) :\
+	 ((void __iomem *)ha->iobase))
 #define QLA_REQ_QUE_ID(tag) \
 	((tag < QLA_MAX_QUEUES && tag > 0) ? tag : 0)
 #define QLA_DEFAULT_QUE_QOS 5
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 98e8a16..bce41f4 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3574,7 +3574,6 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
 	unsigned long flags;
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
-	struct device_reg_25xxmq __iomem *reg;
 	struct qla_hw_data *ha = vha->hw;
 
 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
@@ -3595,9 +3594,6 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
 	if (IS_QLA83XX(ha))
 		mcp->mb[15] = 0;
 
-	reg = (struct device_reg_25xxmq __iomem *)((ha->mqiobase) +
-		QLA_QUE_PAGE * req->id);
-
 	mcp->mb[4] = req->id;
 	/* que in ptr index */
 	mcp->mb[8] = 0;
@@ -3619,12 +3615,10 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	if (!(req->options & BIT_0)) {
-		WRT_REG_DWORD(&reg->req_q_in, 0);
+		WRT_REG_DWORD(req->req_q_in, 0);
 		if (!IS_QLA83XX(ha))
-			WRT_REG_DWORD(&reg->req_q_out, 0);
+			WRT_REG_DWORD(req->req_q_out, 0);
 	}
-	req->req_q_in = &reg->req_q_in;
-	req->req_q_out = &reg->req_q_out;
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	rval = qla2x00_mailbox_command(vha, mcp);
@@ -3646,7 +3640,6 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
 	unsigned long flags;
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
-	struct device_reg_25xxmq __iomem *reg;
 	struct qla_hw_data *ha = vha->hw;
 
 	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
@@ -3664,9 +3657,6 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
 	if (IS_QLA83XX(ha))
 		mcp->mb[15] = 0;
 
-	reg = (struct device_reg_25xxmq __iomem *)((ha->mqiobase) +
-		QLA_QUE_PAGE * rsp->id);
-
 	mcp->mb[4] = rsp->id;
 	/* que in ptr index */
 	mcp->mb[8] = 0;
@@ -3690,9 +3680,9 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	if (!(rsp->options & BIT_0)) {
-		WRT_REG_DWORD(&reg->rsp_q_out, 0);
+		WRT_REG_DWORD(rsp->rsp_q_out, 0);
 		if (!IS_QLA83XX(ha))
-			WRT_REG_DWORD(&reg->rsp_q_in, 0);
+			WRT_REG_DWORD(rsp->rsp_q_in, 0);
 	}
 
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index f868a9f..a72df70 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -699,6 +699,8 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
 	req->cnt = req->length;
 	req->id = que_id;
 	reg = ISP_QUE_REG(ha, que_id);
+	req->req_q_in = &reg->isp25mq.req_q_in;
+	req->req_q_out = &reg->isp25mq.req_q_out;
 	req->max_q_depth = ha->req_q_map[0]->max_q_depth;
 	mutex_unlock(&ha->vport_lock);
 	ql_dbg(ql_dbg_multiq, base_vha, 0xc004,
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 05/29] qla2xxx: Set factory reset recovery timeout to 10 min. for ISPFX00.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (3 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 04/29] qla2xxx: Correct multiqueue offset calculations Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 06/29] qla2xxx: Perform warm reset every 2 minutes if firmware load fails " Saurav Kashyap
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Acked-by: Srinivasa Rao <srinivasa.rao@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_def.h |    1 +
 drivers/scsi/qla2xxx/qla_mr.c  |    3 +++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index d675860..58e4f19 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -806,6 +806,7 @@ struct mbx_cmd_32 {
 #define MBA_MIRROR_LUN_CHANGE	0x8402	/* Mirror LUN State Change
 					   Notification */
 #define MBA_FW_POLL_STATE	0x8600  /* Firmware in poll diagnostic state */
+#define MBA_FW_RESET_FCT	0x8502	/* Firmware reset factory defaults */
 
 /* 83XX FCoE specific */
 #define MBA_IDC_AEN		0x8200  /* FCoE: NIC Core state change AEN */
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 413f050..7136bf5 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1539,6 +1539,9 @@ qlafx00_timer_routine(scsi_qla_host_t *vha)
 		} else if ((aenmbx0 & 0xFF00) == MBA_FW_POLL_STATE) {
 			ha->mr.fw_reset_timer_tick =
 			    QLAFX00_MAX_RESET_INTERVAL;
+		} else if (aenmbx0 == MBA_FW_RESET_FCT) {
+			ha->mr.fw_reset_timer_tick =
+			    QLAFX00_MAX_RESET_INTERVAL;
 		}
 		ha->mr.old_aenmbx0_state = aenmbx0;
 		ha->mr.fw_reset_timer_tick--;
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 06/29] qla2xxx: Perform warm reset every 2 minutes if firmware load fails for ISPFX00.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (4 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 05/29] qla2xxx: Set factory reset recovery timeout to 10 min. for ISPFX00 Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 07/29] qla2xxx: Add ISPFX00 specific bus reset routine Saurav Kashyap
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Acked-by: Srinivasa Rao <srinivasa.rao@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_mr.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 7136bf5..1aeb9e1 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1606,6 +1606,14 @@ qlafx00_abort_isp(scsi_qla_host_t *vha)
 
 		scsi_block_requests(vha->host);
 		qlafx00_abort_isp_cleanup(vha);
+	} else {
+		scsi_block_requests(vha->host);
+		clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		vha->qla_stats.total_isp_aborts++;
+		ha->isp_ops->reset_chip(vha);
+		set_bit(FX00_RESET_RECOVERY, &vha->dpc_flags);
+		/* Clear the Interrupts */
+		QLAFX00_CLR_INTR_REG(ha, QLAFX00_HST_INT_STS_BITS);
 	}
 
 	ql_log(ql_log_info, vha, 0x0145,
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 07/29] qla2xxx: Add ISPFX00 specific bus reset routine.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (5 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 06/29] qla2xxx: Perform warm reset every 2 minutes if firmware load fails " Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 08/29] qla2xxx: Remove QL_DEBUG_LEVEL_17 defines from qla_nx.c Saurav Kashyap
                   ` (22 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c |    2 +-
 drivers/scsi/qla2xxx/qla_gbl.h |    1 +
 drivers/scsi/qla2xxx/qla_mr.c  |   23 +++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_os.c  |    8 +++++---
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index aa10109..9d289a4 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -38,7 +38,7 @@
  * |                              |                    | 0x70ad-0x70ae, |
  * |                              |                    | 0x70d1-0x70da, |
  * |                              |                    | 0x7047,0x703b	|
- * | Task Management              |       0x803c       | 0x8025-0x8026  |
+ * | Task Management              |       0x803d       | 0x8025-0x8026  |
  * |                              |                    | 0x800b,0x8039  |
  * | AER/EEH                      |       0x9011       |		|
  * | Virtual Port                 |       0xa007       |		|
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 152e5dd..9ce9131 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -605,6 +605,7 @@ extern void qlafx00_abort_iocb(srb_t *, struct abort_iocb_entry_fx00 *);
 extern void qlafx00_fxdisc_iocb(srb_t *, struct fxdisc_entry_fx00 *);
 extern void qlafx00_timer_routine(scsi_qla_host_t *);
 extern int qlafx00_rescan_isp(scsi_qla_host_t *);
+extern int qlafx00_loop_reset(scsi_qla_host_t *vha);
 
 /* qla82xx related functions */
 
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 1aeb9e1..be60a77 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -776,6 +776,29 @@ qlafx00_lun_reset(fc_port_t *fcport, unsigned int l, int tag)
 }
 
 int
+qlafx00_loop_reset(scsi_qla_host_t *vha)
+{
+	int ret;
+	struct fc_port *fcport;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (ql2xtargetreset) {
+		list_for_each_entry(fcport, &vha->vp_fcports, list) {
+			if (fcport->port_type != FCT_TARGET)
+				continue;
+
+			ret = ha->isp_ops->target_reset(fcport, 0, 0);
+			if (ret != QLA_SUCCESS) {
+				ql_dbg(ql_dbg_taskm, vha, 0x803d,
+				    "Bus Reset failed: Reset=%d "
+				    "d_id=%x.\n", ret, fcport->d_id.b24);
+			}
+		}
+	}
+	return QLA_SUCCESS;
+}
+
+int
 qlafx00_iospace_config(struct qla_hw_data *ha)
 {
 	if (pci_request_selected_regions(ha->pdev, ha->bars,
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index f92b22b..3f53151 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1303,6 +1303,10 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
 	struct fc_port *fcport;
 	struct qla_hw_data *ha = vha->hw;
 
+	if (IS_QLAFX00(ha)) {
+		return qlafx00_loop_reset(vha);
+	}
+
 	if (ql2xtargetreset == 1 && ha->flags.enable_target_reset) {
 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
 			if (fcport->port_type != FCT_TARGET)
@@ -1311,14 +1315,12 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
 			ret = ha->isp_ops->target_reset(fcport, 0, 0);
 			if (ret != QLA_SUCCESS) {
 				ql_dbg(ql_dbg_taskm, vha, 0x802c,
-				    "Bus Reset failed: Target Reset=%d "
+				    "Bus Reset failed: Reset=%d "
 				    "d_id=%x.\n", ret, fcport->d_id.b24);
 			}
 		}
 	}
 
-	if (IS_QLAFX00(ha))
-		return QLA_SUCCESS;
 
 	if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) {
 		atomic_set(&vha->loop_state, LOOP_DOWN);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 08/29] qla2xxx: Remove QL_DEBUG_LEVEL_17 defines from qla_nx.c.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (6 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 07/29] qla2xxx: Add ISPFX00 specific bus reset routine Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 09/29] qla2xxx: Add setting of driver version string for vendor application Saurav Kashyap
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Chad Dupuis <chad.dupuis@qlogic.com>

Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c |    1 +
 drivers/scsi/qla2xxx/qla_nx.c  |   14 --------------
 2 files changed, 1 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 9d289a4..6ee4fcb 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -27,6 +27,7 @@
  * | Async Events                 |       0x5081       | 0x502b-0x502f  |
  * |                              |                    | 0x5047,0x5052  |
  * |                              |                    | 0x5040,0x5075  |
+ * |                              |                    | 0x503d,0x5044  |
  * | Timer Routines               |       0x6011       |                |
  * | User Space Interactions      |       0x70dd       | 0x7018,0x702e, |
  * |                              |                    | 0x7020,0x7024, |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 01b72e0..b3e48f5 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -2077,13 +2077,6 @@ qla82xx_intr_handler(int irq, void *dev_id)
 		WRT_REG_DWORD(&reg->host_int, 0);
 	}
 
-#ifdef QL_DEBUG_LEVEL_17
-	if (!irq && ha->flags.eeh_busy)
-		ql_log(ql_log_warn, vha, 0x503d,
-		    "isr:status %x, cmd_flags %lx, mbox_int %x, stat %x.\n",
-		    status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat);
-#endif
-
 	qla2x00_handle_mbx_completion(ha, status);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
@@ -2149,13 +2142,6 @@ qla82xx_msix_default(int irq, void *dev_id)
 		WRT_REG_DWORD(&reg->host_int, 0);
 	} while (0);
 
-#ifdef QL_DEBUG_LEVEL_17
-	if (!irq && ha->flags.eeh_busy)
-		ql_log(ql_log_warn, vha, 0x5044,
-		    "isr:status %x, cmd_flags %lx, mbox_int %x, stat %x.\n",
-		    status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat);
-#endif
-
 	qla2x00_handle_mbx_completion(ha, status);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 09/29] qla2xxx: Add setting of driver version string for vendor application.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (7 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 08/29] qla2xxx: Remove QL_DEBUG_LEVEL_17 defines from qla_nx.c Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 10/29] qla2xxx: Reconfigure thermal temperature Saurav Kashyap
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Joe Carnuccio <joe.carnuccio@qlogic.com>

Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c  |    2 +-
 drivers/scsi/qla2xxx/qla_def.h  |    1 +
 drivers/scsi/qla2xxx/qla_gbl.h  |    6 ++
 drivers/scsi/qla2xxx/qla_init.c |    5 ++
 drivers/scsi/qla2xxx/qla_mbx.c  |  106 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 119 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 6ee4fcb..ecaafe4 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -12,7 +12,7 @@
  * |             Level            |   Last Value Used  |     Holes	|
  * ----------------------------------------------------------------------
  * | Module Init and Probe        |       0x0151       | 0x4b,0xba,0xfa |
- * | Mailbox commands             |       0x117a       | 0x111a-0x111b  |
+ * | Mailbox commands             |       0x1181       | 0x111a-0x111b  |
  * |                              |                    | 0x1155-0x1158  |
  * | Device Discovery             |       0x2095       | 0x2020-0x2022, |
  * |                              |                    | 0x2011-0x2012, |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 58e4f19..f393d24 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -999,6 +999,7 @@ struct mbx_cmd_32 {
 #define	MBX_1		BIT_1
 #define	MBX_0		BIT_0
 
+#define RNID_TYPE_SET_VERSION	0x9
 #define RNID_TYPE_ASIC_TEMP	0xC
 
 /*
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 9ce9131..dc14ac2 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -357,6 +357,12 @@ extern int
 qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *);
 
 extern int
+qla82xx_set_driver_version(scsi_qla_host_t *, char *);
+
+extern int
+qla25xx_set_driver_version(scsi_qla_host_t *, char *);
+
+extern int
 qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint8_t *,
 	uint16_t, uint16_t, uint16_t, uint16_t);
 
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a92b166a..71cbdeb 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -626,6 +626,11 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
 	if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))
 		qla24xx_read_fcp_prio_cfg(vha);
 
+	if (IS_P3P_TYPE(ha))
+		qla82xx_set_driver_version(vha, QLA2XXX_VERSION);
+	else
+		qla25xx_set_driver_version(vha, QLA2XXX_VERSION);
+
 	return (rval);
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index bce41f4..ce76110 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3862,6 +3862,112 @@ qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
 	return rval;
 }
 
+int
+qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+	int i;
+	int len;
+	uint16_t *str;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (!IS_P3P_TYPE(ha))
+		return QLA_FUNCTION_FAILED;
+
+	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
+	    "Entered %s.\n", __func__);
+
+	str = (void *)version;
+	len = strlen(version);
+
+	mcp->mb[0] = MBC_SET_RNID_PARAMS;
+	mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
+	mcp->out_mb = MBX_1|MBX_0;
+	for (i = 4; i < 16 && len; i++, str++, len -= 2) {
+		mcp->mb[i] = cpu_to_le16p(str);
+		mcp->out_mb |= 1<<i;
+	}
+	for (; i < 16; i++) {
+		mcp->mb[i] = 0;
+		mcp->out_mb |= 1<<i;
+	}
+	mcp->in_mb = MBX_1|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(vha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0x117c,
+		    "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
+	} else {
+		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
+		    "Done %s.\n", __func__);
+	}
+
+	return rval;
+}
+
+int
+qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+	int len;
+	uint16_t dwlen;
+	uint8_t *str;
+	dma_addr_t str_dma;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
+	    IS_P3P_TYPE(ha))
+		return QLA_FUNCTION_FAILED;
+
+	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
+	    "Entered %s.\n", __func__);
+
+	str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
+	if (!str) {
+		ql_log(ql_log_warn, vha, 0x117f,
+		    "Failed to allocate driver version param.\n");
+		return QLA_MEMORY_ALLOC_FAILED;
+	}
+
+	memcpy(str, "\x7\x3\x11\x0", 4);
+	dwlen = str[0];
+	len = dwlen * 4 - 4;
+	memset(str + 4, 0, len);
+	if (len > strlen(version))
+		len = strlen(version);
+	memcpy(str + 4, version, len);
+
+	mcp->mb[0] = MBC_SET_RNID_PARAMS;
+	mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
+	mcp->mb[2] = MSW(LSD(str_dma));
+	mcp->mb[3] = LSW(LSD(str_dma));
+	mcp->mb[6] = MSW(MSD(str_dma));
+	mcp->mb[7] = LSW(MSD(str_dma));
+	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+	mcp->in_mb = MBX_1|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(vha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0x1180,
+		    "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
+	} else {
+		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
+		    "Done %s.\n", __func__);
+	}
+
+	dma_pool_free(ha->s_dma_pool, str, str_dma);
+
+	return rval;
+}
+
 static int
 qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
 {
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 10/29] qla2xxx: Reconfigure thermal temperature.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (8 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 09/29] qla2xxx: Add setting of driver version string for vendor application Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 11/29] qla2xxx: Notify ISPFX00 firmware when driver is unloaded or system is shut down Saurav Kashyap
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Joe Carnuccio <joe.carnuccio@qlogic.com>

For supported ISPS, Read asic temperature by calling the
GET PARAMS (type C) mailbox command.

Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_attr.c |    6 ----
 drivers/scsi/qla2xxx/qla_dbg.c  |    4 ++-
 drivers/scsi/qla2xxx/qla_def.h  |    3 --
 drivers/scsi/qla2xxx/qla_gbl.h  |    2 +
 drivers/scsi/qla2xxx/qla_init.c |    1 -
 drivers/scsi/qla2xxx/qla_mbx.c  |   61 ++++++++++++++++++++------------------
 drivers/scsi/qla2xxx/qla_mr.c   |    1 -
 drivers/scsi/qla2xxx/qla_nx.c   |    8 +++++
 drivers/scsi/qla2xxx/qla_nx2.c  |    8 +++++
 9 files changed, 53 insertions(+), 41 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 8e8b50e..93f3783 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1300,12 +1300,6 @@ qla2x00_thermal_temp_show(struct device *dev,
 	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 	uint16_t temp = 0;
 
-	if (!vha->hw->thermal_support) {
-		ql_log(ql_log_warn, vha, 0x70db,
-		    "Thermal not supported by this card.\n");
-		goto done;
-	}
-
 	if (qla2x00_reset_active(vha)) {
 		ql_log(ql_log_warn, vha, 0x70dc, "ISP reset active.\n");
 		goto done;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index ecaafe4..aa31f7a 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -14,6 +14,8 @@
  * | Module Init and Probe        |       0x0151       | 0x4b,0xba,0xfa |
  * | Mailbox commands             |       0x1181       | 0x111a-0x111b  |
  * |                              |                    | 0x1155-0x1158  |
+ * |                              |                    | 0x1018-0x1019  |
+ * |                              |                    | 0x10ca		|
  * | Device Discovery             |       0x2095       | 0x2020-0x2022, |
  * |                              |                    | 0x2011-0x2012, |
  * |                              |                    | 0x2016         |
@@ -37,7 +39,7 @@
  * |                              |                    | 0x70a5,0x70a6, |
  * |                              |                    | 0x70a8,0x70ab, |
  * |                              |                    | 0x70ad-0x70ae, |
- * |                              |                    | 0x70d1-0x70da, |
+ * |                              |                    | 0x70d1-0x70db, |
  * |                              |                    | 0x7047,0x703b	|
  * | Task Management              |       0x803d       | 0x8025-0x8026  |
  * |                              |                    | 0x800b,0x8039  |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index f393d24..a494e2e 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3304,9 +3304,6 @@ struct qla_hw_data {
 	struct mr_data_fx00 mr;
 
 	struct qlt_hw_data tgt;
-	uint16_t	thermal_support;
-#define THERMAL_SUPPORT_I2C BIT_0
-#define THERMAL_SUPPORT_ISP BIT_1
 };
 
 /*
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index dc14ac2..d03b15d 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -685,6 +685,8 @@ extern int qla81xx_get_led_config(scsi_qla_host_t *, uint16_t *);
 extern int qla82xx_mbx_beacon_ctl(scsi_qla_host_t *, int);
 extern char *qdev_state(uint32_t);
 extern void qla82xx_clear_pending_mbx(scsi_qla_host_t *);
+extern int qla82xx_read_temperature(scsi_qla_host_t *);
+extern int qla8044_read_temperature(scsi_qla_host_t *);
 
 /* BSG related functions */
 extern int qla24xx_bsg_request(struct fc_bsg_job *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 71cbdeb..91df7a5 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -524,7 +524,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
 	vha->flags.reset_active = 0;
 	ha->flags.pci_channel_io_perm_failure = 0;
 	ha->flags.eeh_busy = 0;
-	ha->thermal_support = THERMAL_SUPPORT_I2C|THERMAL_SUPPORT_ISP;
 	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
 	atomic_set(&vha->loop_state, LOOP_DOWN);
 	vha->device_flags = DFLG_NO_CABLE;
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index ce76110..1261884 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -4608,40 +4608,43 @@ qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
 	struct qla_hw_data *ha = vha->hw;
 	uint8_t byte;
 
-	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ca,
-	    "Entered %s.\n", __func__);
-
-	if (ha->thermal_support & THERMAL_SUPPORT_I2C) {
-		rval = qla2x00_read_sfp(vha, 0, &byte,
-		    0x98, 0x1, 1, BIT_13|BIT_12|BIT_0);
-		*temp = byte;
-		if (rval == QLA_SUCCESS)
-			goto done;
-
-		ql_log(ql_log_warn, vha, 0x10c9,
-		    "Thermal not supported through I2C bus, trying alternate "
-		    "method (ISP access).\n");
-		ha->thermal_support &= ~THERMAL_SUPPORT_I2C;
+	if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
+		ql_dbg(ql_dbg_mbx, vha, 0x1150,
+		    "Thermal not supported by this card.\n");
+		return rval;
 	}
 
-	if (ha->thermal_support & THERMAL_SUPPORT_ISP) {
-		rval = qla2x00_read_asic_temperature(vha, temp);
-		if (rval == QLA_SUCCESS)
-			goto done;
-
-		ql_log(ql_log_warn, vha, 0x1019,
-		    "Thermal not supported through ISP.\n");
-		ha->thermal_support &= ~THERMAL_SUPPORT_ISP;
+	if (IS_QLA25XX(ha)) {
+		if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
+		    ha->pdev->subsystem_device == 0x0175) {
+			rval = qla2x00_read_sfp(vha, 0, &byte,
+			    0x98, 0x1, 1, BIT_13|BIT_0);
+			*temp = byte;
+			return rval;
+		}
+		if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
+		    ha->pdev->subsystem_device == 0x338e) {
+			rval = qla2x00_read_sfp(vha, 0, &byte,
+			    0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
+			*temp = byte;
+			return rval;
+		}
+		ql_dbg(ql_dbg_mbx, vha, 0x10c9,
+		    "Thermal not supported by this card.\n");
+		return rval;
 	}
 
-	ql_log(ql_log_warn, vha, 0x1150,
-	    "Thermal not supported by this card "
-	    "(ignoring further requests).\n");
-	return  rval;
+	if (IS_QLA82XX(ha)) {
+		*temp = qla82xx_read_temperature(vha);
+		rval = QLA_SUCCESS;
+		return rval;
+	} else if (IS_QLA8044(ha)) {
+		*temp = qla8044_read_temperature(vha);
+		rval = QLA_SUCCESS;
+		return rval;
+	}
 
-done:
-	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1018,
-	    "Done %s.\n", __func__);
+	rval = qla2x00_read_asic_temperature(vha, temp);
 	return rval;
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index be60a77..e087a49 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -2062,7 +2062,6 @@ qlafx00_initialize_adapter(scsi_qla_host_t *vha)
 	vha->flags.reset_active = 0;
 	ha->flags.pci_channel_io_perm_failure = 0;
 	ha->flags.eeh_busy = 0;
-	ha->thermal_support = 0;
 	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
 	atomic_set(&vha->loop_state, LOOP_DOWN);
 	vha->device_flags = DFLG_NO_CABLE;
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index b3e48f5..11ce53d 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -3327,6 +3327,14 @@ static int qla82xx_check_temp(scsi_qla_host_t *vha)
 	return 0;
 }
 
+int qla82xx_read_temperature(scsi_qla_host_t *vha)
+{
+	uint32_t temp;
+
+	temp = qla82xx_rd_32(vha->hw, CRB_TEMP_STATE);
+	return qla82xx_get_temp_val(temp);
+}
+
 void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha)
 {
 	struct qla_hw_data *ha = vha->hw;
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c
index 005cd6b..712a9bb 100644
--- a/drivers/scsi/qla2xxx/qla_nx2.c
+++ b/drivers/scsi/qla2xxx/qla_nx2.c
@@ -1945,6 +1945,14 @@ qla8044_check_temp(struct scsi_qla_host *vha)
 	return 0;
 }
 
+int qla8044_read_temperature(scsi_qla_host_t *vha)
+{
+	uint32_t temp;
+
+	temp = qla8044_rd_direct(vha, QLA8044_CRB_TEMP_STATE_INDEX);
+	return qla82xx_get_temp_val(temp);
+}
+
 /**
  * qla8044_check_fw_alive  - Check firmware health
  * @ha: Pointer to host adapter structure.
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 11/29] qla2xxx: Notify ISPFX00 firmware when driver is unloaded or system is shut down.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (9 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 10/29] qla2xxx: Reconfigure thermal temperature Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 12/29] qla2xxx: Add critical temperature handling for ISPFX00 Saurav Kashyap
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Acked-by: Srinivasa Rao <srinivasa.rao@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_gbl.h |    1 +
 drivers/scsi/qla2xxx/qla_mr.c  |    2 +-
 drivers/scsi/qla2xxx/qla_os.c  |    7 +++++++
 3 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index d03b15d..9a80c49 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -594,6 +594,7 @@ extern int qlafx00_start_scsi(srb_t *);
 extern int qlafx00_abort_isp(scsi_qla_host_t *);
 extern int qlafx00_iospace_config(struct qla_hw_data *);
 extern int qlafx00_init_firmware(scsi_qla_host_t *, uint16_t);
+extern int qlafx00_driver_shutdown(scsi_qla_host_t *, int);
 extern int qlafx00_fw_ready(scsi_qla_host_t *);
 extern int qlafx00_configure_devices(scsi_qla_host_t *);
 extern int qlafx00_reset_initialize(scsi_qla_host_t *);
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index e087a49..ab2ae8e 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -294,7 +294,7 @@ premature_exit:
  * Context:
  *	Kernel context.
  */
-static int
+int
 qlafx00_driver_shutdown(scsi_qla_host_t *vha, int tmo)
 {
 	int rval;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3f53151..17a86b6 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3006,6 +3006,10 @@ qla2x00_shutdown(struct pci_dev *pdev)
 	vha = pci_get_drvdata(pdev);
 	ha = vha->hw;
 
+	/* Notify ISPFX00 firmware */
+	if (IS_QLAFX00(ha))
+		qlafx00_driver_shutdown(vha, 20);
+
 	/* Turn-off FCE trace */
 	if (ha->flags.fce_enabled) {
 		qla2x00_disable_fce_trace(vha, NULL, NULL);
@@ -3053,6 +3057,9 @@ qla2x00_remove_one(struct pci_dev *pdev)
 	ha->flags.host_shutting_down = 1;
 
 	set_bit(UNLOADING, &base_vha->dpc_flags);
+	if (IS_QLAFX00(ha))
+		qlafx00_driver_shutdown(base_vha, 20);
+
 	mutex_lock(&ha->vport_lock);
 	while (ha->cur_vport_count) {
 		spin_lock_irqsave(&ha->vport_slock, flags);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 12/29] qla2xxx: Add critical temperature handling for ISPFX00.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (10 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 11/29] qla2xxx: Notify ISPFX00 firmware when driver is unloaded or system is shut down Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 13/29] qla2xxx: Make log message that prints when a completion status requires a port down more readable Saurav Kashyap
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Acked-by: Srinivasa Rao <srinivasa.rao@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c |    6 +-
 drivers/scsi/qla2xxx/qla_def.h |    1 +
 drivers/scsi/qla2xxx/qla_mr.c  |   86 ++++++++++++++++++++++++++++++++++------
 drivers/scsi/qla2xxx/qla_mr.h  |   27 ++++++++++++-
 drivers/scsi/qla2xxx/qla_os.c  |    1 +
 5 files changed, 104 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index aa31f7a..b1b6bc1 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -11,7 +11,7 @@
  * ----------------------------------------------------------------------
  * |             Level            |   Last Value Used  |     Holes	|
  * ----------------------------------------------------------------------
- * | Module Init and Probe        |       0x0151       | 0x4b,0xba,0xfa |
+ * | Module Init and Probe        |       0x0152       | 0x4b,0xba,0xfa |
  * | Mailbox commands             |       0x1181       | 0x111a-0x111b  |
  * |                              |                    | 0x1155-0x1158  |
  * |                              |                    | 0x1018-0x1019  |
@@ -26,11 +26,11 @@
  * |                              |                    | 0x3036,0x3038  |
  * |                              |                    | 0x303a		|
  * | DPC Thread                   |       0x4022       | 0x4002,0x4013  |
- * | Async Events                 |       0x5081       | 0x502b-0x502f  |
+ * | Async Events                 |       0x5083       | 0x502b-0x502f  |
  * |                              |                    | 0x5047,0x5052  |
  * |                              |                    | 0x5040,0x5075  |
  * |                              |                    | 0x503d,0x5044  |
- * | Timer Routines               |       0x6011       |                |
+ * | Timer Routines               |       0x6012       |                |
  * | User Space Interactions      |       0x70dd       | 0x7018,0x702e, |
  * |                              |                    | 0x7020,0x7024, |
  * |                              |                    | 0x7039,0x7045, |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index a494e2e..e5d3373 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3369,6 +3369,7 @@ typedef struct scsi_qla_host {
 #define PORT_UPDATE_NEEDED	24
 #define FX00_RESET_RECOVERY	25
 #define FX00_TARGET_SCAN	26
+#define FX00_CRITEMP_RECOVERY	27
 
 	uint32_t	device_flags;
 #define SWITCH_FOUND		BIT_0
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index ab2ae8e..27b8af8 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1372,21 +1372,22 @@ qlafx00_configure_devices(scsi_qla_host_t *vha)
 }
 
 static void
-qlafx00_abort_isp_cleanup(scsi_qla_host_t *vha)
+qlafx00_abort_isp_cleanup(scsi_qla_host_t *vha, bool critemp)
 {
 	struct qla_hw_data *ha = vha->hw;
 	fc_port_t *fcport;
 
 	vha->flags.online = 0;
-	ha->flags.chip_reset_done = 0;
 	ha->mr.fw_hbt_en = 0;
-	clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
-	vha->qla_stats.total_isp_aborts++;
-
-	ql_log(ql_log_info, vha, 0x013f,
-	    "Performing ISP error recovery - ha = %p.\n", ha);
 
-	ha->isp_ops->reset_chip(vha);
+	if (!critemp) {
+		ha->flags.chip_reset_done = 0;
+		clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		vha->qla_stats.total_isp_aborts++;
+		ql_log(ql_log_info, vha, 0x013f,
+		    "Performing ISP error recovery - ha = %p.\n", ha);
+		ha->isp_ops->reset_chip(vha);
+	}
 
 	if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
 		atomic_set(&vha->loop_state, LOOP_DOWN);
@@ -1406,12 +1407,19 @@ qlafx00_abort_isp_cleanup(scsi_qla_host_t *vha)
 	}
 
 	if (!ha->flags.eeh_busy) {
-		/* Requeue all commands in outstanding command list. */
-		qla2x00_abort_all_cmds(vha, DID_RESET << 16);
+		if (critemp) {
+			qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
+		} else {
+			/* Requeue all commands in outstanding command list. */
+			qla2x00_abort_all_cmds(vha, DID_RESET << 16);
+		}
 	}
 
 	qla2x00_free_irqs(vha);
-	set_bit(FX00_RESET_RECOVERY, &vha->dpc_flags);
+	if (critemp)
+		set_bit(FX00_CRITEMP_RECOVERY, &vha->dpc_flags);
+	else
+		set_bit(FX00_RESET_RECOVERY, &vha->dpc_flags);
 
 	/* Clear the Interrupts */
 	QLAFX00_CLR_INTR_REG(ha, QLAFX00_HST_INT_STS_BITS);
@@ -1498,6 +1506,7 @@ qlafx00_timer_routine(scsi_qla_host_t *vha)
 	uint32_t fw_heart_beat;
 	uint32_t aenmbx0;
 	struct device_reg_fx00 __iomem *reg = &ha->iobase->ispfx00;
+	uint32_t tempc;
 
 	/* Check firmware health */
 	if (ha->mr.fw_hbt_cnt)
@@ -1569,6 +1578,29 @@ qlafx00_timer_routine(scsi_qla_host_t *vha)
 		ha->mr.old_aenmbx0_state = aenmbx0;
 		ha->mr.fw_reset_timer_tick--;
 	}
+	if (test_bit(FX00_CRITEMP_RECOVERY, &vha->dpc_flags)) {
+		/*
+		 * Critical temperature recovery to be
+		 * performed in timer routine
+		 */
+		if (ha->mr.fw_critemp_timer_tick == 0) {
+			tempc = QLAFX00_GET_TEMPERATURE(ha);
+			ql_log(ql_dbg_timer, vha, 0x6012,
+			    "ISPFx00(%s): Critical temp timer, "
+			    "current SOC temperature: %d\n",
+			    __func__, tempc);
+			if (tempc < ha->mr.critical_temperature) {
+				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+				clear_bit(FX00_CRITEMP_RECOVERY,
+				    &vha->dpc_flags);
+				qla2xxx_wake_dpc(vha);
+			}
+			ha->mr.fw_critemp_timer_tick =
+			    QLAFX00_CRITEMP_INTERVAL;
+		} else {
+			ha->mr.fw_critemp_timer_tick--;
+		}
+	}
 }
 
 /*
@@ -1596,7 +1628,7 @@ qlafx00_reset_initialize(scsi_qla_host_t *vha)
 
 	if (vha->flags.online) {
 		scsi_block_requests(vha->host);
-		qlafx00_abort_isp_cleanup(vha);
+		qlafx00_abort_isp_cleanup(vha, false);
 	}
 
 	ql_log(ql_log_info, vha, 0x0143,
@@ -1628,7 +1660,7 @@ qlafx00_abort_isp(scsi_qla_host_t *vha)
 		}
 
 		scsi_block_requests(vha->host);
-		qlafx00_abort_isp_cleanup(vha);
+		qlafx00_abort_isp_cleanup(vha, false);
 	} else {
 		scsi_block_requests(vha->host);
 		clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -1722,6 +1754,16 @@ qlafx00_process_aen(struct scsi_qla_host *vha, struct qla_work_evt *evt)
 		aen_code = FCH_EVT_LINKDOWN;
 		aen_data = 0;
 		break;
+	case QLAFX00_MBA_TEMP_OVER:
+	case QLAFX00_MBA_TEMP_CRIT:	/* Critical temperature event */
+		ql_log(ql_log_info, vha, 0x5082,
+		    "Process critical temperature event "
+		    "aenmb[0]: %x\n",
+		    evt->u.aenfx.evtcode);
+		scsi_block_requests(vha->host);
+		qlafx00_abort_isp_cleanup(vha, true);
+		scsi_unblock_requests(vha->host);
+		break;
 	}
 
 	fc_host_post_event(vha->host, fc_get_event_number(),
@@ -1913,6 +1955,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
 		    sizeof(vha->hw->mr.uboot_version));
 		memcpy(&vha->hw->mr.fru_serial_num, pinfo->fru_serial_num,
 		    sizeof(vha->hw->mr.fru_serial_num));
+		vha->hw->mr.critical_temperature = pinfo->nominal_temp_value;
 	} else if (fx_type == FXDISC_GET_PORT_INFO) {
 		struct port_info_data *pinfo =
 		    (struct port_info_data *) fdisc->u.fxiocb.rsp_addr;
@@ -2055,6 +2098,7 @@ qlafx00_initialize_adapter(scsi_qla_host_t *vha)
 {
 	int	rval;
 	struct qla_hw_data *ha = vha->hw;
+	uint32_t tempc;
 
 	/* Clear adapter flags. */
 	vha->flags.online = 0;
@@ -2105,6 +2149,11 @@ qlafx00_initialize_adapter(scsi_qla_host_t *vha)
 	rval = qla2x00_init_rings(vha);
 	ha->flags.chip_reset_done = 1;
 
+	tempc = QLAFX00_GET_TEMPERATURE(ha);
+	ql_dbg(ql_dbg_init, vha, 0x0152,
+	    "ISPFx00(%s): Critical temp timer, current SOC temperature: 0x%x\n",
+	    __func__, tempc);
+
 	return rval;
 }
 
@@ -2854,6 +2903,17 @@ qlafx00_async_event(scsi_qla_host_t *vha)
 		    ha->aenmb[0], ha->aenmb[1], ha->aenmb[2], ha->aenmb[3]);
 		data_size = 4;
 		break;
+
+	case QLAFX00_MBA_TEMP_OVER:	/* Over temperature event */
+	case QLAFX00_MBA_TEMP_CRIT:	/* Critical temperature event */
+		ql_log(ql_log_info, vha, 0x5083,
+		    "Asynchronous critical temperature event received "
+		    "aenmb[0]: %x\n",
+		ha->aenmb[0]);
+		qlafx00_post_aenfx_work(vha, ha->aenmb[0],
+		    (uint32_t *)ha->aenmb, 1);
+		break;
+
 	default:
 		ha->aenmb[1] = RD_REG_WORD(&reg->aenmailbox1);
 		ha->aenmb[2] = RD_REG_WORD(&reg->aenmailbox2);
diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h
index 179f8e4..982f7d3 100644
--- a/drivers/scsi/qla2xxx/qla_mr.h
+++ b/drivers/scsi/qla2xxx/qla_mr.h
@@ -329,11 +329,13 @@ struct config_info_data {
 	uint64_t	adapter_id;
 
 	uint32_t	cluster_key_len;
-	uint8_t		cluster_key[10];
+	uint8_t		cluster_key[16];
 
 	uint64_t	cluster_master_id;
 	uint64_t	cluster_slave_id;
 	uint8_t		cluster_flags;
+	uint32_t	enabled_capabilities;
+	uint32_t	nominal_temp_value;
 } __packed;
 
 #define FXDISC_GET_CONFIG_INFO		0x01
@@ -346,6 +348,7 @@ struct config_info_data {
 #define QLAFX00_ICR_ENB_MASK            0x80000000
 #define QLAFX00_ICR_DIS_MASK            0x7fffffff
 #define QLAFX00_HST_RST_REG		0x18264
+#define QLAFX00_SOC_TEMP_REG		0x184C4
 #define QLAFX00_HST_TO_HBA_REG		0x20A04
 #define QLAFX00_HBA_TO_HOST_REG		0x21B70
 #define QLAFX00_HST_INT_STS_BITS	0x7
@@ -361,6 +364,9 @@ struct config_info_data {
 #define QLAFX00_INTR_ALL_CMPLT		0x7
 
 #define QLAFX00_MBA_SYSTEM_ERR		0x8002
+#define QLAFX00_MBA_TEMP_OVER		0x8005
+#define QLAFX00_MBA_TEMP_NORM		0x8006
+#define	QLAFX00_MBA_TEMP_CRIT		0x8007
 #define QLAFX00_MBA_LINK_UP		0x8011
 #define QLAFX00_MBA_LINK_DOWN		0x8012
 #define QLAFX00_MBA_PORT_UPDATE		0x8014
@@ -501,12 +507,31 @@ struct mr_data_fx00 {
 	uint32_t old_fw_hbt_cnt;
 	uint16_t fw_reset_timer_tick;
 	uint8_t fw_reset_timer_exp;
+	uint16_t fw_critemp_timer_tick;
 	uint32_t old_aenmbx0_state;
+	uint32_t critical_temperature;
 };
 
+/*
+ * SoC Junction Temperature is stored in
+ * bits 9:1 of SoC Junction Temperature Register
+ * in a firmware specific format format.
+ * To get the temperature in Celsius degrees
+ * the value from this bitfiled should be converted
+ * using this formula:
+ * Temperature (degrees C) = ((3,153,000 - (10,000 * X)) / 13,825)
+ * where X is the bit field value
+ * this macro reads the register, extracts the bitfield value,
+ * performs the calcualtions and returns temperature in Celsius
+ */
+#define QLAFX00_GET_TEMPERATURE(ha) ((3153000 - (10000 * \
+	((QLAFX00_RD_REG(ha, QLAFX00_SOC_TEMP_REG) & 0x3FE) >> 1))) / 13825)
+
+
 #define QLAFX00_LOOP_DOWN_TIME		615     /* 600 */
 #define QLAFX00_HEARTBEAT_INTERVAL	6	/* number of seconds */
 #define QLAFX00_HEARTBEAT_MISS_CNT	3	/* number of miss */
 #define QLAFX00_RESET_INTERVAL		120	/* number of seconds */
 #define QLAFX00_MAX_RESET_INTERVAL	600	/* number of seconds */
+#define QLAFX00_CRITEMP_INTERVAL	60	/* number of seconds */
 #endif
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 17a86b6..7a81ede 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2575,6 +2575,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->port_down_retry_count = 30; /* default value */
 		ha->mr.fw_hbt_cnt = QLAFX00_HEARTBEAT_INTERVAL;
 		ha->mr.fw_reset_timer_tick = QLAFX00_RESET_INTERVAL;
+		ha->mr.fw_critemp_timer_tick = QLAFX00_CRITEMP_INTERVAL;
 		ha->mr.fw_hbt_en = 1;
 	}
 
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 13/29] qla2xxx: Make log message that prints when a completion status requires a port down more readable.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (11 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 12/29] qla2xxx: Add critical temperature handling for ISPFX00 Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 14/29] qla2xxx: Add missing FCP statistics to sysfs interface Saurav Kashyap
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Chad Dupuis <chad.dupuis@qlogic.com>

Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_isr.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index b4fb8a6..4a9782c 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2178,8 +2178,10 @@ check_scsi_status:
 		}
 
 		ql_dbg(ql_dbg_io, fcport->vha, 0x3021,
-		    "Port down status: port-state=0x%x.\n",
-		    atomic_read(&fcport->state));
+		    "Port to be marked lost on fcport=%02x%02x%02x, current "
+		    "port state= %s.\n", fcport->d_id.b.domain,
+		    fcport->d_id.b.area, fcport->d_id.b.al_pa,
+		    port_state_str[atomic_read(&fcport->state)]);
 
 		if (atomic_read(&fcport->state) == FCS_ONLINE)
 			qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 14/29] qla2xxx: Add missing FCP statistics to sysfs interface.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (12 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 13/29] qla2xxx: Make log message that prints when a completion status requires a port down more readable Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 15/29] qla2xxx: Add changes to support extended IOs for ISPFX00 Saurav Kashyap
                   ` (15 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Joe Carnuccio <joe.carnuccio@qlogic.com>

Add the missing FCP statistics to sysfs.
Add reset FCP statistics functionality via sysfs.

Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_attr.c |   25 ++++++++++++++++++++++++-
 drivers/scsi/qla2xxx/qla_def.h  |   10 ++++++++--
 drivers/scsi/qla2xxx/qla_gs.c   |    6 ++++++
 drivers/scsi/qla2xxx/qla_init.c |    1 +
 drivers/scsi/qla2xxx/qla_iocb.c |   13 +++++++++++++
 drivers/scsi/qla2xxx/qla_isr.c  |    3 +++
 6 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 93f3783..85aad4a 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1732,11 +1732,21 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
 		pfc_host_stat->lip_count = stats->lip_cnt;
 		pfc_host_stat->tx_frames = stats->tx_frames;
 		pfc_host_stat->rx_frames = stats->rx_frames;
-		pfc_host_stat->dumped_frames = stats->dumped_frames;
+		pfc_host_stat->dumped_frames = stats->discarded_frames;
 		pfc_host_stat->nos_count = stats->nos_rcvd;
+		pfc_host_stat->error_frames =
+			stats->dropped_frames + stats->discarded_frames;
+		pfc_host_stat->rx_words = vha->qla_stats.input_bytes;
+		pfc_host_stat->tx_words = vha->qla_stats.output_bytes;
 	}
+	pfc_host_stat->fcp_control_requests = vha->qla_stats.control_requests;
+	pfc_host_stat->fcp_input_requests = vha->qla_stats.input_requests;
+	pfc_host_stat->fcp_output_requests = vha->qla_stats.output_requests;
 	pfc_host_stat->fcp_input_megabytes = vha->qla_stats.input_bytes >> 20;
 	pfc_host_stat->fcp_output_megabytes = vha->qla_stats.output_bytes >> 20;
+	pfc_host_stat->seconds_since_last_reset =
+		get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset;
+	do_div(pfc_host_stat->seconds_since_last_reset, HZ);
 
 done_free:
         dma_pool_free(ha->s_dma_pool, stats, stats_dma);
@@ -1745,6 +1755,16 @@ done:
 }
 
 static void
+qla2x00_reset_host_stats(struct Scsi_Host *shost)
+{
+	scsi_qla_host_t *vha = shost_priv(shost);
+
+	memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat));
+
+	vha->qla_stats.jiffies_at_last_reset = get_jiffies_64();
+}
+
+static void
 qla2x00_get_host_symbolic_name(struct Scsi_Host *shost)
 {
 	scsi_qla_host_t *vha = shost_priv(shost);
@@ -2050,6 +2070,7 @@ struct fc_function_template qla2xxx_transport_functions = {
 	.dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
 	.terminate_rport_io = qla2x00_terminate_rport_io,
 	.get_fc_host_stats = qla2x00_get_fc_host_stats,
+	.reset_fc_host_stats = qla2x00_reset_host_stats,
 
 	.vport_create = qla24xx_vport_create,
 	.vport_disable = qla24xx_vport_disable,
@@ -2096,6 +2117,8 @@ struct fc_function_template qla2xxx_transport_vport_functions = {
 	.dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
 	.terminate_rport_io = qla2x00_terminate_rport_io,
 	.get_fc_host_stats = qla2x00_get_fc_host_stats,
+	.reset_fc_host_stats = qla2x00_reset_host_stats,
+
 	.bsg_request = qla24xx_bsg_request,
 	.bsg_timeout = qla24xx_bsg_timeout,
 };
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index e5d3373..0aa1bea 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1236,8 +1236,9 @@ struct link_statistics {
 	uint32_t unused1[0x1a];
 	uint32_t tx_frames;
 	uint32_t rx_frames;
-	uint32_t dumped_frames;
-	uint32_t unused2[2];
+	uint32_t discarded_frames;
+	uint32_t dropped_frames;
+	uint32_t unused2[1];
 	uint32_t nos_rcvd;
 };
 
@@ -2659,6 +2660,11 @@ struct qla_statistics {
 	uint32_t total_isp_aborts;
 	uint64_t input_bytes;
 	uint64_t output_bytes;
+	uint64_t input_requests;
+	uint64_t output_requests;
+	uint32_t control_requests;
+
+	uint64_t jiffies_at_last_reset;
 };
 
 struct bidi_statistics {
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 84cce36..cd47f1b 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -49,6 +49,8 @@ qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
 	ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
 	ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
 
+	vha->qla_stats.control_requests++;
+
 	return (ms_pkt);
 }
 
@@ -87,6 +89,8 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
 	ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
 	ct_pkt->vp_index = vha->vp_idx;
 
+	vha->qla_stats.control_requests++;
+
 	return (ct_pkt);
 }
 
@@ -723,6 +727,8 @@ qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
 	wc = (data_size - 16) / 4;		/* Size in 32bit words. */
 	sns_cmd->p.cmd.size = cpu_to_le16(wc);
 
+	vha->qla_stats.control_requests++;
+
 	return (sns_cmd);
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 91df7a5..03f715e 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -524,6 +524,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
 	vha->flags.reset_active = 0;
 	ha->flags.pci_channel_io_perm_failure = 0;
 	ha->flags.eeh_busy = 0;
+	vha->qla_stats.jiffies_at_last_reset = get_jiffies_64();
 	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
 	atomic_set(&vha->loop_state, LOOP_DOWN);
 	vha->device_flags = DFLG_NO_CABLE;
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index e2a7d2d..46b9307 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -32,9 +32,11 @@ qla2x00_get_cmd_direction(srb_t *sp)
 	if (cmd->sc_data_direction == DMA_TO_DEVICE) {
 		cflags = CF_WRITE;
 		vha->qla_stats.output_bytes += scsi_bufflen(cmd);
+		vha->qla_stats.output_requests++;
 	} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
 		cflags = CF_READ;
 		vha->qla_stats.input_bytes += scsi_bufflen(cmd);
+		vha->qla_stats.input_requests++;
 	}
 	return (cflags);
 }
@@ -642,10 +644,12 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
 		cmd_pkt->control_flags =
 		    __constant_cpu_to_le16(CF_WRITE_DATA);
 		vha->qla_stats.output_bytes += scsi_bufflen(cmd);
+		vha->qla_stats.output_requests++;
 	} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
 		cmd_pkt->control_flags =
 		    __constant_cpu_to_le16(CF_READ_DATA);
 		vha->qla_stats.input_bytes += scsi_bufflen(cmd);
+		vha->qla_stats.input_requests++;
 	}
 
 	cur_seg = scsi_sglist(cmd);
@@ -758,10 +762,12 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
 		cmd_pkt->task_mgmt_flags =
 		    __constant_cpu_to_le16(TMF_WRITE_DATA);
 		vha->qla_stats.output_bytes += scsi_bufflen(cmd);
+		vha->qla_stats.output_requests++;
 	} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
 		cmd_pkt->task_mgmt_flags =
 		    __constant_cpu_to_le16(TMF_READ_DATA);
 		vha->qla_stats.input_bytes += scsi_bufflen(cmd);
+		vha->qla_stats.input_requests++;
 	}
 
 	/* One DSD is available in the Command Type 3 IOCB */
@@ -2056,6 +2062,8 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
             (bsg_job->reply_payload.sg_list)));
         els_iocb->rx_len = cpu_to_le32(sg_dma_len
             (bsg_job->reply_payload.sg_list));
+
+	sp->fcport->vha->qla_stats.control_requests++;
 }
 
 static void
@@ -2133,6 +2141,8 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb)
 		avail_dsds--;
 	}
 	ct_iocb->entry_count = entry_count;
+
+	sp->fcport->vha->qla_stats.control_requests++;
 }
 
 static void
@@ -2685,6 +2695,9 @@ qla25xx_build_bidir_iocb(srb_t *sp, struct scsi_qla_host *vha,
 	vha->bidi_stats.transfer_bytes += req_data_len;
 	vha->bidi_stats.io_count++;
 
+	vha->qla_stats.output_bytes += req_data_len;
+	vha->qla_stats.output_requests++;
+
 	/* Only one dsd is available for bidirectional IOCB, remaining dsds
 	 * are bundled in continuation iocb
 	 */
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 4a9782c..bbc24d3 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1807,6 +1807,9 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
 		if (scsi_status == 0) {
 			bsg_job->reply->reply_payload_rcv_len =
 					bsg_job->reply_payload.payload_len;
+			vha->qla_stats.input_bytes +=
+				bsg_job->reply->reply_payload_rcv_len;
+			vha->qla_stats.input_requests++;
 			rval = EXT_STATUS_OK;
 		}
 		goto done;
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 15/29] qla2xxx: Add changes to support extended IOs for ISPFX00
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (13 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 14/29] qla2xxx: Add missing FCP statistics to sysfs interface Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 16/29] qla2xxx: Add changes in initialization for ISPFX00 cards with BIOS Saurav Kashyap
                   ` (14 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_mr.c |    5 ++---
 drivers/scsi/qla2xxx/qla_mr.h |    3 +++
 drivers/scsi/qla2xxx/qla_os.c |   10 +++++++---
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 27b8af8..f4c5d74 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1956,6 +1956,8 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
 		memcpy(&vha->hw->mr.fru_serial_num, pinfo->fru_serial_num,
 		    sizeof(vha->hw->mr.fru_serial_num));
 		vha->hw->mr.critical_temperature = pinfo->nominal_temp_value;
+		ha->mr.extended_io_enabled = (pinfo->enabled_capabilities &
+		    QLAFX00_EXTENDED_IO_EN_MASK) != 0;
 	} else if (fx_type == FXDISC_GET_PORT_INFO) {
 		struct port_info_data *pinfo =
 		    (struct port_info_data *) fdisc->u.fxiocb.rsp_addr;
@@ -2799,9 +2801,6 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha,
 	struct sts_entry_fx00 *pkt;
 	response_t *lptr;
 
-	if (!vha->flags.online)
-		return;
-
 	while (RD_REG_DWORD((void __iomem *)&(rsp->ring_ptr->signature)) !=
 	    RESPONSE_PROCESSED) {
 		lptr = rsp->ring_ptr;
diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h
index 982f7d3..772860b 100644
--- a/drivers/scsi/qla2xxx/qla_mr.h
+++ b/drivers/scsi/qla2xxx/qla_mr.h
@@ -510,8 +510,11 @@ struct mr_data_fx00 {
 	uint16_t fw_critemp_timer_tick;
 	uint32_t old_aenmbx0_state;
 	uint32_t critical_temperature;
+	bool extended_io_enabled;
 };
 
+#define QLAFX00_EXTENDED_IO_EN_MASK    0x20
+
 /*
  * SoC Junction Temperature is stored in
  * bits 9:1 of SoC Junction Temperature Register
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7a81ede..e1808b9 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2876,6 +2876,13 @@ skip_dpc:
 
 	ha->isp_ops->enable_intrs(ha);
 
+	if (IS_QLAFX00(ha)) {
+		ret = qlafx00_fx_disc(base_vha,
+			&base_vha->hw->mr.fcport, FXDISC_GET_CONFIG_INFO);
+		host->sg_tablesize = (ha->mr.extended_io_enabled) ?
+		    QLA_SG_ALL : 128;
+	}
+
 	ret = scsi_add_host(host, &pdev->dev);
 	if (ret)
 		goto probe_failed;
@@ -2896,9 +2903,6 @@ skip_dpc:
 
 	if (IS_QLAFX00(ha)) {
 		ret = qlafx00_fx_disc(base_vha,
-			&base_vha->hw->mr.fcport, FXDISC_GET_CONFIG_INFO);
-
-		ret = qlafx00_fx_disc(base_vha,
 			&base_vha->hw->mr.fcport, FXDISC_GET_PORT_INFO);
 
 		/* Register system information */
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 16/29] qla2xxx: Add changes in initialization for ISPFX00 cards with BIOS
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (14 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 15/29] qla2xxx: Add changes to support extended IOs for ISPFX00 Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 17/29] qla2xxx: Send all AENs for ISPFx00 to above layers Saurav Kashyap
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_def.h |    1 +
 drivers/scsi/qla2xxx/qla_mr.c  |   11 +++++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 0aa1bea..d6eefb8 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -643,6 +643,7 @@ struct device_reg_fx00 {
 	uint32_t initval6;		/* C8 */
 	uint32_t initval7;		/* CC */
 	uint32_t fwheartbeat;		/* D0 */
+	uint32_t pseudoaen;		/* D4 */
 };
 
 
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index f4c5d74..85587de 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -941,12 +941,23 @@ qlafx00_init_fw_ready(scsi_qla_host_t *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct device_reg_fx00 __iomem *reg = &ha->iobase->ispfx00;
 	uint32_t aenmbx, aenmbx7 = 0;
+	uint32_t pseudo_aen;
 	uint32_t state[5];
 	bool done = false;
 
 	/* 30 seconds wait - Adjust if required */
 	wait_time = 30;
 
+	pseudo_aen = RD_REG_DWORD(&reg->pseudoaen);
+	if (pseudo_aen == 1) {
+		aenmbx7 = RD_REG_DWORD(&reg->initval7);
+		ha->mbx_intr_code = MSW(aenmbx7);
+		ha->rqstq_intr_code = LSW(aenmbx7);
+		rval = qlafx00_driver_shutdown(vha, 10);
+		if (rval != QLA_SUCCESS)
+			qlafx00_soft_reset(vha);
+	}
+
 	/* wait time before firmware ready */
 	wtime = jiffies + (wait_time * HZ);
 	do {
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 17/29] qla2xxx: Send all AENs for ISPFx00 to above layers.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (15 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 16/29] qla2xxx: Add changes in initialization for ISPFX00 cards with BIOS Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 18/29] qla2xxx: Remove handling of Shutdown Requested AEN from qlafx00_process_aen() Saurav Kashyap
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_mr.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 85587de..ae1d00c6 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1734,6 +1734,10 @@ qlafx00_process_aen(struct scsi_qla_host *vha, struct qla_work_evt *evt)
 	aen_data = evt->u.aenfx.evtcode;
 
 	switch (evt->u.aenfx.evtcode) {
+	case QLAFX00_MBA_SHUTDOWN_RQSTD: /* FW shutdown pending */
+		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		rval = qlafx00_driver_shutdown(vha, 10);
+		break;
 	case QLAFX00_MBA_PORT_UPDATE:		/* Port database update */
 		if (evt->u.aenfx.mbx[1] == 0) {
 			if (evt->u.aenfx.mbx[2] == 1) {
@@ -2920,8 +2924,6 @@ qlafx00_async_event(scsi_qla_host_t *vha)
 		    "Asynchronous critical temperature event received "
 		    "aenmb[0]: %x\n",
 		ha->aenmb[0]);
-		qlafx00_post_aenfx_work(vha, ha->aenmb[0],
-		    (uint32_t *)ha->aenmb, 1);
 		break;
 
 	default:
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 18/29] qla2xxx: Remove handling of Shutdown Requested AEN from qlafx00_process_aen().
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (16 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 17/29] qla2xxx: Send all AENs for ISPFx00 to above layers Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 19/29] qla2xxx: Correct Interrupt Register offset for ISPFX00 Saurav Kashyap
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_mr.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index ae1d00c6..470f070 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1734,10 +1734,6 @@ qlafx00_process_aen(struct scsi_qla_host *vha, struct qla_work_evt *evt)
 	aen_data = evt->u.aenfx.evtcode;
 
 	switch (evt->u.aenfx.evtcode) {
-	case QLAFX00_MBA_SHUTDOWN_RQSTD: /* FW shutdown pending */
-		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
-		rval = qlafx00_driver_shutdown(vha, 10);
-		break;
 	case QLAFX00_MBA_PORT_UPDATE:		/* Port database update */
 		if (evt->u.aenfx.mbx[1] == 0) {
 			if (evt->u.aenfx.mbx[2] == 1) {
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 19/29] qla2xxx: Correct Interrupt Register offset for ISPFX00
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (17 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 18/29] qla2xxx: Remove handling of Shutdown Requested AEN from qlafx00_process_aen() Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 20/29] qla2xxx: QLAFX00 make over temperature AEN handling informational, add log for normal temperature AEN Saurav Kashyap
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_mr.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h
index 772860b..7b33416 100644
--- a/drivers/scsi/qla2xxx/qla_mr.h
+++ b/drivers/scsi/qla2xxx/qla_mr.h
@@ -344,7 +344,7 @@ struct config_info_data {
 #define FXDISC_GET_TGT_NODE_LIST	0x81
 #define FXDISC_REG_HOST_INFO		0x99
 
-#define QLAFX00_HBA_ICNTRL_REG		0x21B08
+#define QLAFX00_HBA_ICNTRL_REG		0x20B08
 #define QLAFX00_ICR_ENB_MASK            0x80000000
 #define QLAFX00_ICR_DIS_MASK            0x7fffffff
 #define QLAFX00_HST_RST_REG		0x18264
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 20/29] qla2xxx: QLAFX00 make over temperature AEN handling informational, add log for normal temperature AEN
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (18 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 19/29] qla2xxx: Correct Interrupt Register offset for ISPFX00 Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 21/29] qla2xxx: Set default critical temperature value in cases when ISPFX00 firmware doesn't provide it Saurav Kashyap
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c |    2 +-
 drivers/scsi/qla2xxx/qla_mr.c  |   14 +++++++++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index b1b6bc1..ca6bcf6 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -26,7 +26,7 @@
  * |                              |                    | 0x3036,0x3038  |
  * |                              |                    | 0x303a		|
  * | DPC Thread                   |       0x4022       | 0x4002,0x4013  |
- * | Async Events                 |       0x5083       | 0x502b-0x502f  |
+ * | Async Events                 |       0x5086       | 0x502b-0x502f  |
  * |                              |                    | 0x5047,0x5052  |
  * |                              |                    | 0x5040,0x5075  |
  * |                              |                    | 0x503d,0x5044  |
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 470f070..e48a71e 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1765,7 +1765,6 @@ qlafx00_process_aen(struct scsi_qla_host *vha, struct qla_work_evt *evt)
 		aen_code = FCH_EVT_LINKDOWN;
 		aen_data = 0;
 		break;
-	case QLAFX00_MBA_TEMP_OVER:
 	case QLAFX00_MBA_TEMP_CRIT:	/* Critical temperature event */
 		ql_log(ql_log_info, vha, 0x5082,
 		    "Process critical temperature event "
@@ -2915,6 +2914,19 @@ qlafx00_async_event(scsi_qla_host_t *vha)
 		break;
 
 	case QLAFX00_MBA_TEMP_OVER:	/* Over temperature event */
+		ql_log(ql_log_info, vha, 0x5085,
+		    "Asynchronous over temperature event received "
+		    "aenmb[0]: %x\n",
+		    ha->aenmb[0]);
+		break;
+
+	case QLAFX00_MBA_TEMP_NORM:	/* Normal temperature event */
+		ql_log(ql_log_info, vha, 0x5086,
+		    "Asynchronous normal temperature event received "
+		    "aenmb[0]: %x\n",
+		    ha->aenmb[0]);
+		break;
+
 	case QLAFX00_MBA_TEMP_CRIT:	/* Critical temperature event */
 		ql_log(ql_log_info, vha, 0x5083,
 		    "Asynchronous critical temperature event received "
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 21/29] qla2xxx: Set default critical temperature value in cases when ISPFX00 firmware doesn't provide it
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (19 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 20/29] qla2xxx: QLAFX00 make over temperature AEN handling informational, add log for normal temperature AEN Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 22/29] qla2xxx: Add loopback IDC-TIME-EXTEND aen handling support Saurav Kashyap
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Armen Baloyan <armen.baloyan@qlogic.com>

Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_mr.c |    4 +++-
 drivers/scsi/qla2xxx/qla_mr.h |    3 +++
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index e48a71e..39d1306 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1965,7 +1965,9 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
 		    sizeof(vha->hw->mr.uboot_version));
 		memcpy(&vha->hw->mr.fru_serial_num, pinfo->fru_serial_num,
 		    sizeof(vha->hw->mr.fru_serial_num));
-		vha->hw->mr.critical_temperature = pinfo->nominal_temp_value;
+		vha->hw->mr.critical_temperature =
+		    (pinfo->nominal_temp_value) ?
+		    pinfo->nominal_temp_value : QLAFX00_CRITEMP_THRSHLD;
 		ha->mr.extended_io_enabled = (pinfo->enabled_capabilities &
 		    QLAFX00_EXTENDED_IO_EN_MASK) != 0;
 	} else if (fx_type == FXDISC_GET_PORT_INFO) {
diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h
index 7b33416..79a93c5 100644
--- a/drivers/scsi/qla2xxx/qla_mr.h
+++ b/drivers/scsi/qla2xxx/qla_mr.h
@@ -537,4 +537,7 @@ struct mr_data_fx00 {
 #define QLAFX00_RESET_INTERVAL		120	/* number of seconds */
 #define QLAFX00_MAX_RESET_INTERVAL	600	/* number of seconds */
 #define QLAFX00_CRITEMP_INTERVAL	60	/* number of seconds */
+
+#define QLAFX00_CRITEMP_THRSHLD		80	/* Celsius degrees */
+
 #endif
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 22/29] qla2xxx: Add loopback IDC-TIME-EXTEND aen handling support.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (20 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 21/29] qla2xxx: Set default critical temperature value in cases when ISPFX00 firmware doesn't provide it Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 23/29] qla2xxx: Select link initialization option bits from current operating mode Saurav Kashyap
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Santosh Vernekar <santosh.vernekar@qlogic.com>

Earlier IDC-TIME-EXTEND aen was a nop and ignored by driver.
We now have to handle the aen so that other protocol drivers can use time
extension during some loopback operations.

Signed-off-by: Santosh Vernekar <santosh.vernekar@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_bsg.c |   17 ++++++++++++-
 drivers/scsi/qla2xxx/qla_dbg.c |    2 +-
 drivers/scsi/qla2xxx/qla_def.h |    1 +
 drivers/scsi/qla2xxx/qla_isr.c |   47 +++++++++++++++++++++++++--------------
 4 files changed, 47 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index fb5bd6e..b989add 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -627,6 +627,7 @@ qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
 {
 	int ret = 0;
 	int rval = 0;
+	unsigned long rem_tmo = 0, current_tmo = 0;
 	struct qla_hw_data *ha = vha->hw;
 
 	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
@@ -652,8 +653,19 @@ qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
 	}
 
 	/* Wait for DCBX complete event */
-	if (!wait_for_completion_timeout(&ha->dcbx_comp,
-	    (DCBX_COMP_TIMEOUT * HZ))) {
+	current_tmo = DCBX_COMP_TIMEOUT * HZ;
+	while (1) {
+		rem_tmo = wait_for_completion_timeout(&ha->dcbx_comp,
+		    current_tmo);
+		if (!ha->idc_extend_tmo || rem_tmo) {
+			ha->idc_extend_tmo = 0;
+			break;
+		}
+		current_tmo = ha->idc_extend_tmo * HZ;
+		ha->idc_extend_tmo = 0;
+	}
+
+	if (!rem_tmo) {
 		ql_dbg(ql_dbg_user, vha, 0x7022,
 		    "DCBX completion not received.\n");
 		ret = qla81xx_reset_loopback_mode(vha, new_config, 0, 0);
@@ -678,6 +690,7 @@ qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
 	}
 
 	ha->notify_dcbx_comp = 0;
+	ha->idc_extend_tmo = 0;
 
 done_set_internal:
 	return rval;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index ca6bcf6..f192c52 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -26,7 +26,7 @@
  * |                              |                    | 0x3036,0x3038  |
  * |                              |                    | 0x303a		|
  * | DPC Thread                   |       0x4022       | 0x4002,0x4013  |
- * | Async Events                 |       0x5086       | 0x502b-0x502f  |
+ * | Async Events                 |       0x5087       | 0x502b-0x502f  |
  * |                              |                    | 0x5047,0x5052  |
  * |                              |                    | 0x5040,0x5075  |
  * |                              |                    | 0x503d,0x5044  |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index d6eefb8..93db74e 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -3292,6 +3292,7 @@ struct qla_hw_data {
 
 	/* QLA83XX IDC specific fields */
 	uint32_t	idc_audit_ts;
+	uint32_t	idc_extend_tmo;
 
 	/* DPC low-priority workqueue */
 	struct workqueue_struct *dpc_lp_wq;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index bbc24d3..df1b30b 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -282,25 +282,38 @@ qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr)
 	    "%04x %04x %04x %04x %04x %04x %04x.\n",
 	    event[aen & 0xff], mb[0], mb[1], mb[2], mb[3],
 	    mb[4], mb[5], mb[6]);
-	if ((aen == MBA_IDC_COMPLETE && mb[1] >> 15)) {
-		vha->hw->flags.idc_compl_status = 1;
-		if (vha->hw->notify_dcbx_comp)
-			complete(&vha->hw->dcbx_comp);
-	}
-
-	/* Acknowledgement needed? [Notify && non-zero timeout]. */
-	timeout = (descr >> 8) & 0xf;
-	if (aen != MBA_IDC_NOTIFY || !timeout)
-		return;
+	switch (aen) {
+	/* Handle IDC Error completion case. */
+	case MBA_IDC_COMPLETE:
+		if (mb[1] >> 15) {
+			vha->hw->flags.idc_compl_status = 1;
+			if (vha->hw->notify_dcbx_comp)
+				complete(&vha->hw->dcbx_comp);
+		}
+		break;
 
-	ql_dbg(ql_dbg_async, vha, 0x5022,
-	    "%lu Inter-Driver Communication %s -- ACK timeout=%d.\n",
-	    vha->host_no, event[aen & 0xff], timeout);
+	case MBA_IDC_NOTIFY:
+		/* Acknowledgement needed? [Notify && non-zero timeout]. */
+		timeout = (descr >> 8) & 0xf;
+		ql_dbg(ql_dbg_async, vha, 0x5022,
+		    "%lu Inter-Driver Communication %s -- ACK timeout=%d.\n",
+		    vha->host_no, event[aen & 0xff], timeout);
 
-	rval = qla2x00_post_idc_ack_work(vha, mb);
-	if (rval != QLA_SUCCESS)
-		ql_log(ql_log_warn, vha, 0x5023,
-		    "IDC failed to post ACK.\n");
+		if (!timeout)
+			return;
+		rval = qla2x00_post_idc_ack_work(vha, mb);
+		if (rval != QLA_SUCCESS)
+			ql_log(ql_log_warn, vha, 0x5023,
+			    "IDC failed to post ACK.\n");
+		break;
+	case MBA_IDC_TIME_EXT:
+		vha->hw->idc_extend_tmo = descr;
+		ql_dbg(ql_dbg_async, vha, 0x5087,
+		    "%lu Inter-Driver Communication %s -- "
+		    "Extend timeout by=%d.\n",
+		    vha->host_no, event[aen & 0xff], vha->hw->idc_extend_tmo);
+		break;
+	}
 }
 
 #define LS_UNKNOWN	2
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 23/29] qla2xxx: Select link initialization option bits from current operating mode.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (21 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 22/29] qla2xxx: Add loopback IDC-TIME-EXTEND aen handling support Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 24/29] qla2xxx: Move queue depth ramp down message to i/o debug level Saurav Kashyap
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Joe Carnuccio <joe.carnuccio@qlogic.com>

Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_mbx.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 1261884..c825d1d 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1667,7 +1667,11 @@ qla24xx_link_initialize(scsi_qla_host_t *vha)
 		return QLA_FUNCTION_FAILED;
 
 	mcp->mb[0] = MBC_LINK_INITIALIZATION;
-	mcp->mb[1] = BIT_6|BIT_4;
+	mcp->mb[1] = BIT_4;
+	if (vha->hw->operating_mode == LOOP)
+		mcp->mb[1] |= BIT_6;
+	else
+		mcp->mb[1] |= BIT_5;
 	mcp->mb[2] = 0;
 	mcp->mb[3] = 0;
 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 24/29] qla2xxx: Move queue depth ramp down message to i/o debug level.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (22 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 23/29] qla2xxx: Select link initialization option bits from current operating mode Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 25/29] qla2xxx: Add a new interface to update versions Saurav Kashyap
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Chad Dupuis <chad.dupuis@qlogic.com>

Unless there is a need to observe them, the queue depth ramp up/down messages
are a nuisance and may cause the system to become unresponsive so move it a
non-default logging level.

Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_os.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index e1808b9..9f01bbb 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1508,7 +1508,7 @@ qla2x00_host_ramp_down_queuedepth(scsi_qla_host_t *vha)
 			if (sdev->queue_depth > shost->cmd_per_lun) {
 				if (sdev->queue_depth < ha->cfg_lun_q_depth)
 					continue;
-				ql_log(ql_log_warn, vp, 0x3031,
+				ql_dbg(ql_dbg_io, vp, 0x3031,
 				    "%ld:%d:%d: Ramping down queue depth to %d",
 				    vp->host_no, sdev->id, sdev->lun,
 				    ha->cfg_lun_q_depth);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 25/29] qla2xxx: Add a new interface to update versions.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (23 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 24/29] qla2xxx: Move queue depth ramp down message to i/o debug level Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 26/29] qla2xxx: Correctly print out/in mailbox registers Saurav Kashyap
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Sawan Chandak <sawan.chandak@qlogic.com>

On any Adapter when we flash through FC/FCoE without card reset option it still
shows the Running FW version in Flashed FW version. This new interface will be
used by API to instruct the driver to update its cache versions.

Signed-off-by: Sawan Chandak <sawan.chandak@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_attr.c |   14 +++++++++++++-
 drivers/scsi/qla2xxx/qla_dbg.c  |    2 +-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 85aad4a..b1d32c4 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -590,7 +590,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
 	int type;
 	uint32_t idc_control;
-
+	uint8_t *tmp_data = NULL;
 	if (off != 0)
 		return -EINVAL;
 
@@ -687,7 +687,19 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
 		__qla83xx_set_idc_control(vha, idc_control);
 		qla83xx_idc_unlock(vha, 0);
 		break;
+	case 0x20261:
+		ql_dbg(ql_dbg_user, vha, 0x70e0,
+		    "Updating cache versions without reset ");
 
+		tmp_data = vmalloc(256);
+		if (!tmp_data) {
+			ql_log(ql_log_warn, vha, 0x70e1,
+			    "Unable to allocate memory for VPD information update.\n");
+			return -ENOMEM;
+		}
+		ha->isp_ops->get_flash_version(vha, tmp_data);
+		vfree(tmp_data);
+		break;
 	}
 	return count;
 }
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index f192c52..f693b30 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -31,7 +31,7 @@
  * |                              |                    | 0x5040,0x5075  |
  * |                              |                    | 0x503d,0x5044  |
  * | Timer Routines               |       0x6012       |                |
- * | User Space Interactions      |       0x70dd       | 0x7018,0x702e, |
+ * | User Space Interactions      |       0x70e1       | 0x7018,0x702e, |
  * |                              |                    | 0x7020,0x7024, |
  * |                              |                    | 0x7039,0x7045, |
  * |                              |                    | 0x7073-0x7075, |
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 26/29] qla2xxx: Correctly print out/in mailbox registers.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (24 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 25/29] qla2xxx: Add a new interface to update versions Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 27/29] qla2xxx: Correction to message ids Saurav Kashyap
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Joe Carnuccio <joe.carnuccio@qlogic.com>

At mailbox/buffer debug level, print the correct values of the
outgoing and incoming mailbox registers.

Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_mbx.c |   28 +++++++++++++---------------
 1 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index c825d1d..a9aae50 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -117,33 +117,25 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	command = mcp->mb[0];
 	mboxes = mcp->out_mb;
 
+	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1111,
+	    "Mailbox registers (OUT):\n");
 	for (cnt = 0; cnt < ha->mbx_count; cnt++) {
 		if (IS_QLA2200(ha) && cnt == 8)
 			optr =
 			    (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
-		if (mboxes & BIT_0)
+		if (mboxes & BIT_0) {
+			ql_dbg(ql_dbg_mbx, vha, 0x1112,
+			    "mbox[%d]<-0x%04x\n", cnt, *iptr);
 			WRT_REG_WORD(optr, *iptr);
+		}
 
 		mboxes >>= 1;
 		optr++;
 		iptr++;
 	}
 
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1111,
-	    "Loaded MBX registers (displayed in bytes) =.\n");
-	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1112,
-	    (uint8_t *)mcp->mb, 16);
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1113,
-	    ".\n");
-	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1114,
-	    ((uint8_t *)mcp->mb + 0x10), 16);
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1115,
-	    ".\n");
-	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1116,
-	    ((uint8_t *)mcp->mb + 0x20), 8);
 	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
 	    "I/O Address = %p.\n", optr);
-	ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x100e);
 
 	/* Issue set host interrupt command to send cmd out. */
 	ha->flags.mbox_int = 0;
@@ -254,9 +246,15 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 		iptr2 = mcp->mb;
 		iptr = (uint16_t *)&ha->mailbox_out[0];
 		mboxes = mcp->in_mb;
+
+		ql_dbg(ql_dbg_mbx, vha, 0x1113,
+		    "Mailbox registers (IN):\n");
 		for (cnt = 0; cnt < ha->mbx_count; cnt++) {
-			if (mboxes & BIT_0)
+			if (mboxes & BIT_0) {
 				*iptr2 = *iptr;
+				ql_dbg(ql_dbg_mbx, vha, 0x1114,
+				    "mbox[%d]->0x%04x\n", cnt, *iptr2);
+			}
 
 			mboxes >>= 1;
 			iptr2++;
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 27/29] qla2xxx: Correction to message ids.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (25 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 26/29] qla2xxx: Correctly print out/in mailbox registers Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 28/29] qla2xxx: print MAC via %pMR Saurav Kashyap
                   ` (2 subsequent siblings)
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_dbg.c |   12 ++++++++----
 drivers/scsi/qla2xxx/qla_mr.c  |    2 +-
 drivers/scsi/qla2xxx/qla_nx2.c |   10 +++++-----
 drivers/scsi/qla2xxx/qla_sup.c |    2 +-
 4 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index f693b30..2ef497e 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -11,10 +11,11 @@
  * ----------------------------------------------------------------------
  * |             Level            |   Last Value Used  |     Holes	|
  * ----------------------------------------------------------------------
- * | Module Init and Probe        |       0x0152       | 0x4b,0xba,0xfa |
+ * | Module Init and Probe        |       0x0159       | 0x4b,0xba,0xfa |
  * | Mailbox commands             |       0x1181       | 0x111a-0x111b  |
  * |                              |                    | 0x1155-0x1158  |
  * |                              |                    | 0x1018-0x1019  |
+ * |                              |                    | 0x1115-0x1116  |
  * |                              |                    | 0x10ca		|
  * | Device Discovery             |       0x2095       | 0x2020-0x2022, |
  * |                              |                    | 0x2011-0x2012, |
@@ -28,7 +29,7 @@
  * | DPC Thread                   |       0x4022       | 0x4002,0x4013  |
  * | Async Events                 |       0x5087       | 0x502b-0x502f  |
  * |                              |                    | 0x5047,0x5052  |
- * |                              |                    | 0x5040,0x5075  |
+ * |                              |                    | 0x5084,0x5075	|
  * |                              |                    | 0x503d,0x5044  |
  * | Timer Routines               |       0x6012       |                |
  * | User Space Interactions      |       0x70e1       | 0x7018,0x702e, |
@@ -41,6 +42,7 @@
  * |                              |                    | 0x70ad-0x70ae, |
  * |                              |                    | 0x70d1-0x70db, |
  * |                              |                    | 0x7047,0x703b	|
+ * |                              |                    | 0x70de-0x70df, |
  * | Task Management              |       0x803d       | 0x8025-0x8026  |
  * |                              |                    | 0x800b,0x8039  |
  * | AER/EEH                      |       0x9011       |		|
@@ -54,10 +56,12 @@
  * |                              |                    | 0xb12c,0xb12d  |
  * |                              |                    | 0xb13a,0xb142  |
  * |                              |                    | 0xb13c-0xb140  |
+ * |                              |                    | 0xb149		|
  * | MultiQ                       |       0xc00c       |		|
  * | Misc                         |       0xd010       |		|
- * | Target Mode		  |	  0xe070       |		|
- * | Target Mode Management	  |	  0xf072       |		|
+ * | Target Mode		  |	  0xe070       | 0xe021		|
+ * | Target Mode Management	  |	  0xf072       | 0xf002-0xf003	|
+ * |                              |                    | 0xf046-0xf049  |
  * | Target Mode Task Management  |	  0x1000b      |		|
  * ----------------------------------------------------------------------
  */
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 39d1306..2482975 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1596,7 +1596,7 @@ qlafx00_timer_routine(scsi_qla_host_t *vha)
 		 */
 		if (ha->mr.fw_critemp_timer_tick == 0) {
 			tempc = QLAFX00_GET_TEMPERATURE(ha);
-			ql_log(ql_dbg_timer, vha, 0x6012,
+			ql_dbg(ql_dbg_timer, vha, 0x6012,
 			    "ISPFx00(%s): Critical temp timer, "
 			    "current SOC temperature: %d\n",
 			    __func__, tempc);
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c
index 712a9bb..a26ce74 100644
--- a/drivers/scsi/qla2xxx/qla_nx2.c
+++ b/drivers/scsi/qla2xxx/qla_nx2.c
@@ -3153,7 +3153,7 @@ qla8044_poll_flash_status_reg(struct scsi_qla_host *vha)
 		ret_val = qla8044_rd_reg_indirect(vha, QLA8044_FLASH_STATUS,
 		    &flash_status);
 		if (ret_val) {
-			ql_log(ql_log_warn, vha, 0xb120,
+			ql_log(ql_log_warn, vha, 0xb13c,
 			    "%s: Failed to read FLASH_STATUS reg.\n",
 			    __func__);
 			break;
@@ -3484,7 +3484,7 @@ qla8044_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
 		}
 		erase_offset += QLA8044_SECTOR_SIZE;
 	}
-	ql_dbg(ql_dbg_user, vha, 0xb139,
+	ql_dbg(ql_dbg_user, vha, 0xb13f,
 	    "Got write for addr = 0x%x length=0x%x.\n",
 	    offset, length);
 
@@ -3653,7 +3653,7 @@ qla8044_clear_rst_ready(scsi_qla_host_t *vha)
 	 */
 	drv_state &= ~(1 << vha->hw->portnum);
 
-	ql_dbg(ql_dbg_p3p, vha, 0xb143,
+	ql_dbg(ql_dbg_p3p, vha, 0xb13d,
 	    "drv_state: 0x%08x\n", drv_state);
 	qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, drv_state);
 }
@@ -3681,13 +3681,13 @@ qla8044_abort_isp(scsi_qla_host_t *vha)
 		/* If IDC_CTRL DONTRESETHBA_BIT0 is set don't do reset
 		 * recovery */
 		if (qla8044_idc_dontreset(ha) == DONTRESET_BIT0) {
-			ql_dbg(ql_dbg_p3p, vha, 0xb144,
+			ql_dbg(ql_dbg_p3p, vha, 0xb13e,
 			    "Reset recovery disabled\n");
 			rval = QLA_FUNCTION_FAILED;
 			goto exit_isp_reset;
 		}
 
-		ql_dbg(ql_dbg_p3p, vha, 0xb145,
+		ql_dbg(ql_dbg_p3p, vha, 0xb140,
 		    "HW State: NEED RESET\n");
 		qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
 		    QLA8XXX_DEV_NEED_RESET);
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 2f2e029..bd56cde 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -2944,7 +2944,7 @@ qla82xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
 		ha->fw_revision[0] = bcode[0x4];
 		ha->fw_revision[1] = bcode[0x5];
 		ha->fw_revision[2] = bcode[0x6];
-		ql_dbg(ql_dbg_init, vha, 0x015a,
+		ql_dbg(ql_dbg_init, vha, 0x0153,
 		    "Firmware revision %d.%d.%d\n",
 		    ha->fw_revision[0], ha->fw_revision[1],
 		    ha->fw_revision[2]);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 28/29] qla2xxx: print MAC via %pMR.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (26 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 27/29] qla2xxx: Correction to message ids Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-27  5:37 ` [PATCH 29/29] qla2xxx: Update the driver version to 8.06.00.08-k Saurav Kashyap
  2013-08-28  3:24 ` [PATCH 00/29] Update driver " James Bottomley
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_attr.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index b1d32c4..5f174b8 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1290,10 +1290,7 @@ qla2x00_vn_port_mac_address_show(struct device *dev,
 	if (!IS_CNA_CAPABLE(vha->hw))
 		return snprintf(buf, PAGE_SIZE, "\n");
 
-	return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
-	    vha->fcoe_vn_port_mac[5], vha->fcoe_vn_port_mac[4],
-	    vha->fcoe_vn_port_mac[3], vha->fcoe_vn_port_mac[2],
-	    vha->fcoe_vn_port_mac[1], vha->fcoe_vn_port_mac[0]);
+	return snprintf(buf, PAGE_SIZE, "%pMR\n", vha->fcoe_vn_port_mac);
 }
 
 static ssize_t
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 29/29] qla2xxx: Update the driver version to 8.06.00.08-k.
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (27 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 28/29] qla2xxx: print MAC via %pMR Saurav Kashyap
@ 2013-08-27  5:37 ` Saurav Kashyap
  2013-08-28  3:24 ` [PATCH 00/29] Update driver " James Bottomley
  29 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-27  5:37 UTC (permalink / raw)
  To: jbottomley; +Cc: giridhar.malavali, saurav.kashyap, andrew.vasquez, linux-scsi

Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_version.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 6c66d22..a808e29 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.05.00.03-k"
+#define QLA2XXX_VERSION      "8.06.00.08-k"
 
 #define QLA_DRIVER_MAJOR_VER	8
-#define QLA_DRIVER_MINOR_VER	5
+#define QLA_DRIVER_MINOR_VER	6
 #define QLA_DRIVER_PATCH_VER	0
 #define QLA_DRIVER_BETA_VER	0
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH 00/29] Update driver to 8.06.00.08-k
  2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
                   ` (28 preceding siblings ...)
  2013-08-27  5:37 ` [PATCH 29/29] qla2xxx: Update the driver version to 8.06.00.08-k Saurav Kashyap
@ 2013-08-28  3:24 ` James Bottomley
  2013-08-28  4:31   ` Saurav Kashyap
  29 siblings, 1 reply; 34+ messages in thread
From: James Bottomley @ 2013-08-28  3:24 UTC (permalink / raw)
  To: Saurav Kashyap; +Cc: giridhar.malavali, andrew.vasquez, linux-scsi

On Tue, 2013-08-27 at 01:37 -0400, Saurav Kashyap wrote:
> Hi James,
> 
> Please apply the following patches to the scsi tree, misc branch at your
> earliest convenience.

Patch 26/29 is missing.

James


^ permalink raw reply	[flat|nested] 34+ messages in thread

* RE: [PATCH 00/29] Update driver to 8.06.00.08-k
  2013-08-28  3:24 ` [PATCH 00/29] Update driver " James Bottomley
@ 2013-08-28  4:31   ` Saurav Kashyap
  0 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-28  4:31 UTC (permalink / raw)
  To: James Bottomley; +Cc: Giridhar Malavali, Andrew Vasquez, linux-scsi

[-- Attachment #1: Type: text/plain, Size: 3247 bytes --]

HI James,

There is some issue with an exchange server and this particular patch is not going out. Please find the patch inline and attached with this email.

Thanks,
~Saurav


From: Joe Carnuccio <joe.carnuccio@qlogic.com>
Date: Fri, 23 Aug 2013 07:25:37 -0700
Subject: [PATCH 26/29] qla2xxx: Correctly print out/in mailbox registers.

At mailbox/buffer debug level, print the correct values of the
outgoing and incoming mailbox registers.

Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
---
 drivers/scsi/qla2xxx/qla_mbx.c |   28 +++++++++++++---------------
 1 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index c825d1d..a9aae50 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -117,33 +117,25 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	command = mcp->mb[0];
 	mboxes = mcp->out_mb;
 
+	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1111,
+	    "Mailbox registers (OUT):\n");
 	for (cnt = 0; cnt < ha->mbx_count; cnt++) {
 		if (IS_QLA2200(ha) && cnt == 8)
 			optr =
 			    (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
-		if (mboxes & BIT_0)
+		if (mboxes & BIT_0) {
+			ql_dbg(ql_dbg_mbx, vha, 0x1112,
+			    "mbox[%d]<-0x%04x\n", cnt, *iptr);
 			WRT_REG_WORD(optr, *iptr);
+		}
 
 		mboxes >>= 1;
 		optr++;
 		iptr++;
 	}
 
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1111,
-	    "Loaded MBX registers (displayed in bytes) =.\n");
-	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1112,
-	    (uint8_t *)mcp->mb, 16);
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1113,
-	    ".\n");
-	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1114,
-	    ((uint8_t *)mcp->mb + 0x10), 16);
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1115,
-	    ".\n");
-	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1116,
-	    ((uint8_t *)mcp->mb + 0x20), 8);
 	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
 	    "I/O Address = %p.\n", optr);
-	ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x100e);
 
 	/* Issue set host interrupt command to send cmd out. */
 	ha->flags.mbox_int = 0;
@@ -254,9 +246,15 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 		iptr2 = mcp->mb;
 		iptr = (uint16_t *)&ha->mailbox_out[0];
 		mboxes = mcp->in_mb;
+
+		ql_dbg(ql_dbg_mbx, vha, 0x1113,
+		    "Mailbox registers (IN):\n");
 		for (cnt = 0; cnt < ha->mbx_count; cnt++) {
-			if (mboxes & BIT_0)
+			if (mboxes & BIT_0) {
 				*iptr2 = *iptr;
+				ql_dbg(ql_dbg_mbx, vha, 0x1114,
+				    "mbox[%d]->0x%04x\n", cnt, *iptr2);
+			}
 
 			mboxes >>= 1;
 			iptr2++;
-- 
1.7.7
________________________________________
From: James Bottomley [jbottomley@parallels.com]
Sent: Wednesday, August 28, 2013 8:54 AM
To: Saurav Kashyap
Cc: Giridhar Malavali; Andrew Vasquez; linux-scsi
Subject: Re: [PATCH 00/29] Update driver to 8.06.00.08-k

On Tue, 2013-08-27 at 01:37 -0400, Saurav Kashyap wrote:
> Hi James,
>
> Please apply the following patches to the scsi tree, misc branch at your
> earliest convenience.

Patch 26/29 is missing.

James


[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 8076 bytes --]

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH 02/29] qla2xxx: Add support for ISP8044.
  2013-08-27  5:37 ` [PATCH 02/29] qla2xxx: Add support for ISP8044 Saurav Kashyap
@ 2013-08-28  7:15   ` James Bottomley
  2013-08-28 13:33     ` Saurav Kashyap
  0 siblings, 1 reply; 34+ messages in thread
From: James Bottomley @ 2013-08-28  7:15 UTC (permalink / raw)
  To: Saurav Kashyap; +Cc: giridhar.malavali, andrew.vasquez, linux-scsi

On Tue, 2013-08-27 at 01:37 -0400, Saurav Kashyap wrote:
> From: Atul Deshmukh <atul.deshmukh@qlogic.com>

You seem to have stopped running your stuff through checkpatch:

WARNING: please, no spaces at the start of a line
#317: FILE: drivers/scsi/qla2xxx/qla_gbl.h:479:
+    uint8_t *, uint32_t, uint32_t);$

WARNING: please, no spaces at the start of a line
#341: FILE: drivers/scsi/qla2xxx/qla_gbl.h:713:
+    const uint32_t crb_reg, const uint32_t value);$

WARNING: please, no spaces at the start of a line
#351: FILE: drivers/scsi/qla2xxx/qla_gbl.h:723:
+    uint32_t, uint32_t);$

WARNING: please, no spaces at the start of a line
#3175: FILE: drivers/scsi/qla2xxx/qla_nx2.c:2084:
+    struct qla8044_minidump_entry_hdr *entry_hdr)$

WARNING: please, no spaces at the start of a line
#4258: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3167:
+    uint32_t data)$

WARNING: please, no spaces at the start of a line
#4334: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3243:
+    uint32_t sector_start_addr)$

WARNING: please, no spaces at the start of a line
#4390: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3299:
+    uint32_t *p_data)$

WARNING: please, no spaces at the start of a line
#4425: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3334:
+    uint32_t faddr, uint32_t dwords)$

WARNING: please, no spaces at the start of a line
#4508: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3417:
+    uint32_t faddr, uint32_t dwords)$

WARNING: please, no spaces at the start of a line
#4528: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3437:
+    uint32_t offset, uint32_t length)$

total: 0 errors, 10 warnings, 5781 lines checked

Please don't; those are all legitimate problems.

James


^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 02/29] qla2xxx: Add support for ISP8044.
  2013-08-28  7:15   ` James Bottomley
@ 2013-08-28 13:33     ` Saurav Kashyap
  0 siblings, 0 replies; 34+ messages in thread
From: Saurav Kashyap @ 2013-08-28 13:33 UTC (permalink / raw)
  To: James Bottomley; +Cc: Giridhar Malavali, Andrew Vasquez, linux-scsi

[-- Attachment #1: Type: text/plain, Size: 2015 bytes --]

Hi James,
Comments inline..

>On Tue, 2013-08-27 at 01:37 -0400, Saurav Kashyap wrote:
>> From: Atul Deshmukh <atul.deshmukh@qlogic.com>
>
>You seem to have stopped running your stuff through checkpatch:

<SK> We did run all the patches through checkpatch before submission, did
see the warnings and was trying to keep with the formatting in the rest of
the file(s).
We will take care of this in future.

Thanks,
~Saurav


>
>WARNING: please, no spaces at the start of a line
>#317: FILE: drivers/scsi/qla2xxx/qla_gbl.h:479:
>+    uint8_t *, uint32_t, uint32_t);$
>
>WARNING: please, no spaces at the start of a line
>#341: FILE: drivers/scsi/qla2xxx/qla_gbl.h:713:
>+    const uint32_t crb_reg, const uint32_t value);$
>
>WARNING: please, no spaces at the start of a line
>#351: FILE: drivers/scsi/qla2xxx/qla_gbl.h:723:
>+    uint32_t, uint32_t);$
>
>WARNING: please, no spaces at the start of a line
>#3175: FILE: drivers/scsi/qla2xxx/qla_nx2.c:2084:
>+    struct qla8044_minidump_entry_hdr *entry_hdr)$
>
>WARNING: please, no spaces at the start of a line
>#4258: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3167:
>+    uint32_t data)$
>
>WARNING: please, no spaces at the start of a line
>#4334: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3243:
>+    uint32_t sector_start_addr)$
>
>WARNING: please, no spaces at the start of a line
>#4390: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3299:
>+    uint32_t *p_data)$
>
>WARNING: please, no spaces at the start of a line
>#4425: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3334:
>+    uint32_t faddr, uint32_t dwords)$
>
>WARNING: please, no spaces at the start of a line
>#4508: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3417:
>+    uint32_t faddr, uint32_t dwords)$
>
>WARNING: please, no spaces at the start of a line
>#4528: FILE: drivers/scsi/qla2xxx/qla_nx2.c:3437:
>+    uint32_t offset, uint32_t length)$
>
>total: 0 errors, 10 warnings, 5781 lines checked
>
>Please don't; those are all legitimate problems.
>
>James
>


[-- Attachment #2: winmail.dat --]
[-- Type: application/ms-tnef, Size: 4380 bytes --]

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2013-08-28 19:25 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-27  5:37 [PATCH 00/29] Update driver to 8.06.00.08-k Saurav Kashyap
2013-08-27  5:37 ` [PATCH 01/29] qla2xxx: Print some variables to hexadecimal string via %*phN format Saurav Kashyap
2013-08-27  5:37 ` [PATCH 02/29] qla2xxx: Add support for ISP8044 Saurav Kashyap
2013-08-28  7:15   ` James Bottomley
2013-08-28 13:33     ` Saurav Kashyap
2013-08-27  5:37 ` [PATCH 03/29] qla2xxx: Fix incorrect test after list_for_each_entry() exits Saurav Kashyap
2013-08-27  5:37 ` [PATCH 04/29] qla2xxx: Correct multiqueue offset calculations Saurav Kashyap
2013-08-27  5:37 ` [PATCH 05/29] qla2xxx: Set factory reset recovery timeout to 10 min. for ISPFX00 Saurav Kashyap
2013-08-27  5:37 ` [PATCH 06/29] qla2xxx: Perform warm reset every 2 minutes if firmware load fails " Saurav Kashyap
2013-08-27  5:37 ` [PATCH 07/29] qla2xxx: Add ISPFX00 specific bus reset routine Saurav Kashyap
2013-08-27  5:37 ` [PATCH 08/29] qla2xxx: Remove QL_DEBUG_LEVEL_17 defines from qla_nx.c Saurav Kashyap
2013-08-27  5:37 ` [PATCH 09/29] qla2xxx: Add setting of driver version string for vendor application Saurav Kashyap
2013-08-27  5:37 ` [PATCH 10/29] qla2xxx: Reconfigure thermal temperature Saurav Kashyap
2013-08-27  5:37 ` [PATCH 11/29] qla2xxx: Notify ISPFX00 firmware when driver is unloaded or system is shut down Saurav Kashyap
2013-08-27  5:37 ` [PATCH 12/29] qla2xxx: Add critical temperature handling for ISPFX00 Saurav Kashyap
2013-08-27  5:37 ` [PATCH 13/29] qla2xxx: Make log message that prints when a completion status requires a port down more readable Saurav Kashyap
2013-08-27  5:37 ` [PATCH 14/29] qla2xxx: Add missing FCP statistics to sysfs interface Saurav Kashyap
2013-08-27  5:37 ` [PATCH 15/29] qla2xxx: Add changes to support extended IOs for ISPFX00 Saurav Kashyap
2013-08-27  5:37 ` [PATCH 16/29] qla2xxx: Add changes in initialization for ISPFX00 cards with BIOS Saurav Kashyap
2013-08-27  5:37 ` [PATCH 17/29] qla2xxx: Send all AENs for ISPFx00 to above layers Saurav Kashyap
2013-08-27  5:37 ` [PATCH 18/29] qla2xxx: Remove handling of Shutdown Requested AEN from qlafx00_process_aen() Saurav Kashyap
2013-08-27  5:37 ` [PATCH 19/29] qla2xxx: Correct Interrupt Register offset for ISPFX00 Saurav Kashyap
2013-08-27  5:37 ` [PATCH 20/29] qla2xxx: QLAFX00 make over temperature AEN handling informational, add log for normal temperature AEN Saurav Kashyap
2013-08-27  5:37 ` [PATCH 21/29] qla2xxx: Set default critical temperature value in cases when ISPFX00 firmware doesn't provide it Saurav Kashyap
2013-08-27  5:37 ` [PATCH 22/29] qla2xxx: Add loopback IDC-TIME-EXTEND aen handling support Saurav Kashyap
2013-08-27  5:37 ` [PATCH 23/29] qla2xxx: Select link initialization option bits from current operating mode Saurav Kashyap
2013-08-27  5:37 ` [PATCH 24/29] qla2xxx: Move queue depth ramp down message to i/o debug level Saurav Kashyap
2013-08-27  5:37 ` [PATCH 25/29] qla2xxx: Add a new interface to update versions Saurav Kashyap
2013-08-27  5:37 ` [PATCH 26/29] qla2xxx: Correctly print out/in mailbox registers Saurav Kashyap
2013-08-27  5:37 ` [PATCH 27/29] qla2xxx: Correction to message ids Saurav Kashyap
2013-08-27  5:37 ` [PATCH 28/29] qla2xxx: print MAC via %pMR Saurav Kashyap
2013-08-27  5:37 ` [PATCH 29/29] qla2xxx: Update the driver version to 8.06.00.08-k Saurav Kashyap
2013-08-28  3:24 ` [PATCH 00/29] Update driver " James Bottomley
2013-08-28  4:31   ` Saurav Kashyap

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.