Skip to main content

Source code Changes To

on-src / usr / src / uts / common / io / fibre-channel / fca / emlxs / emlxs_download.c

From revision 13148 to 13149:

diff -r 7f829eb09eb7 -r b23a4dab3d50 usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c	Wed Aug 18 15:57:57 2010 -0600
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c	Wed Aug 18 15:52:48 2010 -0600
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2009 Emulex.  All rights reserved.
+ * Copyright 2010 Emulex.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -38,33 +38,27 @@
 			PIMAGE_HDR ImageHdr, caddr_t Buffer);
 
 static int32_t	emlxs_build_parms(caddr_t Buffer, PWAKE_UP_PARMS AbsWakeUpParms,
-			uint32_t BufferSize, PAIF_HDR AifHeader,
-			int32_t DwcFile);
+			uint32_t BufferSize, PAIF_HDR AifHeader);
 static uint32_t	emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer,
 			uint32_t Size, emlxs_fw_image_t *fw_image);
 static void	emlxs_format_dump(emlxs_hba_t *hba, MAILBOXQ *mbq,
 			uint32_t Type, uint32_t RegionId, uint32_t WordCnt,
 			uint32_t BaseAddr);
 static uint32_t	emlxs_start_abs_download(emlxs_hba_t *hba, PAIF_HDR AifHdr,
-			caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms,
-			uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize,
-			PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile);
+			caddr_t Buffer, uint32_t len,
+			PWAKE_UP_PARMS WakeUpParms);
 static uint32_t	emlxs_start_abs_download_2mb(emlxs_hba_t *hba, caddr_t buffer,
 			uint32_t len, uint32_t offline,
 			emlxs_fw_image_t *fw_image);
-static uint32_t	emlxs_proc_abs_2mb(emlxs_hba_t *hba, PAIF_HDR AifHdr,
+static uint32_t	emlxs_proc_abs_2mb(emlxs_hba_t *hba,
 			caddr_t EntireBuffer, uint32_t FileType,
-			uint32_t BWCflag, uint32_t extType);
+			uint32_t extType);
 static void	emlxs_format_load_area_cmd(MAILBOXQ *mbq, uint32_t Base,
 			uint32_t DlByteCount, uint32_t Function,
 			uint32_t Complete, uint32_t DataOffset, uint32_t AreaId,
 			uint8_t MbxCmd, uint32_t StepCmd);
 static uint32_t	emlxs_build_parms_2mb_bwc(emlxs_hba_t *hba, PAIF_HDR AifHdr,
 			uint32_t extType, PWAKE_UP_PARMS AbsWakeUpParms);
-static uint32_t	emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba, caddr_t Buffer,
-			uint32_t BufferSize, PAIF_HDR AifHeader,
-			PWAKE_UP_PARMS AbsWakeUpParms, uint32_t BWCflag,
-			uint32_t extType, uint32_t *numBootImage);
 static uint32_t	emlxs_update_exp_rom(emlxs_hba_t *hba,
 			PWAKE_UP_PARMS WakeUpParms);
 extern uint32_t	emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize,
@@ -72,7 +66,7 @@
 static void	emlxs_format_prog_flash(MAILBOXQ *mbq, uint32_t Base,
 			uint32_t DlByteCount, uint32_t Function,
 			uint32_t Complete, uint32_t BdeAddress,
-			uint32_t BdeSize, PROG_ID *ProgId);
+			uint32_t BdeSize, PROG_ID *ProgId, uint32_t keep);
 static void	emlxs_format_update_parms(MAILBOXQ *mbq,
 			PWAKE_UP_PARMS WakeUpParms);
 static void	emlxs_format_update_pci_cfg(emlxs_hba_t *hba, MAILBOXQ *mbq,
@@ -95,7 +89,7 @@
 			PWAKE_UP_PARMS WakeUpParms, PROG_ID *id);
 static uint32_t	emlxs_start_rel_download(emlxs_hba_t *hba, PIMAGE_HDR ImageHdr,
 			caddr_t Buffer, PWAKE_UP_PARMS WakeUpParms,
-			uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize);
+			uint32_t dwc_flag);
 static uint32_t	emlxs_read_load_list(emlxs_hba_t *hba, LOAD_LIST *LoadList);
 
 static uint32_t	emlxs_valid_cksum(uint32_t *StartAddr, uint32_t *EndAddr);
@@ -104,10 +98,6 @@
 
 static void	emlxs_dump_image_header(emlxs_hba_t *hba, PIMAGE_HDR image);
 
-static uint32_t	emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize);
-
-static uint32_t	emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer,
-			uint32_t BufferSize, PAIF_HDR AifHeader);
 static uint32_t	emlxs_type_check(uint32_t type);
 
 static uint32_t	emlxs_kern_check(emlxs_hba_t *hba, uint32_t version);
@@ -142,6 +132,16 @@
 static int32_t emlxs_sli4_fw_download(emlxs_hba_t *hba, caddr_t buffer,
 			uint32_t len, uint32_t offline);
 
+static uint32_t emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer,
+			emlxs_fw_image_t *fw_image);
+static uint32_t emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId);
+
+static void emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *image);
+
+static uint32_t emlxs_clean_flash(emlxs_hba_t *hba,
+			PWAKE_UP_PARMS OldWakeUpParms,
+			PWAKE_UP_PARMS NewWakeUpParms);
+
 /* ************************************************************************* */
 
 extern int32_t
@@ -154,11 +154,6 @@
 	AIF_HDR AifHdr;
 	uint32_t ImageType;
 	WAKE_UP_PARMS WakeUpParms;
-	WAKE_UP_PARMS AbsWakeUpParms;
-	uint32_t MaxRbusSramSize;
-	uint32_t MaxIbusSramSize;
-	int32_t AbsChangeParams = 0;
-	int32_t DwcFile = FALSE;
 	uint32_t rval = 0;
 	emlxs_fw_image_t fw_image;
 	uint32_t i;
@@ -209,6 +204,9 @@
 		goto done;
 	}
 
+	/* Verify image */
+	emlxs_verify_image(hba, &fw_image);
+
 	/* Get image type */
 	Uptr = (uint32_t *)buffer;
 	ImageType = *Uptr;
@@ -239,26 +237,16 @@
 
 	/* Pre-pegasus adapters only */
 
-	/* Check for absolute image */
-	else if (ImageType == NOP_IMAGE_TYPE) {
+	/* Initialize headers */
+	if (ImageType == NOP_IMAGE_TYPE) {
 		bcopy(buffer, &AifHdr, sizeof (AIF_HDR));
 		bzero((void *)&ImageHdr, sizeof (IMAGE_HDR));
-
-		if (AifHdr.ImageBase && (AifHdr.ImageBase == 0x20000)) {
-			DwcFile = TRUE;
-		}
-
-		AbsChangeParams = emlxs_build_parms(buffer,
-		    &AbsWakeUpParms, len, &AifHdr, DwcFile);
-	} else {	/* (ImageType != NOP_IMAGE_TYPE) Relative image */
-
+	} else { /* PRG file */
 		bzero((void *)&AifHdr, sizeof (AIF_HDR));
 		bcopy(buffer, &ImageHdr, sizeof (IMAGE_HDR));
 	}
 
-	/*
-	 * Everything checks out, now to just do it
-	 */
+	/* Everything checks out, now to just do it */
 
 	if (offline) {
 		if (emlxs_offline(hba) != FC_SUCCESS) {
@@ -268,7 +256,6 @@
 			    "Unable to take adapter offline.");
 
 			rval = EMLXS_OFFLINE_FAILED;
-
 			goto SLI_DOWNLOAD_EXIT;
 		}
 
@@ -279,11 +266,12 @@
 			    "Unable to restart adapter.");
 
 			rval = EMLXS_OFFLINE_FAILED;
-
 			goto SLI_DOWNLOAD_EXIT;
 		}
 	}
 
+	/* Pre-pegasus adapters */
+
 	if (ImageHdr.Id.Type == SBUS_FCODE) {
 		/* Erase Flash */
 		if (emlxs_erase_fcode_flash(hba)) {
@@ -291,7 +279,6 @@
 			    "Unable to erase flash.");
 
 			rval = EMLXS_IMAGE_FAILED;
-
 			goto SLI_DOWNLOAD_EXIT;
 		}
 
@@ -301,62 +288,47 @@
 			    "Unable to write flash.");
 
 			rval = EMLXS_IMAGE_FAILED;
-
 			goto SLI_DOWNLOAD_EXIT;
 		}
 
