changeset 11980:1d26bfcee070

6916195 Update Thebe to firmware 1.09.02 6929376 Add ila version info to sasinfo command and firmware update messages 6936954 ITNT should be set to 2 seconds
author David Hollister <David.Hollister@Sun.COM>
date Tue, 23 Mar 2010 13:05:23 -0600
parents e44013b33d33
children c44abfd092db
files usr/src/cmd/mdb/common/modules/pmcs/pmcs.c usr/src/uts/common/io/scsi/adapters/pmcs/firmware.bin usr/src/uts/common/io/scsi/adapters/pmcs/ila.bin usr/src/uts/common/io/scsi/adapters/pmcs/pmcs8001fw.version usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_fwlog.c usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_nvram.c usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs.h usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_param.h usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_reg.h
diffstat 11 files changed, 172 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c	Tue Mar 23 14:38:56 2010 -0400
+++ b/usr/src/cmd/mdb/common/modules/pmcs/pmcs.c	Tue Mar 23 13:05:23 2010 -0600
@@ -533,6 +533,8 @@
 	mdb_printf("Firmware version: %x.%x.%x (%s)\n",
 	    PMCS_FW_MAJOR(mp), PMCS_FW_MINOR(mp), PMCS_FW_MICRO(mp),
 	    fwsupport);
+	mdb_printf("ILA version:      %08x\n", m.ila_ver);
+	mdb_printf("Active f/w img:   %c\n", (m.fw_active_img) ? 'A' : 'B');
 
 	mdb_printf("Number of PHYs:   %d\n", m.nphy);
 	mdb_printf("Maximum commands: %d\n", m.max_cmd);
@@ -543,6 +545,15 @@
 	} else {
 		mdb_printf("Firmware logging: Enabled (%d)\n", m.fwlog);
 	}
+	if (m.fwlog_file == 0) {
+		mdb_printf("Firmware logfile: Not configured\n");
+	} else {
+		mdb_printf("Firmware logfile: Configured\n");
+		mdb_inc_indent(2);
+		mdb_printf("AAP1 log file:  %s\n", m.fwlogfile_aap1);
+		mdb_printf("IOP logfile:    %s\n", m.fwlogfile_iop);
+		mdb_dec_indent(2);
+	}
 }
 
 static void
