diff options
Diffstat (limited to 'drivers/message/fusion/mptbase.c')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 94 |
1 files changed, 52 insertions, 42 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 52fb216dfe74..425f60c21fdd 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -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); } |