-	} else {	/* !SBUS_FCODE */
-
-
-		if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) {
-			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
-			    "Unable to get parameters.");
+		goto SLI_DOWNLOAD_EXIT;
+	}
+
+	/* Pre-pegasus PCI adapters */
+
+	if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 1)) {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
+		    "Unable to get parameters.");
+
+		rval = EMLXS_IMAGE_FAILED;
+
+		goto SLI_DOWNLOAD_EXIT;
+	}
+
+	if (ImageType == NOP_IMAGE_TYPE) {
+		if (emlxs_start_abs_download(hba, &AifHdr,
+		    buffer, len, &WakeUpParms)) {
+			EMLXS_MSGF(EMLXS_CONTEXT,
+			    &emlxs_download_failed_msg,
+			    "Failed to program flash.");
 
 			rval = EMLXS_IMAGE_FAILED;
 
 			goto SLI_DOWNLOAD_EXIT;
 		}
 
-		if (emlxs_get_max_sram(hba, &MaxRbusSramSize,
-		    &MaxIbusSramSize)) {
-			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
-			    "Unable to get RAM size.");
+	} else { /* Relative PRG file */
+		if (emlxs_start_rel_download(hba, &ImageHdr, buffer,
+		    &WakeUpParms, 0)) {
+			EMLXS_MSGF(EMLXS_CONTEXT,
+			    &emlxs_download_failed_msg,
+			    "Failed to program flash.");
 
 			rval = EMLXS_IMAGE_FAILED;
 
 			goto SLI_DOWNLOAD_EXIT;
 		}
-
-		if (ImageType == NOP_IMAGE_TYPE) {
-			if (emlxs_start_abs_download(hba, &AifHdr, buffer,
-			    &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize,
-			    (AbsChangeParams) ? &AbsWakeUpParms : NULL,
-			    DwcFile)) {
-				EMLXS_MSGF(EMLXS_CONTEXT,
-				    &emlxs_download_failed_msg,
-				    "Failed to program flash.");
-
-				rval = EMLXS_IMAGE_FAILED;
-
-				goto SLI_DOWNLOAD_EXIT;
-			}
-
-		} else {
-
-			if (emlxs_start_rel_download(hba, &ImageHdr, buffer,
-			    &WakeUpParms, MaxRbusSramSize, MaxIbusSramSize)) {
-				EMLXS_MSGF(EMLXS_CONTEXT,
-				    &emlxs_download_failed_msg,
-				    "Failed to program flash.");
-
-				rval = EMLXS_IMAGE_FAILED;
-
-				goto SLI_DOWNLOAD_EXIT;
-			}
-		}
-
-	}	/* !SBUS_FCODE */
-
+	}
 
 SLI_DOWNLOAD_EXIT:
 
@@ -461,12 +433,13 @@
 			image_ptr  += count;
 		}
 
-		/* Set last two words of last payload with */
-		/* image size and block crc */
+		/* Set last three words of last payload with */
+		/* load address, image size and block crc */
 		if (flashrom->params.opcode == MGMT_FLASHROM_OPCODE_FLASH) {
-			wptr = (uint32_t *)&payload[(xfer_size - 8)];
-			wptr[0] = file->image_size;
-			wptr[1] = file->block_crc;
+			wptr = (uint32_t *)&payload[(xfer_size - 12)];
+			wptr[0] = file->load_address;
+			wptr[1] = file->image_size;
+			wptr[2] = file->block_crc;
 		}
 
 		/* Send write request */
@@ -1082,6 +1055,7 @@
 			file->image_offset = entry->offset;
 			file->block_size   = entry->pad_size;
 			file->block_crc    = entry->checksum;
+			file->load_address = entry->entry_point;
 		} else {
 			file->image_offset = entry->offset +
 			    sizeof (emlxs_sli4_ufi_header_t);
@@ -1097,6 +1071,10 @@
 					file->block_size = (k + 8) -
 					    file->image_offset;
 
+					/* Read load_address */
+					value = *(wptr - 2);
+					file->load_address = BE_SWAP32(value);
+
 					/* Read block_crc */
 					value = *wptr;
 					file->block_crc = BE_SWAP32(value);
@@ -1116,7 +1094,7 @@
 		}
 
 		/* Make sure image will fit in block specified */
-		if (file->image_size + 8 > file->block_size) {
+		if (file->image_size + 12 > file->block_size) {
 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
 			    "%s: Image too large for block. image=%x block=%x",
 			    file->label, file->image_size, file->block_size);
@@ -1134,6 +1112,7 @@
 			file2->image_size = file->image_size;
 			file2->block_size = file->block_size;
 			file2->block_crc = file->block_crc;
+			file2->load_address = file->load_address;
 
 			/* Save FCOE version info */
 			bptr = (uint8_t *)buffer + file->image_offset + 0x30;
@@ -1150,6 +1129,7 @@
 			file2->image_size = file->image_size;
 			file2->block_size = file->block_size;
 			file2->block_crc = file->block_crc;
+			file2->load_address = file->load_address;
 		}
 	}
 
@@ -1173,9 +1153,10 @@
 		}
 
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
-		    "%s: type=%x block=%x image=%x offset=%x crc=%x",
+		    "%s: type=%x block=%x image=%x offset=%x crc=%x load=%x",
 		    file->label, file->type, file->block_size,
-		    file->image_size, file->image_offset, file->block_crc);
+		    file->image_size, file->image_offset, file->block_crc,
+		    file->load_address);
 	}
 
 	return (0);
@@ -1660,13 +1641,11 @@
 emlxs_start_abs_download(emlxs_hba_t *hba,
     PAIF_HDR AifHdr,
     caddr_t Buffer,
-    PWAKE_UP_PARMS WakeUpParms,
-    uint32_t MaxRbusSramSize,
-    uint32_t MaxIbusSramSize, PWAKE_UP_PARMS AbsWakeUpParms, int32_t DwcFile)
+    uint32_t len,
+    PWAKE_UP_PARMS WakeUpParms)
 {
 	emlxs_port_t *port = &PPORT;
 	uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize;
-	IMAGE_HDR ImageHdr;
 	uint32_t *Src;
 	uint32_t *Dst;
 	caddr_t DataBuffer = NULL;
@@ -1677,8 +1656,10 @@
 	uint32_t DlToAddr = AifHdr->ImageBase;
 	uint32_t DlCount;
 	uint32_t i;
-
-	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+	WAKE_UP_PARMS AbsWakeUpParms;
+	int32_t AbsChangeParams;
+
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
 	    "Performing absolute download...");
 
 	if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT,
@@ -1701,16 +1682,20 @@
 
 	mb = (MAILBOX *)mbox;
 
+	AbsChangeParams = emlxs_build_parms(Buffer,
+	    &AbsWakeUpParms, len, AifHdr);
+
 	Buffer += sizeof (AIF_HDR);
 
-	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash...");
-
-	if (DwcFile) {
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg, "Erasing flash...");
+
+	if (AifHdr->ImageBase == 0x20000) {
+		/* DWC File */
 		emlxs_format_prog_flash(mbox, 0x20000, 0x50000, ERASE_FLASH, 0,
-		    0, 0, NULL);
+		    0, 0, NULL, 0);
 	} else {
 		emlxs_format_prog_flash(mbox, DlToAddr, DlByteCount,
-		    ERASE_FLASH, 0, 0, 0, NULL);
+		    ERASE_FLASH, 0, 0, 0, NULL, 0);
 	}
 
 	if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
@@ -1723,7 +1708,7 @@
 		goto EXIT_ABS_DOWNLOAD;
 	}
 
-	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
 	    "Programming flash...");
 
 	while (DlByteCount) {
@@ -1750,7 +1735,7 @@
 		    sizeof (MAILBOX)), (DlCount / sizeof (uint32_t)));
 
 		emlxs_format_prog_flash(mbox, DlToAddr, DlCount,
-		    PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL);
+		    PROGRAM_FLASH, (DlByteCount) ? 0 : 1, 0, DlCount, NULL, 0);
 
 		if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) !=
 		    MBX_SUCCESS) {
@@ -1779,31 +1764,12 @@
 	}
 #endif  /* FMA_SUPPORT */
 
-	bzero((caddr_t)&ImageHdr, sizeof (IMAGE_HDR));
-	ImageHdr.Id.Type = FUNC_FIRMWARE;
-
-	switch (MaxRbusSramSize) {
-	case REDUCED_RBUS_SRAM_CFG:
-		ImageHdr.Id.Id = REDUCED_SRAM_CFG_PROG_ID;
-		break;
-	case FULL_RBUS_SRAM_CFG:
-		ImageHdr.Id.Id = FULL_SRAM_CFG_PROG_ID;
-		break;
-	default:
-		ImageHdr.Id.Id = OTHER_SRAM_CFG_PROG_ID;
-		break;
-	}
-
 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Updating params...");
 