Binary file usr/src/uts/common/io/scsi/adapters/pmcs/firmware.bin has changed
Binary file usr/src/uts/common/io/scsi/adapters/pmcs/ila.bin has changed
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs8001fw.version	Tue Mar 23 14:38:56 2010 -0400
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs8001fw.version	Tue Mar 23 13:05:23 2010 -0600
@@ -17,8 +17,8 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-PMCS_FW_VERSION=0x01080335
-PMCS_FW_VERSION_STRING="1.8.03 Special"
+PMCS_FW_VERSION=0x01090200
+PMCS_FW_VERSION_STRING="1.9.02 Released"
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_fwlog.c	Tue Mar 23 14:38:56 2010 -0400
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_fwlog.c	Tue Mar 23 13:05:23 2010 -0600
@@ -684,30 +684,31 @@
 	n += snprintf(&buf[n], (size_left - n), "\nDump GSM configuration "
 	    "registers: \n -----------------\n");
 	n += snprintf(&buf[n], (size_left - n), "RB6 Access Register = "
-	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, RB6_ACCESS));
+	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, RB6_ACCESS));
 	n += snprintf(&buf[n], (size_left - n), "CFG and RST = 0x%08x\n",
-	    pmcs_rd_gsm_reg(pwp, GSM_CFG_AND_RESET));
+	    pmcs_rd_gsm_reg(pwp, 0, GSM_CFG_AND_RESET));
 	n += snprintf(&buf[n], (size_left - n), "RAM ECC ERR INDICATOR= "
-	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, RAM_ECC_DOUBLE_ERROR_INDICATOR));
+	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, 0,
+	    RAM_ECC_DOUBLE_ERROR_INDICATOR));
 	n += snprintf(&buf[n], (size_left - n), "READ ADR PARITY CHK EN = "
-	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, READ_ADR_PARITY_CHK_EN));
+	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, READ_ADR_PARITY_CHK_EN));
 	n += snprintf(&buf[n], (size_left - n), "WRITE ADR PARITY CHK EN = "
-	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, WRITE_ADR_PARITY_CHK_EN));
+	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, WRITE_ADR_PARITY_CHK_EN));
 	n += snprintf(&buf[n], (size_left - n), "WRITE DATA PARITY CHK EN= "
-	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, WRITE_DATA_PARITY_CHK_EN));
+	    "0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, WRITE_DATA_PARITY_CHK_EN));
 	n += snprintf(&buf[n], (size_left - n),
 	    "READ ADR PARITY ERROR INDICATOR = 0x%08x\n",
-	    pmcs_rd_gsm_reg(pwp, READ_ADR_PARITY_ERROR_INDICATOR));
+	    pmcs_rd_gsm_reg(pwp, 0, READ_ADR_PARITY_ERROR_INDICATOR));
 	n += snprintf(&buf[n], (size_left - n),
 	    "WRITE ADR PARITY ERROR INDICATOR = 0x%08x\n",
-	    pmcs_rd_gsm_reg(pwp, WRITE_ADR_PARITY_ERROR_INDICATOR));
+	    pmcs_rd_gsm_reg(pwp, 0, WRITE_ADR_PARITY_ERROR_INDICATOR));
 	n += snprintf(&buf[n], (size_left - n),
 	    "WRITE DATA PARITY ERROR INDICATOR = 0x%08x\n",
-	    pmcs_rd_gsm_reg(pwp, WRITE_DATA_PARITY_ERROR_INDICATOR));
+	    pmcs_rd_gsm_reg(pwp, 0, WRITE_DATA_PARITY_ERROR_INDICATOR));
 	n += snprintf(&buf[n], (size_left - n), "NMI Enable VPE0 IOP Register"
-	    " = 0x%08x\n", pmcs_rd_gsm_reg(pwp, NMI_EN_VPE0_IOP));
+	    " = 0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, NMI_EN_VPE0_IOP));
 	n += snprintf(&buf[n], (size_left - n), "NMI Enable VPE0 AAP1 Register"
-	    " = 0x%08x\n", pmcs_rd_gsm_reg(pwp, NMI_EN_VPE0_AAP1));
+	    " = 0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, NMI_EN_VPE0_AAP1));
 	n += snprintf(&buf[n], (size_left - n), "-----------------\n"
 	    "Dump GSM configuration registers end \n");
 	return (n);
@@ -889,7 +890,7 @@
 		if (nums == 0) {
 			n += snprintf(&buf[n], (size_left - n),
 			    "[%04X]: %08X\n", gsm_spregs[i].offset_start,
-			    pmcs_rd_gsm_reg(pwp, gsm_addr));
+			    pmcs_rd_gsm_reg(pwp, 0, gsm_addr));
 		} else if (nums > 0) {
 			n += snprintf(&buf[n], (size_left - n),
 			    "\n[%04X] - [%04X]: \n", gsm_spregs[i].offset_start,
@@ -900,7 +901,7 @@
 				addr = gsm_addr + j * 4;
 				n += snprintf(&buf[n], (size_left - n),
 				    "[%04X]: %08X\n", addr & GSM_BASE_MASK,
-				    pmcs_rd_gsm_reg(pwp, addr));
+				    pmcs_rd_gsm_reg(pwp, 0, addr));
 				j++;
 				nums -= 4;
 			}
