|
@@ -2056,7 +2056,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
|
|
ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
|
|
|
"mpt_upload: alt_%s has cached_fw=%p \n",
|
|
|
ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
|
|
|
- ioc->alt_ioc->cached_fw = NULL;
|
|
|
+ ioc->cached_fw = NULL;
|
|
|
}
|
|
|
} else {
|
|
|
printk(MYIOC_s_WARN_FMT
|
|
@@ -2262,10 +2262,12 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
|
|
|
int ret;
|
|
|
|
|
|
if (ioc->cached_fw != NULL) {
|
|
|
- ddlprintk(ioc, printk(MYIOC_s_INFO_FMT
|
|
|
- "mpt_adapter_disable: Pushing FW onto adapter\n", ioc->name));
|
|
|
- if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
|
|
|
- printk(MYIOC_s_WARN_FMT "firmware downloadboot failure (%d)!\n",
|
|
|
+ ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
|
|
|
+ "adapter\n", __FUNCTION__, ioc->name));
|
|
|
+ if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
|
|
|
+ ioc->cached_fw, CAN_SLEEP)) < 0) {
|
|
|
+ printk(MYIOC_s_WARN_FMT
|
|
|
+ ": firmware downloadboot failure (%d)!\n",
|
|
|
ioc->name, ret);
|
|
|
}
|
|
|
}
|
|
@@ -2303,13 +2305,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
|
|
|
ioc->alloc_total -= sz;
|
|
|
}
|
|
|
|
|
|
- if (ioc->cached_fw != NULL) {
|
|
|
- sz = ioc->facts.FWImageSize;
|
|
|
- pci_free_consistent(ioc->pcidev, sz,
|
|
|
- ioc->cached_fw, ioc->cached_fw_dma);
|
|
|
- ioc->cached_fw = NULL;
|
|
|
- ioc->alloc_total -= sz;
|
|
|
- }
|
|
|
+ mpt_free_fw_memory(ioc);
|
|
|
|
|
|
kfree(ioc->spi_data.nvram);
|
|
|
mpt_inactive_raid_list_free(ioc);
|
|
@@ -3047,44 +3043,62 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
|
|
|
*
|
|
|
* If memory has already been allocated, the same (cached) value
|
|
|
* is returned.
|
|
|
- */
|
|
|
-void
|
|
|
+ *
|
|
|
+ * Return 0 if successfull, or non-zero for failure
|
|
|
+ **/
|
|
|
+int
|
|
|
mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
|
|
|
{
|
|
|
- if (ioc->cached_fw)
|
|
|
- return; /* use already allocated memory */
|
|
|
- if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ if (ioc->cached_fw) {
|
|
|
+ rc = 0; /* use already allocated memory */
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
|
|
|
ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
|
|
|
ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
|
|
|
- ioc->alloc_total += size;
|
|
|
- ioc->alt_ioc->alloc_total -= size;
|
|
|
+ rc = 0;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
|
|
|
+ if (!ioc->cached_fw) {
|
|
|
+ printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
|
|
|
+ ioc->name);
|
|
|
+ rc = -1;
|
|
|
} else {
|
|
|
- if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
|
|
|
- ioc->alloc_total += size;
|
|
|
+ dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
|
|
|
+ ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
|
|
|
+ ioc->alloc_total += size;
|
|
|
+ rc = 0;
|
|
|
}
|
|
|
+ out:
|
|
|
+ return rc;
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
* mpt_free_fw_memory - free firmware memory
|
|
|
* @ioc: Pointer to MPT_ADAPTER structure
|
|
|
*
|
|
|
* If alt_img is NULL, delete from ioc structure.
|
|
|
* Else, delete a secondary image in same format.
|
|
|
- */
|
|
|
+ **/
|
|
|
void
|
|
|
mpt_free_fw_memory(MPT_ADAPTER *ioc)
|
|
|
{
|
|
|
int sz;
|
|
|
|
|
|
+ if (!ioc->cached_fw)
|
|
|
+ return;
|
|
|
+
|
|
|
sz = ioc->facts.FWImageSize;
|
|
|
- dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
|
|
|
- ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
|
|
|
+ dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
|
|
|
+ ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
|
|
|
pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
|
|
|
+ ioc->alloc_total -= sz;
|
|
|
ioc->cached_fw = NULL;
|
|
|
-
|
|
|
- return;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
|
|
/**
|
|
|
* mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
|
|
@@ -3116,17 +3130,12 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
|
|
|
if ((sz = ioc->facts.FWImageSize) == 0)
|
|
|
return 0;
|
|
|
|
|
|
- mpt_alloc_fw_memory(ioc, sz);
|
|
|
+ if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
|
|
|
ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
|
|
|
|
|
|
- if (ioc->cached_fw == NULL) {
|
|
|
- /* Major Failure.
|
|
|
- */
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
-
|
|
|
prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
|
|
|
kzalloc(ioc->req_sz, GFP_KERNEL);
|
|
|
if (!prequest) {
|
|
@@ -3498,12 +3507,12 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
|
|
|
static int
|
|
|
mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
|
|
{
|
|
|
- MPT_ADAPTER *iocp=NULL;
|
|
|
u32 diag0val;
|
|
|
u32 doorbell;
|
|
|
int hard_reset_done = 0;
|
|
|
int count = 0;
|
|
|
u32 diag1val = 0;
|
|
|
+ MpiFwHeader_t *cached_fw; /* Pointer to FW */
|
|
|
|
|
|
/* Clear any existing interrupts */
|
|
|
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
|
|
@@ -3635,22 +3644,24 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
|
|
}
|
|
|
|
|
|
if (ioc->cached_fw)
|
|
|
- iocp = ioc;
|
|
|
+ cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
|
|
|
else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
|
|
|
- iocp = ioc->alt_ioc;
|
|
|
- if (iocp) {
|
|
|
+ cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
|
|
|
+ else
|
|
|
+ cached_fw = NULL;
|
|
|
+ if (cached_fw) {
|
|
|
/* If the DownloadBoot operation fails, the
|
|
|
* IOC will be left unusable. This is a fatal error
|
|
|
* case. _diag_reset will return < 0
|
|
|
*/
|
|
|
for (count = 0; count < 30; count ++) {
|
|
|
- diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
|
|
|
+ diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
|
|
|
if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
|
|
|
- iocp->name, diag0val, count));
|
|
|
+ ioc->name, diag0val, count));
|
|
|
/* wait 1 sec */
|
|
|
if (sleepFlag == CAN_SLEEP) {
|
|
|
msleep (1000);
|
|
@@ -3658,8 +3669,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
|
|
mdelay (1000);
|
|
|
}
|
|
|
}
|
|
|
- if ((count = mpt_downloadboot(ioc,
|
|
|
- (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
|
|
|
+ if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
|
|
|
printk(MYIOC_s_WARN_FMT
|
|
|
"firmware downloadboot failure (%d)!\n", ioc->name, count);
|
|
|
}
|