-	if (AbsWakeUpParms) {
+	if (AbsChangeParams) {
 		rval =
-		    emlxs_update_wakeup_parms(hba, AbsWakeUpParms,
+		    emlxs_update_wakeup_parms(hba, &AbsWakeUpParms,
 		    WakeUpParms);
-	} else {
-		rval =
-		    emlxs_update_boot_wakeup_parms(hba, WakeUpParms,
-		    &ImageHdr.Id, 1);
 	}
 
 EXIT_ABS_DOWNLOAD:
@@ -1827,16 +1793,20 @@
     uint32_t DlByteCount,
     uint32_t Function,
     uint32_t Complete,
-    uint32_t BdeAddress, uint32_t BdeSize, PROG_ID *ProgId)
+    uint32_t BdeAddress,
+    uint32_t BdeSize,
+    PROG_ID *ProgId,
+    uint32_t keep)
 {
 	MAILBOX *mb = (MAILBOX *)mbq;
 
 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
 
-	if (ProgId)
+	if (ProgId) {
 		mb->mbxCommand = MBX_DOWN_LOAD;
-	else
+	} else {
 		mb->mbxCommand = MBX_LOAD_SM;
+	}
 
 	mb->un.varLdSM.load_cmplt = Complete;
 	mb->un.varLdSM.method = DL_FROM_SLIM;
@@ -1844,6 +1814,7 @@
 	mb->un.varLdSM.erase_or_prog = Function;
 	mb->un.varLdSM.dl_to_adr = Base;
 	mb->un.varLdSM.dl_len = DlByteCount;
+	mb->un.varLdSM.keep = keep;
 
 	if (BdeSize) {
 		mb->un.varLdSM.un.dl_from_slim_offset = DL_FROM_SLIM_OFFSET;
@@ -1911,6 +1882,7 @@
 	MAILBOX *mb;
 	MAILBOXQ *mbox;
 	uint32_t rval = 0;
+	PROG_ID old_prog_id;
 
 	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
 	    KM_NOSLEEP)) == NULL) {
@@ -1928,6 +1900,7 @@
 		(void) emlxs_update_exp_rom(hba, WakeUpParms);
 	}
 
+	old_prog_id = WakeUpParms->u0.boot_bios_id;
 	WakeUpParms->u0.boot_bios_id = *prog_id;
 
 	emlxs_format_update_parms(mbox, WakeUpParms);
@@ -1937,6 +1910,7 @@
 		    "Unable to update boot wakeup parms: Mailbox cmd=%x "
 		    "status=%x", mb->mbxCommand, mb->mbxStatus);
 
+		WakeUpParms->u0.boot_bios_id = old_prog_id;
 		rval = 1;
 	}
 
@@ -1958,6 +1932,7 @@
 	uint32_t rval = 0;
 	MAILBOXQ *mbox;
 	MAILBOX *mb;
+	PROG_ID old_prog_id;
 
 	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
 	    KM_NOSLEEP)) == NULL) {
@@ -1967,8 +1942,12 @@
 		return (1);
 	}
 
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+	    "FF: Updating parms...");
+
 	mb = (MAILBOX *)mbox;
 
+	old_prog_id = WakeUpParms->prog_id;
 	WakeUpParms->prog_id = *prog_id;
 
 	emlxs_format_update_parms(mbox, WakeUpParms);
@@ -1978,6 +1957,7 @@
 		    "Unable to update wakeup parameters: Mailbox cmd=%x "
 		    "status=%x", mb->mbxCommand, mb->mbxStatus);
 
+		WakeUpParms->prog_id = old_prog_id;
 		rval = 1;
 	}
 
@@ -1998,6 +1978,7 @@
 	uint32_t rval = 0;
 	MAILBOXQ *mbox;
 	MAILBOX *mb;
+	PROG_ID old_prog_id;
 
 	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
 	    KM_NOSLEEP)) == NULL) {
@@ -2007,8 +1988,12 @@
 		return (1);
 	}
 
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+	    "SLI1: Updating parms...");
+
 	mb = (MAILBOX *)mbox;
 
+	old_prog_id = WakeUpParms->sli1_prog_id;
 	WakeUpParms->sli1_prog_id = *prog_id;
 
 	emlxs_format_update_parms(mbox, WakeUpParms);
@@ -2018,6 +2003,7 @@
 		    "Unable to update wakeup parameters. Mailbox cmd=%x "
 		    "status=%x", mb->mbxCommand, mb->mbxStatus);
 
+		WakeUpParms->sli1_prog_id = old_prog_id;
 		rval = 1;
 	}
 
@@ -2038,6 +2024,7 @@
 	uint32_t rval = 0;
 	MAILBOXQ *mbox;
 	MAILBOX *mb;
+	PROG_ID old_prog_id;
 
 	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
 	    KM_NOSLEEP)) == NULL) {
@@ -2047,8 +2034,12 @@
 		return (1);
 	}
 
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+	    "SLI2: Updating parms...");
+
 	mb = (MAILBOX *)mbox;
 
+	old_prog_id = WakeUpParms->sli2_prog_id;
 	WakeUpParms->sli2_prog_id = *prog_id;
 
 	emlxs_format_update_parms(mbox, WakeUpParms);
@@ -2058,6 +2049,7 @@
 		    "Unable to update wakeup parameters. Mailbox cmd=%x "
 		    "status=%x", mb->mbxCommand, mb->mbxStatus);
 
+		WakeUpParms->sli2_prog_id = old_prog_id;
 		rval = 1;
 	}
 
@@ -2078,6 +2070,7 @@
 	uint32_t rval = 0;
 	MAILBOXQ *mbox;
 	MAILBOX *mb;
+	PROG_ID old_prog_id;
 
 	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
 	    KM_NOSLEEP)) == NULL) {
@@ -2087,8 +2080,12 @@
 		return (1);
 	}
 
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+	    "SLI3: Updating parms...");
+
 	mb = (MAILBOX *)mbox;
 
+	old_prog_id = WakeUpParms->sli3_prog_id;
 	WakeUpParms->sli3_prog_id = *prog_id;
 
 	emlxs_format_update_parms(mbox, WakeUpParms);
@@ -2098,6 +2095,7 @@
 		    "Unable to update wakeup parameters. Mailbox cmd=%x "
 		    "status=%x", mb->mbxCommand, mb->mbxStatus);
 
+		WakeUpParms->sli3_prog_id = old_prog_id;
 		rval = 1;
 	}
 
@@ -2118,6 +2116,7 @@
 	uint32_t rval = 0;
 	MAILBOXQ *mbox;
 	MAILBOX *mb;
+	PROG_ID old_prog_id;
 
 	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
 	    KM_NOSLEEP)) == NULL) {
@@ -2127,8 +2126,12 @@
 		return (1);
 	}
 
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+	    "SLI4: Updating parms...");
+
 	mb = (MAILBOX *)mbox;
 
+	old_prog_id = WakeUpParms->sli4_prog_id;
 	WakeUpParms->sli4_prog_id = *prog_id;
 
 	emlxs_format_update_parms(mbox, WakeUpParms);
@@ -2138,6 +2141,7 @@
 		    "Unable to update wakeup parameters. Mailbox cmd=%x "
 		    "status=%x", mb->mbxCommand, mb->mbxStatus);
 
+		WakeUpParms->sli4_prog_id = old_prog_id;
 		rval = 1;
 	}
 
@@ -2150,13 +2154,184 @@
 } /* emlxs_update_sli4_wakeup_parms() */
 
 