@@ -1089,11 +1090,13 @@
 			addr = hsst_state[i+8].offset_start +
 			    hsst_state[i+8].shift_addr;
 			n += snprintf(&buf[n], (size_left - n),
-			    "[%08X]: %08X\t", addr, pmcs_rd_gsm_reg(pwp, addr));
+			    "[%08X]: %08X\t", addr, pmcs_rd_gsm_reg(pwp, 0,
+			    addr));
 			addr = hsst_state[i+16].offset_start +
 			    hsst_state[i+16].shift_addr;
 			n += snprintf(&buf[n], (size_left - n),
-			    "[%08X]: %08X\n", addr, pmcs_rd_gsm_reg(pwp, addr));
+			    "[%08X]: %08X\n", addr, pmcs_rd_gsm_reg(pwp, 0,
+			    addr));
 		}
 
 	}
@@ -1118,11 +1121,11 @@
 			    sspa_state[i].desc ? sspa_state[i].desc : "NULL");
 		}
 		addr = sspa_state[i].offset_start + sspa_state[i].shift_addr;
-		rv = pmcs_rd_gsm_reg(pwp, addr);
+		rv = pmcs_rd_gsm_reg(pwp, 0, addr);
 		rv |= PMCS_SSPA_CONTROL_REGISTER_BIT27;
 		pmcs_wr_gsm_reg(pwp, addr, rv);
 		n += snprintf(&buf[n], (size_left - n), "[%08X]: %08X \n",
-		    addr, pmcs_rd_gsm_reg(pwp, addr));
+		    addr, pmcs_rd_gsm_reg(pwp, 0, addr));
 
 	}
 	return (n);
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_nvram.c	Tue Mar 23 14:38:56 2010 -0400
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_nvram.c	Tue Mar 23 13:05:23 2010 -0600
@@ -47,13 +47,15 @@
 pmcs_firmware_update(pmcs_hw_t *pwp)
 {
 	ddi_modhandle_t modhp;
-	char buf[64];
+	char buf[64], *bufp;
 	int errno;
 	uint8_t *cstart, *cend;		/* Firmware image file */
 	uint8_t *istart, *iend; 	/* ila */
 	uint8_t *sstart, *send;		/* SPCBoot */
 	uint32_t *fwvp;
 	int defret = 0;
+	long fw_version, ila_version;
+	uint8_t *fw_verp, *ila_verp;
 
 	/*
 	 * If updating is disabled, we're done.
@@ -74,10 +76,6 @@
 
 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
 		    "Firmware version matches, but still forcing update");
-	} else {
-		pmcs_prt(pwp, PMCS_PRT_WARN, NULL, NULL,
-		    "Upgrading firmware on card from 0x%x to 0x%x",
-		    pwp->fw, PMCS_FIRMWARE_VERSION);
 	}
 
 	modhp = ddi_modopen(PMCS_FIRMWARE_FILENAME, KRTLD_MODE_FIRST, &errno);
@@ -176,6 +174,32 @@
 	}
 
 	/*
+	 * Get the ILA and firmware versions from the modules themselves
+	 */
+	ila_verp = iend - PMCS_ILA_VER_OFFSET;
+	(void) ddi_strtol((const char *)ila_verp, &bufp, 16, &ila_version);
+	fw_verp = cend - PMCS_FW_VER_OFFSET;
+	(void) ddi_strtol((const char *)fw_verp, &bufp, 16, &fw_version);
+
+	/*
+	 * If force update is not set, verify that what we're loading is
+	 * what we expect.
+	 */
+	if (pwp->fw_force_update == 0) {
+		if (fw_version != PMCS_FIRMWARE_VERSION) {
+			pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL,
+			    "Expected fw version 0x%x, not 0x%lx: not "
+			    "updating", PMCS_FIRMWARE_VERSION, fw_version);
+			(void) ddi_modclose(modhp);
+			return (defret);
+		}
+	}
+
+	pmcs_prt(pwp, PMCS_PRT_WARN, NULL, NULL,
+	    "Upgrading firmware on card from 0x%x to 0x%lx (ILA version 0x%lx)",
+	    pwp->fw, fw_version, ila_version);
+
+	/*
 	 * The SPCBoot image must be updated first, and this is written to
 	 * SEEPROM, not flash.
 	 */
