--- 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.");
-
- 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.");
+ 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 (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;
- }
+ } 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;
}
-
- } /* !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);
}
}