+static uint32_t
+emlxs_clean_flash(emlxs_hba_t *hba,
+    PWAKE_UP_PARMS OldWakeUpParms, PWAKE_UP_PARMS NewWakeUpParms)
+{
+	emlxs_port_t *port = &PPORT;
+	PROG_ID load_list[MAX_LOAD_ENTRY];
+	PROG_ID *wakeup_list[MAX_LOAD_ENTRY];
+	uint32_t count;
+	uint32_t i;
+	uint32_t j;
+	uint32_t k = 0;
+	uint32_t *wptr;
+
+	if (!NewWakeUpParms) {
+		return (1);
+	}
+
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+	    "Cleaning flash...");
+
+	/* If old wakeup parameter list is available, */
+	/* then cleanup old entries */
+	if (OldWakeUpParms) {
+		if (bcmp(&OldWakeUpParms->prog_id, &NewWakeUpParms->prog_id,
+		    sizeof (PROG_ID))) {
+
+			wptr = (uint32_t *)&OldWakeUpParms->prog_id;
+			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+			    "OLD:      prog_id: 0x%08x 0x%08x  Removing.",
+			    wptr[0], wptr[1]);
+
+			(void) emlxs_delete_load_entry(hba,
+			    &OldWakeUpParms->prog_id);
+		}
+
+		if (bcmp(&OldWakeUpParms->u0.boot_bios_id,
+		    &NewWakeUpParms->u0.boot_bios_id, sizeof (PROG_ID))) {
+
+			wptr = (uint32_t *)&OldWakeUpParms->u0.boot_bios_id;
+			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+			    "OLD: boot_bios_id: 0x%08x 0x%08x  Removing.",
+			    wptr[0], wptr[1]);
+
+			(void) emlxs_delete_load_entry(hba,
+			    &OldWakeUpParms->u0.boot_bios_id);
+		}
+
+		if (bcmp(&OldWakeUpParms->sli1_prog_id,
+		    &NewWakeUpParms->sli1_prog_id, sizeof (PROG_ID))) {
+
+			wptr = (uint32_t *)&OldWakeUpParms->sli1_prog_id;
+			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+			    "OLD: sli1_prog_id: 0x%08x 0x%08x  Removing.",
+			    wptr[0], wptr[1]);
+
+			(void) emlxs_delete_load_entry(hba,
+			    &OldWakeUpParms->sli1_prog_id);
+		}
+
+		if (bcmp(&OldWakeUpParms->sli2_prog_id,
+		    &NewWakeUpParms->sli2_prog_id, sizeof (PROG_ID))) {
+
+			wptr = (uint32_t *)&OldWakeUpParms->sli2_prog_id;
+			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+			    "OLD: sli2_prog_id: 0x%08x 0x%08x  Removing.",
+			    wptr[0], wptr[1]);
+
+			(void) emlxs_delete_load_entry(hba,
+			    &OldWakeUpParms->sli2_prog_id);
+		}
+
+		if (bcmp(&OldWakeUpParms->sli3_prog_id,
+		    &NewWakeUpParms->sli3_prog_id, sizeof (PROG_ID))) {
+
+			wptr = (uint32_t *)&OldWakeUpParms->sli3_prog_id;
+			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+			    "OLD: sli3_prog_id: 0x%08x 0x%08x  Removing.",
+			    wptr[0], wptr[1]);
+
+			(void) emlxs_delete_load_entry(hba,
+			    &OldWakeUpParms->sli3_prog_id);
+		}
+
+		if (bcmp(&OldWakeUpParms->sli4_prog_id,
+		    &NewWakeUpParms->sli4_prog_id, sizeof (PROG_ID))) {
+
+			wptr = (uint32_t *)&OldWakeUpParms->sli4_prog_id;
+			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+			    "OLD: sli4_prog_id: 0x%08x 0x%08x  Removing.",
+			    wptr[0], wptr[1]);
+
+			(void) emlxs_delete_load_entry(hba,
+			    &OldWakeUpParms->sli4_prog_id);
+		}
+
+		return (0);
+	}
+
+	/* Otherwise use the current load list */
+	count = emlxs_get_load_list(hba, load_list);
+
+	if (!count) {
+		return (1);
+	}
+
+	/* Init the wakeup list */
+	wptr = (uint32_t *)&NewWakeUpParms->prog_id;
+	if (*wptr) {
+		wakeup_list[k++] = &NewWakeUpParms->prog_id;
+	}
+
+	wptr = (uint32_t *)&NewWakeUpParms->u0.boot_bios_id;
+	if (*wptr) {
+		wakeup_list[k++] = &NewWakeUpParms->u0.boot_bios_id;
+	}
+
+	wptr = (uint32_t *)&NewWakeUpParms->sli1_prog_id;
+	if (*wptr) {
+		wakeup_list[k++] = &NewWakeUpParms->sli1_prog_id;
+	}
+
+	wptr = (uint32_t *)&NewWakeUpParms->sli2_prog_id;
+	if (*wptr) {
+		wakeup_list[k++] = &NewWakeUpParms->sli2_prog_id;
+	}
+
+	wptr = (uint32_t *)&NewWakeUpParms->sli3_prog_id;
+	if (*wptr) {
+		wakeup_list[k++] = &NewWakeUpParms->sli3_prog_id;
+	}
+
+	wptr = (uint32_t *)&NewWakeUpParms->sli4_prog_id;
+	if (*wptr) {
+		wakeup_list[k++] = &NewWakeUpParms->sli4_prog_id;
+	}
+
+	if (k == 0) {
+		return (0);
+	}
+
+	/* Match load list to wakeup list */
+	for (i = 0; i < count; i++) {
+
+		wptr = (uint32_t *)&load_list[i];
+
+		for (j = 0; j < k; j++) {
+			if (bcmp((uint8_t *)wakeup_list[j],
+			    (uint8_t *)&load_list[i], sizeof (PROG_ID)) == 0) {
+				break;
+			}
+		}
+
+		/* No match */
+		if (j == k) {
+			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+			    "Load List[%d]: %08x %08x  Removing.",
+			    i, wptr[0], wptr[1]);
+
+			(void) emlxs_delete_load_entry(hba, &load_list[i]);
+		} else {
+			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+			    "Load List[%d]: %08x %08x  Preserving.",
+			    i, wptr[0], wptr[1]);
+		}
+	}
+
+	return (0);
+
+} /* emlxs_clean_flash() */
+
+
 /* ARGSUSED */
 static uint32_t
 emlxs_start_rel_download(emlxs_hba_t *hba,
     PIMAGE_HDR ImageHdr,
     caddr_t Buffer,
     PWAKE_UP_PARMS WakeUpParms,
-    uint32_t MaxRbusSramSize, uint32_t MaxIbusSramSize)
+    uint32_t dwc_flag)
 {
 	emlxs_port_t *port = &PPORT;
 	MAILBOXQ *mbox;
@@ -2164,21 +2339,23 @@
 	uint32_t *Src;
 	uint32_t *Dst;
 	caddr_t DataBuffer = NULL;
-	uint32_t rval = 1;
-	uint32_t DlByteCount = ImageHdr->BlockSize;
+	uint32_t rval = 0;
+	uint32_t DlByteCount;
 	uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT;
 	uint32_t DlCount;
 	uint32_t i;
-
-	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-	    "Performing relative download...");
+	uint32_t *wptr;
+
+	wptr = (uint32_t *)&ImageHdr->Id;
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
+	    "Relative download: %08x %08x", wptr[0], wptr[1]);
 
 	if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT,
 	    KM_NOSLEEP)) == NULL) {
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
 		    "Unable to allocate data buffer.");
 
-		return (rval);
+		return (1);
 	}
 
 	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
@@ -2188,60 +2365,31 @@
 
 		kmem_free(DataBuffer, DL_SLIM_SEG_BYTE_COUNT);
 
-		return (rval);
-	}
-
-	if (ImageHdr->Id.Type == FUNC_FIRMWARE) {
-		switch (MaxRbusSramSize) {
-		case REDUCED_RBUS_SRAM_CFG:
-			if (ImageHdr->Id.Id != REDUCED_SRAM_CFG_PROG_ID) {
-				EMLXS_MSGF(EMLXS_CONTEXT,
-				    &emlxs_image_bad_msg,
-				    "Invalid header id.");
-
-				return (1);
-			}
-			break;
-		case FULL_RBUS_SRAM_CFG:
-			if (ImageHdr->Id.Id != FULL_SRAM_CFG_PROG_ID) {
-				EMLXS_MSGF(EMLXS_CONTEXT,
-				    &emlxs_image_bad_msg,
-				    "Invalid header id.");
-
-				return (1);
-			}
-			break;
-		default:
-			if (ImageHdr->Id.Id != OTHER_SRAM_CFG_PROG_ID) {
-				EMLXS_MSGF(EMLXS_CONTEXT,
-				    &emlxs_image_bad_msg,
-				    "Invalid header id.");
-
-				return (1);
-			}
-			break;
-		}
+		return (1);
 	}
 
 	mb = (MAILBOX *)mbox;
 
+	DlByteCount = ImageHdr->BlockSize;
+
 	emlxs_format_prog_flash(mbox, 0, DlByteCount, ERASE_FLASH, 0, 0, 0,
-	    &ImageHdr->Id);
-
-	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg, "Erasing flash...");
-
-	if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
+	    &ImageHdr->Id, 0);
+
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
+	    "  Erasing flash...");
+
+	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0);
+
+	if (rval) {
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
 		    "Unable to erase flash. Mailbox cmd=%x status=%x",
 		    mb->mbxCommand, mb->mbxStatus);
 
-		rval = 1;
-
 		goto EXIT_REL_DOWNLOAD;
 	}
 
-	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-	    "Programming flash...");
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
+	    "  Programming flash...");
 
 	while (DlByteCount) {
 		if (DlByteCount > SegSize) {
@@ -2269,16 +2417,16 @@
 		    0,
 		    DlCount,
 		    PROGRAM_FLASH,
-		    (DlByteCount) ? 0 : 1, 0, DlCount, &ImageHdr->Id);
-
-		if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) !=
-		    MBX_SUCCESS) {
+		    (DlByteCount) ? 0 : 1,
+		    0, DlCount, &ImageHdr->Id, dwc_flag);
+
+		rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0);
+
+		if (rval) {
 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
 			    "Unable to program flash. Mailbox cmd=%x status=%x",
 			    mb->mbxCommand, mb->mbxStatus);
 
-			rval = 1;
-
 			goto EXIT_REL_DOWNLOAD;
 		}
 
@@ -2297,57 +2445,73 @@
 	}
 #endif  /* FMA_SUPPORT */
 