--- a/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c	Tue Mar 23 14:38:56 2010 -0400
+++ b/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_subr.c	Tue Mar 23 13:05:23 2010 -0600
@@ -71,6 +71,7 @@
 static boolean_t pmcs_tgtmap_deactivate_cb(void *, char *,
     scsi_tgtmap_tgt_type_t, void *, scsi_tgtmap_deact_rsn_t);
 static void pmcs_add_dead_phys(pmcs_hw_t *, pmcs_phy_t *);
+static void pmcs_get_fw_version(pmcs_hw_t *);
 
 /*
  * Often used strings
@@ -168,7 +169,7 @@
 	pwp->mpi_oqc_offset =
 	    pwp->mpi_offset + pmcs_rd_mpi_tbl(pwp, PMCS_MPI_OQCTO);
 
-	pwp->fw = pmcs_rd_mpi_tbl(pwp, PMCS_MPI_FW);
+	pmcs_get_fw_version(pwp);
 
 	pwp->max_cmd = pmcs_rd_mpi_tbl(pwp, PMCS_MPI_MOIO);
 	pwp->max_dev = pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO0) >> 16;
@@ -1492,7 +1493,7 @@
 	/*
 	 * Step 3
 	 */
-	gsm = pmcs_rd_gsm_reg(pwp, GSM_CFG_AND_RESET);
+	gsm = pmcs_rd_gsm_reg(pwp, 0, GSM_CFG_AND_RESET);
 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "GSM %08x -> %08x", gsm,
 	    gsm & ~PMCS_SOFT_RESET_BITS);
 	pmcs_wr_gsm_reg(pwp, GSM_CFG_AND_RESET, gsm & ~PMCS_SOFT_RESET_BITS);
@@ -1500,15 +1501,15 @@
 	/*
 	 * Step 4
 	 */
-	rapchk = pmcs_rd_gsm_reg(pwp, READ_ADR_PARITY_CHK_EN);
+	rapchk = pmcs_rd_gsm_reg(pwp, 0, READ_ADR_PARITY_CHK_EN);
 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "READ_ADR_PARITY_CHK_EN "
 	    "%08x -> %08x", rapchk, 0);
 	pmcs_wr_gsm_reg(pwp, READ_ADR_PARITY_CHK_EN, 0);
-	wapchk = pmcs_rd_gsm_reg(pwp, WRITE_ADR_PARITY_CHK_EN);
+	wapchk = pmcs_rd_gsm_reg(pwp, 0, WRITE_ADR_PARITY_CHK_EN);
 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "WRITE_ADR_PARITY_CHK_EN "
 	    "%08x -> %08x", wapchk, 0);
 	pmcs_wr_gsm_reg(pwp, WRITE_ADR_PARITY_CHK_EN, 0);
-	wdpchk = pmcs_rd_gsm_reg(pwp, WRITE_DATA_PARITY_CHK_EN);
+	wdpchk = pmcs_rd_gsm_reg(pwp, 0, WRITE_DATA_PARITY_CHK_EN);
 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "WRITE_DATA_PARITY_CHK_EN "
 	    "%08x -> %08x", wdpchk, 0);
 	pmcs_wr_gsm_reg(pwp, WRITE_DATA_PARITY_CHK_EN, 0);
@@ -1521,7 +1522,7 @@
 	/*
 	 * Step 5.5 (Temporary workaround for 1.07.xx Beta)
 	 */
-	tsmode = pmcs_rd_gsm_reg(pwp, PMCS_GPIO_TRISTATE_MODE_ADDR);
+	tsmode = pmcs_rd_gsm_reg(pwp, 0, PMCS_GPIO_TRISTATE_MODE_ADDR);
 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "GPIO TSMODE %08x -> %08x",
 	    tsmode, tsmode & ~(PMCS_GPIO_TSMODE_BIT0|PMCS_GPIO_TSMODE_BIT1));
 	pmcs_wr_gsm_reg(pwp, PMCS_GPIO_TRISTATE_MODE_ADDR,
@@ -1567,7 +1568,7 @@
 	/*
 	 * Step 11
 	 */
-	gsm = pmcs_rd_gsm_reg(pwp, GSM_CFG_AND_RESET);
+	gsm = pmcs_rd_gsm_reg(pwp, 0, GSM_CFG_AND_RESET);
 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "GSM %08x -> %08x", gsm,
 	    gsm | PMCS_SOFT_RESET_BITS);
 	pmcs_wr_gsm_reg(pwp, GSM_CFG_AND_RESET, gsm | PMCS_SOFT_RESET_BITS);
@@ -1577,17 +1578,17 @@
 	 * Step 12
 	 */
 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "READ_ADR_PARITY_CHK_EN "
-	    "%08x -> %08x", pmcs_rd_gsm_reg(pwp, READ_ADR_PARITY_CHK_EN),
+	    "%08x -> %08x", pmcs_rd_gsm_reg(pwp, 0, READ_ADR_PARITY_CHK_EN),
 	    rapchk);
 	pmcs_wr_gsm_reg(pwp, READ_ADR_PARITY_CHK_EN, rapchk);
 	drv_usecwait(10);
 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "WRITE_ADR_PARITY_CHK_EN "
-	    "%08x -> %08x", pmcs_rd_gsm_reg(pwp, WRITE_ADR_PARITY_CHK_EN),
+	    "%08x -> %08x", pmcs_rd_gsm_reg(pwp, 0, WRITE_ADR_PARITY_CHK_EN),
 	    wapchk);
 	pmcs_wr_gsm_reg(pwp, WRITE_ADR_PARITY_CHK_EN, wapchk);
 	drv_usecwait(10);
 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "WRITE_DATA_PARITY_CHK_EN "
-	    "%08x -> %08x", pmcs_rd_gsm_reg(pwp, WRITE_DATA_PARITY_CHK_EN),
+	    "%08x -> %08x", pmcs_rd_gsm_reg(pwp, 0, WRITE_DATA_PARITY_CHK_EN),
 	    wapchk);
 	pmcs_wr_gsm_reg(pwp, WRITE_DATA_PARITY_CHK_EN, wdpchk);
 	drv_usecwait(10);
@@ -5590,9 +5591,9 @@
 		break;
 	}
 	pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL,
-	    "Chip Revision: %c; F/W Revision %x.%x.%x %s", 'A' + pwp->chiprev,
-	    PMCS_FW_MAJOR(pwp), PMCS_FW_MINOR(pwp), PMCS_FW_MICRO(pwp),
-	    fwsupport);
+	    "Chip Revision: %c; F/W Revision %x.%x.%x %s (ILA rev %08x)",
+	    'A' + pwp->chiprev, PMCS_FW_MAJOR(pwp), PMCS_FW_MINOR(pwp),
+	    PMCS_FW_MICRO(pwp), fwsupport, pwp->ila_ver);
 }
 
 void
@@ -6490,9 +6491,9 @@
 }
 
 uint32_t
-pmcs_rd_gsm_reg(pmcs_hw_t *pwp, uint32_t off)
-{
-	uint32_t rv, newaxil, oldaxil;
+pmcs_rd_gsm_reg(pmcs_hw_t *pwp, uint8_t hi, uint32_t off)
+{
+	uint32_t rv, newaxil, oldaxil, oldaxih;
 
 	newaxil = off & ~GSM_BASE_MASK;
 	off &= GSM_BASE_MASK;
@@ -6507,7 +6508,29 @@
 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
 		    "AXIL register update failed");
 	}
+	if (hi) {
+		oldaxih = ddi_get32(pwp->top_acc_handle,
+		    &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2]);
+		ddi_put32(pwp->top_acc_handle,
+		    &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2], hi);
+		drv_usecwait(10);
+		if (ddi_get32(pwp->top_acc_handle,
+		    &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2]) != hi) {
+			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
+			    "AXIH register update failed");
+		}
+	}
 	rv = ddi_get32(pwp->gsm_acc_handle, &pwp->gsm_regs[off >> 2]);