+	/* Update wakeup parameters */
 	switch (ImageHdr->Id.Type) {
 	case TEST_PROGRAM:
-		rval = 0;
 		break;
 
 	case FUNC_FIRMWARE:
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "FF: Updating parms...");
-		rval =
-		    emlxs_update_ff_wakeup_parms(hba, WakeUpParms,
-		    &ImageHdr->Id);
+		if (!dwc_flag) {
+			rval = emlxs_update_ff_wakeup_parms(hba, WakeUpParms,
+			    &ImageHdr->Id);
+		} else {
+			WakeUpParms->prog_id = ImageHdr->Id;
+		}
 		break;
 
 	case BOOT_BIOS:
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "BOOT: Updating parms...");
-		rval =
-		    emlxs_update_boot_wakeup_parms(hba, WakeUpParms,
-		    &ImageHdr->Id, 1);
+		if (!dwc_flag) {
+			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+			    "BOOT: Updating parms...");
+
+			rval = emlxs_update_boot_wakeup_parms(hba, WakeUpParms,
+			    &ImageHdr->Id, 1);
+		} else {
+			if (hba->wakeup_parms.u0.boot_bios_wd[0]) {
+				WakeUpParms->u0.boot_bios_id = ImageHdr->Id;
+			}
+
+			if (!(hba->model_info.chip &
+			    (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP))) {
+				WakeUpParms->u1.EROM_prog_id = ImageHdr->Id;
+			}
+		}
 		break;
 
 	case SLI1_OVERLAY:
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "SLI1: Updating parms...");
-		rval =
-		    emlxs_update_sli1_wakeup_parms(hba, WakeUpParms,
-		    &ImageHdr->Id);
+		if (!dwc_flag) {
+			rval = emlxs_update_sli1_wakeup_parms(hba, WakeUpParms,
+			    &ImageHdr->Id);
+		} else {
+			WakeUpParms->sli1_prog_id = ImageHdr->Id;
+		}
 		break;
 
 	case SLI2_OVERLAY:
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "SLI2: Updating parms...");
-		rval =
-		    emlxs_update_sli2_wakeup_parms(hba, WakeUpParms,
-		    &ImageHdr->Id);
+		if (!dwc_flag) {
+			rval = emlxs_update_sli2_wakeup_parms(hba, WakeUpParms,
+			    &ImageHdr->Id);
+		} else {
+			WakeUpParms->sli2_prog_id = ImageHdr->Id;
+		}
 		break;
 
 	case SLI3_OVERLAY:
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "SLI3: Updating parms...");
-		rval =
-		    emlxs_update_sli3_wakeup_parms(hba, WakeUpParms,
-		    &ImageHdr->Id);
+		if (!dwc_flag) {
+			rval = emlxs_update_sli3_wakeup_parms(hba, WakeUpParms,
+			    &ImageHdr->Id);
+		} else {
+			WakeUpParms->sli3_prog_id = ImageHdr->Id;
+		}
 		break;
 
 	case SLI4_OVERLAY:
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "SLI4: Updating parms...");
-		rval =
-		    emlxs_update_sli4_wakeup_parms(hba, WakeUpParms,
-		    &ImageHdr->Id);
+		if (!dwc_flag) {
+			rval = emlxs_update_sli4_wakeup_parms(hba, WakeUpParms,
+			    &ImageHdr->Id);
+		} else {
+			WakeUpParms->sli4_prog_id = ImageHdr->Id;
+		}
 		break;
 
 	default:
@@ -2371,6 +2535,74 @@
 } /* emlxs_start_rel_download() */
 
 
+static uint32_t
+emlxs_proc_rel_2mb(emlxs_hba_t *hba, caddr_t buffer, emlxs_fw_image_t *fw_image)
+{
+	emlxs_port_t *port = &PPORT;
+	uint32_t rval = 0;
+	WAKE_UP_PARMS RelWakeUpParms;
+	WAKE_UP_PARMS WakeUpParms;
+	uint32_t i;
+	IMAGE_HDR ImageHdr;
+	caddr_t bptr;
+	uint32_t flash_cleaned = 0;
+
+	if (emlxs_read_wakeup_parms(hba, &WakeUpParms, 0)) {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
+		    "Unable to get wakeup parameters.");
+
+		return (EMLXS_IMAGE_FAILED);
+	}
+
+download:
+
+	bcopy(&WakeUpParms, &RelWakeUpParms, sizeof (WAKE_UP_PARMS));
+
+	for (i = 0; i < MAX_PROG_TYPES; i++) {
+		if (!fw_image->prog[i].version) {
+			continue;
+		}
+
+		bptr = buffer + fw_image->prog[i].offset;
+
+		bcopy(bptr, &ImageHdr, sizeof (IMAGE_HDR));
+
+		rval = emlxs_start_rel_download(hba, &ImageHdr, bptr,
+		    &RelWakeUpParms, 1);
+
+		if (rval) {
+			EMLXS_MSGF(EMLXS_CONTEXT,
+			    &emlxs_download_failed_msg,
+			    "Failed to program flash.");
+
+			if ((rval == NO_FLASH_MEM_AVAIL) && !flash_cleaned) {
+				/* Cleanup using current load list */
+				(void) emlxs_clean_flash(hba, 0, &WakeUpParms);
+
+				flash_cleaned = 1;
+				goto download;
+			}
+
+			return (EMLXS_IMAGE_FAILED);
+		}
+	}
+
+	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_detail_msg,
+	    "Updating wakeup parameters.");
+
+	if (emlxs_update_wakeup_parms(hba, &RelWakeUpParms,
+	    &RelWakeUpParms)) {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
+		    "Unable to update parameters.");
+
+		return (EMLXS_IMAGE_FAILED);
+	}
+
+	return (0);
+
+} /* emlxs_proc_rel_2mb() */
+
+
 #define	FLASH_POLLING_BIT	0x80
 #define	FLASH_ERROR_BIT		0x20
 
@@ -2639,6 +2871,46 @@
 } /* emlxs_erase_fcode_flash() */
 
 
+static uint32_t
+emlxs_delete_load_entry(emlxs_hba_t *hba, PROG_ID *progId)
+{
+	emlxs_port_t *port = &PPORT;
+	MAILBOXQ *mbox = NULL;
+	MAILBOX *mb;
+	uint32_t rval = 0;
+
+	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
+	    KM_NOSLEEP)) == NULL) {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+		    "Unable to allocate mailbox buffer.");
+
+		return (1);
+	}
+
+	mb = (MAILBOX *)mbox;
+	mb->mbxCommand = MBX_DEL_LD_ENTRY;
+	mb->un.varDelLdEntry.list_req = FLASH_LOAD_LIST;
+	mb->un.varDelLdEntry.prog_id = *progId;
+
+	if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_WAIT, 0) != MBX_SUCCESS) {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
+		    "Unable to delete load entry: Mailbox cmd=%x status=%x",
+		    mb->mbxCommand, mb->mbxStatus);
+
+		rval = 1;
+	}
+
+done:
+
+	if (mbox) {
+		kmem_free(mbox, sizeof (MAILBOXQ));
+	}
+
+	return (rval);
+
+} /* emlxs_delete_load_entry() */
+
+
 extern uint32_t
 emlxs_get_load_list(emlxs_hba_t *hba, PROG_ID *load_list)
 {
@@ -2646,7 +2918,7 @@
 	LOAD_ENTRY *LoadEntry;
 	LOAD_LIST *LoadList = NULL;
 	uint32_t i;
-	uint32_t rval = 0;
+	uint32_t count = 0;
 
 	bzero(load_list, (sizeof (PROG_ID) * MAX_LOAD_ENTRY));
 
@@ -2655,12 +2927,10 @@
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_msg,
 		    "Unable to allocate LOADLIST buffer.");
 
-		rval = 1;
 		goto done;
 	}
 
 	if (emlxs_read_load_list(hba, LoadList)) {
-		rval = 1;
 		goto done;
 	}
 
@@ -2668,10 +2938,11 @@
 		LoadEntry = &LoadList->load_entry[i];
 		if ((LoadEntry->un.wd[0] != 0) &&
 		    (LoadEntry->un.wd[0] != 0xffffffff)) {
-			load_list[i] = LoadEntry->un.id;
 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
-			    "Load List[%d]: %08x %08x", i,
+			    "Load List[%d]: %08x %08x", count,
 			    LoadEntry->un.wd[0], LoadEntry->un.wd[1]);
+
+			load_list[count++] = LoadEntry->un.id;
 		}
 	}
 
@@ -2681,7 +2952,7 @@
 		kmem_free(LoadList, sizeof (LOAD_LIST));
 	}
 
-	return (rval);
+	return (count);
 
 } /* emlxs_get_load_list() */
 
@@ -2920,74 +3191,11 @@
 } /* emlxs_read_load_list() */
 
 