+	if (hi) {
+		ddi_put32(pwp->top_acc_handle,
+		    &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2], oldaxih);
+		drv_usecwait(10);
+		if (ddi_get32(pwp->top_acc_handle,
+		    &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2]) != oldaxih) {
+			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
+			    "AXIH register restore failed");
+		}
+	}
 	ddi_put32(pwp->top_acc_handle,
 	    &pwp->top_regs[PMCS_AXI_TRANS >> 2], oldaxil);
 	drv_usecwait(10);
@@ -6558,7 +6581,7 @@
 	case PMCS_SPC_BOOT_STRAP:
 	case PMCS_SPC_DEVICE_ID:
 	case PMCS_DEVICE_REVISION:
-		off = pmcs_rd_gsm_reg(pwp, off);
+		off = pmcs_rd_gsm_reg(pwp, 0, off);
 		break;
 	default:
 		off = ddi_get32(pwp->top_acc_handle,
@@ -8265,3 +8288,52 @@
 	}
 	mutex_exit(&pwp->dead_phylist_lock);
 }
+
+static void
+pmcs_get_fw_version(pmcs_hw_t *pwp)
+{
+	uint32_t ila_len, ver_hi, ver_lo;
+	uint8_t ila_ver_string[9], img_flag;
+	char uc, *ucp = &uc;
+	unsigned long ila_ver;
+	uint64_t ver_hilo;
+
+	/* Firmware version is easy. */
+	pwp->fw = pmcs_rd_mpi_tbl(pwp, PMCS_MPI_FW);
+
+	/*
+	 * Get the image size (2nd to last dword)
+	 * NOTE: The GSM registers are mapped little-endian, but the data
+	 * on the flash is actually big-endian, so we need to swap these values
+	 * regardless of which platform we're on.
+	 */
+	ila_len = BSWAP_32(pmcs_rd_gsm_reg(pwp, GSM_FLASH_BASE_UPPER,
+	    GSM_FLASH_BASE + GSM_SM_BLKSZ - (2 << 2)));
+	if (ila_len > 65535) {
+		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
+		    "%s: Invalid ILA image size (0x%x)?", __func__, ila_len);
+		return;
+	}
+
+	/*
+	 * The numeric version is at ila_len - PMCS_ILA_VER_OFFSET
+	 */
+	ver_hi = BSWAP_32(pmcs_rd_gsm_reg(pwp, GSM_FLASH_BASE_UPPER,
+	    GSM_FLASH_BASE + ila_len - PMCS_ILA_VER_OFFSET));
+	ver_lo = BSWAP_32(pmcs_rd_gsm_reg(pwp, GSM_FLASH_BASE_UPPER,
+	    GSM_FLASH_BASE + ila_len - PMCS_ILA_VER_OFFSET + 4));
+	ver_hilo = BE_64(((uint64_t)ver_hi << 32) | ver_lo);
+	bcopy((const void *)&ver_hilo, &ila_ver_string[0], 8);
+	ila_ver_string[8] = '\0';
+
+	(void) ddi_strtoul((const char *)ila_ver_string, &ucp, 16, &ila_ver);
+	pwp->ila_ver = (int)(ila_ver & 0xffffffff);
+
+	img_flag = (BSWAP_32(pmcs_rd_gsm_reg(pwp, GSM_FLASH_BASE_UPPER,
+	    GSM_FLASH_IMG_FLAGS)) & 0xff000000) >> 24;
+	if (img_flag & PMCS_IMG_FLAG_A) {
+		pwp->fw_active_img = 1;
+	} else {
+		pwp->fw_active_img = 0;
+	}
+}
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs.h	Tue Mar 23 14:38:56 2010 -0400
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs.h	Tue Mar 23 13:05:23 2010 -0600
@@ -328,7 +328,8 @@
 		configuring		: 1,
 		ds_err_recovering	: 1,
 		quiesced		: 1,