-static uint32_t
-emlxs_get_abs_image_type(caddr_t Buffer, uint32_t BufferSize)
-{
-	uint32_t Version;
-
-	if (BufferSize < (SLI_VERSION_LOC + 4))
-		return (0xffffffff);
-
-	Buffer += SLI_VERSION_LOC;
-	Version = *((uint32_t *)Buffer);
-
-	return (Version);
-
-} /* emlxs_get_abs_image_type() */
-
-
-static uint32_t
-emlxs_get_dwc_image_type(emlxs_hba_t *hba, caddr_t Buffer,
-    uint32_t BufferSize, PAIF_HDR AifHeader)
-{
-	emlxs_port_t *port = &PPORT;
-	IMAGE_HDR ImageHdr;
-	uint32_t NextImage;
-	uint32_t i;
-	uint8_t *Sptr;
-	uint8_t *Dptr;
-	uint32_t HwId = 0xffffffff;
-
-	NextImage = SLI_IMAGE_START - AifHeader->ImageBase;
-
-	while (BufferSize > NextImage) {
-		Sptr = (uint8_t *)&Buffer[NextImage];
-		Dptr = (uint8_t *)&ImageHdr;
-		for (i = 0; i < sizeof (IMAGE_HDR); i++) {
-			Dptr[i] = Sptr[i];
-		}
-
-		if (ImageHdr.BlockSize == 0xffffffff)
-			break;
-
-		switch (ImageHdr.Id.Type) {
-		case 6:
-		case 7:
-			if (HwId == 0xffffffff) {
-				HwId = ImageHdr.Id.Id;
-			}
-
-			if (HwId != ImageHdr.Id.Id) {
-				EMLXS_MSGF(EMLXS_CONTEXT,
-				    &emlxs_image_bad_msg,
-				    "Invalid hardware id. %x %x", HwId,
-				    ImageHdr.Id.Id);
-			}
-			break;
-		}
-
-		NextImage += ImageHdr.BlockSize;
-	}
-
-	return (HwId);
-
-} /* emlxs_get_dwc_image_type() */
-
 
 static int
 emlxs_build_parms(caddr_t Buffer,
     PWAKE_UP_PARMS AbsWakeUpParms,
-    uint32_t BufferSize, PAIF_HDR AifHeader, int32_t DwcFile)
+    uint32_t BufferSize, PAIF_HDR AifHeader)
 {
 	IMAGE_HDR ImageHdr;
 	uint32_t NextImage;
@@ -2998,7 +3206,8 @@
 
 	bzero((caddr_t)AbsWakeUpParms, sizeof (WAKE_UP_PARMS));
 
-	if (!DwcFile && ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) {
+	if ((AifHeader->ImageBase != 0x20000) &&
+	    ((AifHeader->RoSize + AifHeader->RwSize) <= 0x20000)) {
 		return (FALSE);
 	}
 
@@ -3257,6 +3466,164 @@
 } /* emlxs_validate_version() */
 
 
+static void
+emlxs_verify_image(emlxs_hba_t *hba, emlxs_fw_image_t *fw_image)
+{
+	emlxs_port_t *port = &PPORT;
+	emlxs_vpd_t *vpd = &VPD;
+	uint32_t i;
+	uint32_t count;
+
+	/* Check for AWC file */
+	if (fw_image->awc.version) {
+		if (fw_image->awc.version == vpd->postKernRev) {
+			fw_image->awc.version = 0;
+		}
+
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+		    "AWC file: KERN: old=%s  new=%s  %s.",
+		    vpd->postKernName,
+		    fw_image->awc.label,
+		    (fw_image->awc.version)? "Update":"Skip");
+	}
+
+	/* Check for BWC file */
+	if (fw_image->bwc.version) {
+		if (strcmp(vpd->fcode_version, fw_image->bwc.label) == 0) {
+			fw_image->bwc.version = 0;
+		}
+
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+		    "BWC file: BOOT: old=%s  new=%s  %s.",
+		    vpd->fcode_version,
+		    fw_image->bwc.label,
+		    (fw_image->bwc.version)? "Update":"Skip");
+	}
+
+	/* Check for DWC file */
+	if (fw_image->dwc.version) {
+		/* Check for program files */
+		count = 0;
+		for (i = 0; i < MAX_PROG_TYPES; i++) {
+			if (!fw_image->prog[i].version) {
+				continue;
+			}
+
+			/* Skip components that don't need updating */
+			switch (i) {
+			case TEST_PROGRAM:
+				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+				    "DWC file: TEST:             new=%s  "
+				    "Update.",
+				    fw_image->prog[i].label);
+				break;
+
+			case BOOT_BIOS:
+				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+				    "DWC file: BOOT:             new=%s  "
+				    "Update.",
+				    fw_image->prog[i].label);
+				break;
+
+			case FUNC_FIRMWARE:
+				if (vpd->opFwRev &&
+				    (fw_image->prog[i].version ==
+				    vpd->opFwRev)) {
+					fw_image->prog[i].version = 0;
+				}
+
+				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+				    "DWC file: STUB: old=%s  new=%s  %s.",
+				    vpd->opFwName,
+				    fw_image->prog[i].label,
+				    (fw_image->prog[i].version)?
+				    "Update":"Skip");
+				break;
+
+			case SLI1_OVERLAY:
+				if (vpd->sli1FwRev &&
+				    (fw_image->prog[i].version ==
+				    vpd->sli1FwRev)) {
+					fw_image->prog[i].version = 0;
+				}
+
+				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+				    "DWC file: SLI1: old=%s  new=%s  %s.",
+				    vpd->sli1FwName,
+				    fw_image->prog[i].label,
+				    (fw_image->prog[i].version)?
+				    "Update":"Skip");
+				break;
+
+			case SLI2_OVERLAY:
+				if (vpd->sli2FwRev &&
+				    (fw_image->prog[i].version ==
+				    vpd->sli2FwRev)) {
+					fw_image->prog[i].version = 0;
+				}
+
+				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+				    "DWC file: SLI2: old=%s  new=%s  %s.",
+				    vpd->sli2FwName,
+				    fw_image->prog[i].label,
+				    (fw_image->prog[i].version)?
+				    "Update":"Skip");
+				break;
+
+			case SLI3_OVERLAY:
+				if (vpd->sli3FwRev &&
+				    (fw_image->prog[i].version ==
+				    vpd->sli3FwRev)) {
+					fw_image->prog[i].version = 0;
+				}
+
+				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+				    "DWC file: SLI3: old=%s  new=%s  %s.",
+				    vpd->sli3FwName,
+				    fw_image->prog[i].label,
+				    (fw_image->prog[i].version)?
+				    "Update":"Skip");
+				break;
+
+			case SLI4_OVERLAY:
+				if (vpd->sli4FwRev &&
+				    (fw_image->prog[i].version ==
+				    vpd->sli4FwRev)) {
+					fw_image->prog[i].version = 0;
+				}
+
+				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+				    "DWC file: SLI4: old=%s  new=%s  %s.",
+				    vpd->sli4FwRev,
+				    fw_image->prog[i].label,
+				    (fw_image->prog[i].version)?
+				    "Update":"Skip");
+				break;
+
+			default:
+				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+				    "DWC file: type=%x version=%x label=%s  "
+				    "Update.",
+				    i,
+				    fw_image->prog[i].version,
+				    fw_image->prog[i].label);
+			}
+
+			if (fw_image->prog[i].version) {
+				count++;
+			}
+		}
+
+		if (!count) {
+			fw_image->dwc.version = 0;
+		}
+	}
+
+	return;
+
+} /* emlxs_verify_image() */
+
+
 static uint32_t
 emlxs_validate_image(emlxs_hba_t *hba, caddr_t Buffer, uint32_t Size,
     emlxs_fw_image_t *image)
@@ -3266,6 +3633,7 @@
 	AIF_HDR AifHdr;
 	IMAGE_HDR ImageHdr;
 	uint32_t NextImage;
+	uint32_t count;
 	uint32_t FileType;
 	uint32_t FileLen = 0;
 	uint32_t TotalLen = 0;
@@ -3379,6 +3747,7 @@
 				NextImage = sizeof (AIF_HDR) + 4;
 				BufferSize = AifHdr.RoSize + AifHdr.RwSize;
 
+				count = 0;
 				while (BufferSize > NextImage) {
 					bcopy(&bptr[NextImage], &ImageHdr,
 					    sizeof (IMAGE_HDR));
@@ -3416,10 +3785,19 @@
 						return (rval);
 					}
 
+					count++;
 					NextImage += ImageHdr.BlockSize;
 
 				}	/* while () */
 
+				if (count == 0) {
+					EMLXS_MSGF(EMLXS_CONTEXT,
+					    &emlxs_image_bad_msg,
+					    "DWC file has no PRG images.");
+
+					return (EMLXS_IMAGE_BAD);
+				}
+
 				break;
 			}
 
@@ -3520,7 +3898,9 @@
 
 			NextImage += ImageHdr.BlockSize;
 		}
-	} else {
+
+	} else { /* PRG File */
+
 		/* Precheck image size */
 		if (Size < sizeof (IMAGE_HDR)) {
 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_image_bad_msg,
@@ -3570,8 +3950,10 @@
 
 		/* Acquire the versions */
 		image->prog[type].version =
-		    (ImageHdr.Id.Type << 24) | (ImageHdr.Id.
-		    Id << 16) | (ImageHdr.Id.Ver << 8) | ImageHdr.Id.Rev;
+		    (ImageHdr.Id.Type << 24) |
+		    (ImageHdr.Id.Id << 16) |
+		    (ImageHdr.Id.Ver << 8) |
+		    ImageHdr.Id.Rev;
 
 		image->prog[type].revcomp = ImageHdr.Id.un.revcomp;
 
@@ -3584,23 +3966,19 @@
 
 	/*
 	 * This checks if a DragonFly (pre-V2 ASIC) SLI2
-	 * image file is greater than version 3.8
+	 * image file is < version 3.8
 	 */
 	if (FC_JEDEC_ID(vpd->biuRev) == DRAGONFLY_JEDEC_ID) {
-		if (image->prog[SLI2_OVERLAY].version != 0) {
-			ver = (image->prog[SLI2_OVERLAY].version &
-			    0x0000ff00) >> 8;
-
-			if ((((ver & 0xf0) == 0x30) &&
-			    ((ver & 0x0f) >= 0x08)) ||
-			    ((ver & 0xf0) > 0x30)) {
-				EMLXS_MSGF(EMLXS_CONTEXT,
-				    &emlxs_image_incompat_msg,
-				    "ASIC Check: Image requires DragonFly "
-				    "V2 ASIC");
-
-				return (EMLXS_IMAGE_INCOMPATIBLE);
-			}
+		ver = (image->prog[SLI2_OVERLAY].version &
+		    0x0000ff00) >> 8;
+
+		if (ver >= 0x38) {
+			EMLXS_MSGF(EMLXS_CONTEXT,
+			    &emlxs_image_incompat_msg,
+			    "ASIC Check: Image requires DragonFly "
+			    "V2 ASIC");
+
+			return (EMLXS_IMAGE_INCOMPATIBLE);
 		}
 	}
 
@@ -3752,63 +4130,14 @@
     uint32_t offline, emlxs_fw_image_t *fw_image)
 {
 	emlxs_port_t *port = &PPORT;
-	caddr_t AwcBuffer = NULL;
-	caddr_t BwcBuffer = NULL;
-	caddr_t DwcBuffer = NULL;
-	AIF_HDR *AwcAifHdr;
-	AIF_HDR *BwcAifHdr;
-	AIF_HDR *DwcAifHdr;
-	uint32_t BWCflag;
-	emlxs_vpd_t *vpd;
-	uint32_t i;
-	uint32_t count;
-	uint32_t extType = 0;
 	uint32_t rval = 0;
 
-	vpd = &VPD;
-
-	/* Check for AWC file */
-	if (fw_image->awc.version) {
-		AwcBuffer = buffer + fw_image->awc.offset;
-		AwcAifHdr = (AIF_HDR *)AwcBuffer;
-	}
-
-	/* Check for BWC file */
-	if (fw_image->bwc.version) {
-		extType = BWCext;
-		BwcBuffer = buffer + fw_image->bwc.offset;
-		BwcAifHdr = (AIF_HDR *)BwcBuffer;
-	}
-
-	/* Check for DWC file */
-	if (fw_image->dwc.version) {
-		extType = DWCext;
-		DwcBuffer = buffer + fw_image->dwc.offset;
-		DwcAifHdr = (AIF_HDR *)DwcBuffer;
-	}
-
-	/* Check for program files */
-	count = 0;
-	for (i = 0; i < MAX_PROG_TYPES; i++) {
-		if (fw_image->prog[i].version) {
-			count++;
-		}
-	}
-
-	if (count > 1) {
-		extType = ALLext;
-
-		if (fw_image->bwc.version) {
-			BWCflag = ALL_WITH_BWC;
-		} else {
-			BWCflag = ALL_WITHOUT_BWC;
-		}
-	} else {
-		BWCflag = NO_ALL;
-	}
-
 	/* If nothing to download then quit now */
-	if (!AwcBuffer && !DwcBuffer && !BwcBuffer) {
+	if (!fw_image->awc.version &&
+	    !fw_image->dwc.version &&
+	    !fw_image->bwc.version) {
+		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
+		    "Nothing new to update.  Exiting.");
 		return (0);
 	}
 
@@ -3825,65 +4154,33 @@
 		}
 	}
 
-	if (AwcBuffer) {
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "AWC file: KERN: old=%s  new=%s ", vpd->postKernName,
-		    fw_image->awc.label);
-
+	if (fw_image->awc.version) {
 		rval = emlxs_proc_abs_2mb(hba,
-		    AwcAifHdr, AwcBuffer, FILE_TYPE_AWC, BWCflag, extType);
+		    (buffer + fw_image->awc.offset),
+		    FILE_TYPE_AWC, 0);
 
 		if (rval) {
 			goto SLI_DOWNLOAD_2MB_EXIT;
 		}
 	}
 
-	if (DwcBuffer) {
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "DWC file: TEST:             new=%s ",
-		    fw_image->prog[TEST_PROGRAM].label);
-
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "DWC file: STUB: old=%s  new=%s ", vpd->opFwName,
-		    fw_image->prog[FUNC_FIRMWARE].label);
-
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "DWC file: SLI1: old=%s  new=%s ", vpd->sli1FwName,
-		    fw_image->prog[SLI1_OVERLAY].label);
-
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "DWC file: SLI2: old=%s  new=%s ", vpd->sli2FwName,
-		    fw_image->prog[SLI2_OVERLAY].label);
-
-		if (vpd->sli3FwRev || fw_image->prog[SLI3_OVERLAY].version) {
-			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-			    "DWC file: SLI3: old=%s  new=%s ",
-			    vpd->sli3FwName,
-			    fw_image->prog[SLI3_OVERLAY].label);
-		}
-
-		if (vpd->sli4FwRev || fw_image->prog[SLI4_OVERLAY].version) {
-			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-			    "DWC file: SLI4: old=%s  new=%s ",
-			    vpd->sli4FwName,
-			    fw_image->prog[SLI4_OVERLAY].label);
-		}
-
+	if (fw_image->bwc.version) {
 		rval = emlxs_proc_abs_2mb(hba,
-		    DwcAifHdr, DwcBuffer, FILE_TYPE_DWC, BWCflag, extType);
+		    (buffer + fw_image->bwc.offset),
+		    FILE_TYPE_BWC,
+		    (fw_image->dwc.version)? ALLext:BWCext);
 
 		if (rval) {
 			goto SLI_DOWNLOAD_2MB_EXIT;
 		}
 	}
 
-	if (BwcBuffer) {
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_msg,
-		    "BWC file: BOOT: old=%s  new=%s ", vpd->fcode_version,
-		    fw_image->bwc.label);
-
-		rval = emlxs_proc_abs_2mb(hba,
-		    BwcAifHdr, BwcBuffer, FILE_TYPE_BWC, BWCflag, extType);
+	if (fw_image->dwc.version) {
+		rval = emlxs_proc_rel_2mb(hba, buffer, fw_image);
+
+		if (rval) {
+			goto SLI_DOWNLOAD_2MB_EXIT;
+		}
 	}
 
 SLI_DOWNLOAD_2MB_EXIT:
@@ -3912,22 +4209,21 @@
  *
  */
 static uint32_t
-emlxs_proc_abs_2mb(emlxs_hba_t *hba,
-    PAIF_HDR AifHdr,
-    caddr_t EntireBuffer,
-    uint32_t FileType, uint32_t BWCflag, uint32_t extType)
+emlxs_proc_abs_2mb(emlxs_hba_t *hba, caddr_t EntireBuffer,
+    uint32_t FileType, uint32_t extType)
 {
 	emlxs_port_t *port = &PPORT;
+	PAIF_HDR AifHdr;
 	caddr_t Buffer = NULL;
 	caddr_t DataBuffer = NULL;
 	uint32_t *Src;
 	uint32_t *Dst;
 	MAILBOXQ *mbox;
 	MAILBOX *mb;
-	uint32_t DlByteCount = AifHdr->RoSize + AifHdr->RwSize;
+	uint32_t DlByteCount;
 	uint32_t rval = 0;
 	uint32_t SegSize = DL_SLIM_SEG_BYTE_COUNT;
-	uint32_t DlToAddr = AifHdr->ImageBase;
+	uint32_t DlToAddr;
 	uint32_t DlCount;
 	WAKE_UP_PARMS AbsWakeUpParms;
 	uint32_t i;
@@ -3935,9 +4231,11 @@
 	uint32_t EraseByteCount;
 	uint32_t AreaId;
 	uint32_t RspProgress = 0;
-	uint32_t numBootImage = 0;
-	uint32_t ParamsChg = 0;
-	uint32_t BufferSize;
+	uint32_t ParamsChg;
+
+	AifHdr = (PAIF_HDR)EntireBuffer;
+	DlByteCount = AifHdr->RoSize + AifHdr->RwSize;
+	DlToAddr = AifHdr->ImageBase;
 
 	if ((DataBuffer = (caddr_t)kmem_zalloc(DL_SLIM_SEG_BYTE_COUNT,
 	    KM_NOSLEEP)) == NULL) {
@@ -3947,8 +4245,6 @@
 		return (EMLXS_IMAGE_FAILED);
 	}
 
-	bzero(DataBuffer, sizeof (DL_SLIM_SEG_BYTE_COUNT));
-
 	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
 	    KM_NOSLEEP)) == NULL) {
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
@@ -3961,18 +4257,18 @@
 
 	mb = (MAILBOX *)mbox;
 
-	BufferSize = DlByteCount + sizeof (AIF_HDR) + sizeof (uint32_t);
 	Buffer = EntireBuffer + sizeof (AIF_HDR);
 
 	switch (FileType) {
 	case FILE_TYPE_AWC:
+		ParamsChg = 0;
 		break;
 
 	case FILE_TYPE_BWC:
-		ParamsChg = emlxs_build_parms_2mb_bwc(hba,
+		rval = emlxs_build_parms_2mb_bwc(hba,
 		    AifHdr, extType, &AbsWakeUpParms);
 
-		if (ParamsChg == FALSE) {
+		if (rval == FALSE) {
 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
 			    "BWC build parms failed.");
 
@@ -3980,22 +4276,7 @@
 
 			goto EXIT_ABS_DOWNLOAD;
 		}
-		break;
-
-	case FILE_TYPE_DWC:
-		ParamsChg = emlxs_build_parms_2mb_dwc(hba,
-		    Buffer,
-		    BufferSize,
-		    AifHdr, &AbsWakeUpParms, BWCflag, extType, &numBootImage);
-
-		if (ParamsChg == FALSE) {
-			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
-			    "DWC build parms failed.");
-
-			rval = EMLXS_IMAGE_FAILED;
-
-			goto EXIT_ABS_DOWNLOAD;
-		}
+		ParamsChg = 1;
 		break;
 
 	default:
@@ -4190,7 +4471,7 @@
 
 	/* Read wakeup paramters */
 	if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) ==
-	    CFG_DATA_NO_REGION) {
+	    (uint32_t)CFG_DATA_NO_REGION) {
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
 		    "Unable to get BWC parameters.");
 		return (FALSE);