-		fwlog_file		: 1;
+		fwlog_file		: 1,
+		fw_active_img		: 1;	/* 1='A', 0='B' */
 
 	/*
 	 * This HBA instance's iportmap and list of iport states.
@@ -522,6 +523,7 @@
 	 * Card information, some determined during MPI setup
 	 */
 	uint32_t	fw;		/* firmware version */
+	uint32_t	ila_ver;	/* ILA version */
 	uint8_t		max_iq;		/* maximum inbound queues this card */
 	uint8_t 	max_oq;		/* "" outbound "" */
 	uint8_t		nphy;		/* number of phys this card */
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h	Tue Mar 23 14:38:56 2010 -0400
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_iomb.h	Tue Mar 23 13:05:23 2010 -0600
@@ -196,7 +196,7 @@
 #define	PMCS_PHYID_SHIFT		4	/* level 0 registration only */
 #define	PMCS_DEVREG_TLR			0x1	/* Transport Layer Retry */
 
-#define	PMCS_DEVREG_IT_NEXUS_TIMEOUT	200U
+#define	PMCS_DEVREG_IT_NEXUS_TIMEOUT	2000U
 
 #define	PMCS_DEVREG_HA			0x2	/* Host Assigned upper 16 */
 						/* bits for device ID. */
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_param.h	Tue Mar 23 14:38:56 2010 -0400
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_param.h	Tue Mar 23 13:05:23 2010 -0600
@@ -143,6 +143,12 @@
 #define	PMCS_FIRMWARE_FILENAME		"misc/pmcs/pmcs8001fw"
 #define	PMCS_FIRMWARE_VERSION_NAME	"pmcs8001_fwversion"
 
+/*
+ * These are offsets from the end of the image
+ */
+#define	PMCS_FW_VER_OFFSET		528
+#define	PMCS_ILA_VER_OFFSET		528
+
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_reg.h	Tue Mar 23 14:38:56 2010 -0400
+++ b/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs_reg.h	Tue Mar 23 13:05:23 2010 -0600
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  *
  *
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -211,6 +211,13 @@
 #define	WRITE_ADR_PARITY_ERROR_INDICATOR	0x700060
 #define	WRITE_DATA_PARITY_ERROR_INDICATOR	0x700068
 
+#define	GSM_FLASH_BASE_UPPER			0x18
+#define	GSM_FLASH_BASE				0x40000000
+#define	GSM_FLASH_ILA				GSM_FLASH_BASE
+#define	GSM_FLASH_IMG_FLAGS			(GSM_FLASH_BASE + 0x400000)
+
+#define	PMCS_IMG_FLAG_A				0x01
+
 /*
  * GSM Share Memory, IO Status Table and Ring Buffer
  */
@@ -291,6 +298,7 @@
 #define	PMCS_ERROR_INT_ENABLE		0x3048
 #define	PMCS_ERROR_INT_STAT		0x304C
 #define	PMCS_AXI_TRANS			0x3258
+#define	PMCS_AXI_TRANS_UPPER		0x3268
 #define	PMCS_OBDB_AUTO_CLR		0x335C
 #define	PMCS_INT_COALESCING_TIMER	0x33C0
 #define	PMCS_INT_COALESCING_CONTROL	0x33C4
@@ -349,7 +357,7 @@
  * Register Access Inline Functions
  */
 uint32_t pmcs_rd_msgunit(pmcs_hw_t *, uint32_t);
-uint32_t pmcs_rd_gsm_reg(pmcs_hw_t *, uint32_t);
+uint32_t pmcs_rd_gsm_reg(pmcs_hw_t *, uint8_t, uint32_t);
 uint32_t pmcs_rd_topunit(pmcs_hw_t *, uint32_t);
 uint32_t pmcs_rd_mpi_tbl(pmcs_hw_t *, uint32_t);
 uint32_t pmcs_rd_gst_tbl(pmcs_hw_t *, uint32_t);