@@ -4242,148 +4523,6 @@
 } /* emlxs_build_parms_2mb_bwc() */
 
 
-/* ARGSUSED */
-static uint32_t
-emlxs_build_parms_2mb_dwc(emlxs_hba_t *hba,
-    caddr_t Buffer,
-    uint32_t BufferSize,
-    PAIF_HDR AifHeader,
-    PWAKE_UP_PARMS AbsWakeUpParms,
-    uint32_t BWCflag, uint32_t extType, uint32_t *numBootImage)
-{
-	emlxs_port_t *port = &PPORT;
-	uint32_t NextImage;
-	uint32_t i;
-	IMAGE_HDR ImageHdr;
-	uint32_t *ptr1;
-	uint32_t *ptr2;
-	PROG_ID BootId[MAX_BOOTID];
-	uint32_t ChangeParams = FALSE;
-	WAKE_UP_PARMS WakeUpParms;
-	caddr_t Sptr;
-	caddr_t Dptr;
-
-	bzero(&BootId, (sizeof (PROG_ID)) * MAX_BOOTID);
-
-	/* Read wakeup paramters */
-	if (emlxs_read_wakeup_parms(hba, AbsWakeUpParms, 0) ==
-	    CFG_DATA_NO_REGION) {
-		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
-		    "Unable to get DWC parameters.");
-		return (FALSE);
-	}
-
-	bcopy((caddr_t)AbsWakeUpParms, (caddr_t)&WakeUpParms,
-	    sizeof (WAKE_UP_PARMS));
-
-	if (((BWCflag == ALL_WITHOUT_BWC) || (extType == DWCext)) &&
-	    (WakeUpParms.u0.boot_bios_wd[0])) {
-		*numBootImage = 0;
-	}
-
-	/* incoming buffer is without aif header */
-	NextImage = 0x84 - sizeof (AIF_HDR);
-	BufferSize -= (sizeof (AIF_HDR) + sizeof (uint32_t));
-
-	while (BufferSize > NextImage) {
-		Sptr = &Buffer[NextImage];
-		Dptr = (caddr_t)&ImageHdr;
-		for (i = 0; i < sizeof (IMAGE_HDR); i++) {
-			Dptr[i] = Sptr[i];
-		}
-
-		if (ImageHdr.BlockSize == 0xffffffff) {
-			break;
-		}
-
-		switch (ImageHdr.Id.Type) {
-		case TEST_PROGRAM:
-			break;
-
-		case FUNC_FIRMWARE:
-			AbsWakeUpParms->prog_id = ImageHdr.Id;
-			ChangeParams = TRUE;
-			break;
-
-		case BOOT_BIOS:
-			if (!WakeUpParms.u0.boot_bios_wd[0]) {
-				if (extType == DWCext) {
-					break;
-				} else if (BWCflag == ALL_WITHOUT_BWC) {
-					/* for possible future changes */
-					break;
-				}
-			}
-			ChangeParams = TRUE;
-
-			if (*numBootImage < MAX_BOOTID) {
-				BootId[*numBootImage] = ImageHdr.Id;
-				(*numBootImage)++;
-			}
-			break;
-
-		case SLI1_OVERLAY:
-			AbsWakeUpParms->sli1_prog_id = ImageHdr.Id;
-			ChangeParams = TRUE;
-			break;
-
-		case SLI2_OVERLAY:
-			AbsWakeUpParms->sli2_prog_id = ImageHdr.Id;
-			ChangeParams = TRUE;
-			break;
-
-		case SLI3_OVERLAY:
-			AbsWakeUpParms->sli3_prog_id = ImageHdr.Id;
-			ChangeParams = TRUE;
-			break;
-
-		case SLI4_OVERLAY:
-			AbsWakeUpParms->sli4_prog_id = ImageHdr.Id;
-			ChangeParams = TRUE;
-			break;
-		}
-
-		NextImage += ImageHdr.BlockSize;
-	}
-
-	if ((ChangeParams) && ((BWCflag == ALL_WITHOUT_BWC) ||
-	    (extType == DWCext))) {
-
-		if (*numBootImage > 1) {
-			for (i = 0; i < *numBootImage; i++) {
-				ptr1 =
-				    (uint32_t *)&WakeUpParms.u0.
-				    boot_bios_id;
-				ptr2 = (uint32_t *)&BootId[i];
-
-				if (ptr1[0] == ptr2[0]) {
-					AbsWakeUpParms->u1.EROM_prog_id =
-					    BootId[i];
-					(void) emlxs_update_exp_rom(hba,
-					    AbsWakeUpParms);
-					break;
-				}
-			}
-		} else {
-			if (*numBootImage == 1) {
-				ptr2 = (uint32_t *)&BootId[0];
-
-				if (WakeUpParms.u0.boot_bios_wd[0] == ptr2[0]) {
-					AbsWakeUpParms->u1.EROM_prog_id =
-					    BootId[0];
-					(void) emlxs_update_exp_rom(hba,
-					    AbsWakeUpParms);
-				}
-			}
-		}
-	}
-
-	return (ChangeParams);
-
-
-} /* emlxs_build_parms_2mb_dwc() */
-
-
 extern uint32_t
 emlxs_get_max_sram(emlxs_hba_t *hba, uint32_t *MaxRbusSize,
     uint32_t *MaxIbusSize)
@@ -4394,6 +4533,14 @@
 	uint32_t *Uptr;
 	uint32_t rval = 0;
 
+	if (MaxRbusSize) {
+		*MaxRbusSize = 0;
+	}
+
+	if (MaxIbusSize) {
+		*MaxIbusSize = 0;
+	}
+
 	if ((mbox = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
 	    KM_NOSLEEP)) == NULL) {
 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_download_failed_msg,
@@ -4425,8 +4572,13 @@
 		Uptr = (uint32_t *)&mb->un.varDmp.resp_offset;
 	}
 
-	*MaxRbusSize = Uptr[0];
-	*MaxIbusSize = Uptr[1];
+	if (MaxRbusSize) {
+		*MaxRbusSize = Uptr[0];
+	}
+
+	if (MaxIbusSize) {
+		*MaxIbusSize = Uptr[1];
+	}
 
 Exit_Function:
 
@@ -4684,6 +4836,7 @@
 	emlxs_vpd_t *vpd;
 	PROG_ID load_list[MAX_LOAD_ENTRY];
 	uint32_t i;
+	uint32_t count;
 
 	vpd = &VPD;
 
@@ -4716,12 +4869,14 @@
 		    &hba->wakeup_parms.u1.EROM_prog_id, 0);
 	} else {	/* (EMLXS_DRAGONFLY_CHIP | EMLXS_CENTAUR_CHIP) */
 
-		if (emlxs_get_load_list(hba, load_list)) {
+		count = emlxs_get_load_list(hba, load_list);
+
+		if (!count) {
 			return (FC_FAILURE);
 		}
 
 		/* Scan load list for a boot image */
-		for (i = 0; i < MAX_LOAD_ENTRY; i++) {
+		for (i = 0; i < count; i++) {
 			if (load_list[i].Type == BOOT_BIOS) {
 				/* Update the parms with the boot image id */
 				/* Don't load the EROM this time */
@@ -4732,7 +4887,7 @@
 			}
 		}
 
-		if (i == MAX_LOAD_ENTRY) {
+		if (i == count) {
 			return (EMLXS_NO_BOOT_CODE);
 		}
 	}

 
 
Close
loading
Please Confirm
Close