aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/message/fusion/mptbase.c94
-rw-r--r--drivers/message/fusion/mptbase.h2
2 files changed, 53 insertions, 43 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)
2056 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2056 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2057 "mpt_upload: alt_%s has cached_fw=%p \n", 2057 "mpt_upload: alt_%s has cached_fw=%p \n",
2058 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw)); 2058 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2059 ioc->alt_ioc->cached_fw = NULL; 2059 ioc->cached_fw = NULL;
2060 } 2060 }
2061 } else { 2061 } else {
2062 printk(MYIOC_s_WARN_FMT 2062 printk(MYIOC_s_WARN_FMT
@@ -2262,10 +2262,12 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2262 int ret; 2262 int ret;
2263 2263
2264 if (ioc->cached_fw != NULL) { 2264 if (ioc->cached_fw != NULL) {
2265 ddlprintk(ioc, printk(MYIOC_s_INFO_FMT 2265 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2266 "mpt_adapter_disable: Pushing FW onto adapter\n", ioc->name)); 2266 "adapter\n", __FUNCTION__, ioc->name));
2267 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) { 2267 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2268 printk(MYIOC_s_WARN_FMT "firmware downloadboot failure (%d)!\n", 2268 ioc->cached_fw, CAN_SLEEP)) < 0) {
2269 printk(MYIOC_s_WARN_FMT
2270 ": firmware downloadboot failure (%d)!\n",
2269 ioc->name, ret); 2271 ioc->name, ret);
2270 } 2272 }
2271 } 2273 }
@@ -2303,13 +2305,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2303 ioc->alloc_total -= sz; 2305 ioc->alloc_total -= sz;
2304 } 2306 }
2305 2307
2306 if (ioc->cached_fw != NULL) { 2308 mpt_free_fw_memory(ioc);
2307 sz = ioc->facts.FWImageSize;
2308 pci_free_consistent(ioc->pcidev, sz,
2309 ioc->cached_fw, ioc->cached_fw_dma);
2310 ioc->cached_fw = NULL;
2311 ioc->alloc_total -= sz;
2312 }
2313 2309
2314 kfree(ioc->spi_data.nvram); 2310 kfree(ioc->spi_data.nvram);
2315 mpt_inactive_raid_list_free(ioc); 2311 mpt_inactive_raid_list_free(ioc);
@@ -3047,44 +3043,62 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3047 * 3043 *
3048 * If memory has already been allocated, the same (cached) value 3044 * If memory has already been allocated, the same (cached) value
3049 * is returned. 3045 * is returned.
3050 */ 3046 *
3051void 3047 * Return 0 if successfull, or non-zero for failure
3048 **/
3049int
3052mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) 3050mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3053{ 3051{
3054 if (ioc->cached_fw) 3052 int rc;
3055 return; /* use already allocated memory */ 3053
3056 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { 3054 if (ioc->cached_fw) {
3055 rc = 0; /* use already allocated memory */
3056 goto out;
3057 }
3058 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3057 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */ 3059 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3058 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma; 3060 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3059 ioc->alloc_total += size; 3061 rc = 0;
3060 ioc->alt_ioc->alloc_total -= size; 3062 goto out;
3063 }
3064 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3065 if (!ioc->cached_fw) {
3066 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3067 ioc->name);
3068 rc = -1;
3061 } else { 3069 } else {
3062 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) ) 3070 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3063 ioc->alloc_total += size; 3071 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3072 ioc->alloc_total += size;
3073 rc = 0;
3064 } 3074 }
3075 out:
3076 return rc;
3065} 3077}
3078
3066/** 3079/**
3067 * mpt_free_fw_memory - free firmware memory 3080 * mpt_free_fw_memory - free firmware memory
3068 * @ioc: Pointer to MPT_ADAPTER structure 3081 * @ioc: Pointer to MPT_ADAPTER structure
3069 * 3082 *
3070 * If alt_img is NULL, delete from ioc structure. 3083 * If alt_img is NULL, delete from ioc structure.
3071 * Else, delete a secondary image in same format. 3084 * Else, delete a secondary image in same format.
3072 */ 3085 **/
3073void 3086void
3074mpt_free_fw_memory(MPT_ADAPTER *ioc) 3087mpt_free_fw_memory(MPT_ADAPTER *ioc)
3075{ 3088{
3076 int sz; 3089 int sz;
3077 3090
3091 if (!ioc->cached_fw)
3092 return;
3093
3078 sz = ioc->facts.FWImageSize; 3094 sz = ioc->facts.FWImageSize;
3079 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n", 3095 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3080 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 3096 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3081 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma); 3097 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3098 ioc->alloc_total -= sz;
3082 ioc->cached_fw = NULL; 3099 ioc->cached_fw = NULL;
3083
3084 return;
3085} 3100}
3086 3101
3087
3088/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3102/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3089/** 3103/**
3090 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port. 3104 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
@@ -3116,17 +3130,12 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3116 if ((sz = ioc->facts.FWImageSize) == 0) 3130 if ((sz = ioc->facts.FWImageSize) == 0)
3117 return 0; 3131 return 0;
3118 3132
3119 mpt_alloc_fw_memory(ioc, sz); 3133 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3134 return -ENOMEM;
3120 3135
3121 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n", 3136 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3122 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 3137 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3123 3138
3124 if (ioc->cached_fw == NULL) {
3125 /* Major Failure.
3126 */
3127 return -ENOMEM;
3128 }
3129
3130 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) : 3139 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3131 kzalloc(ioc->req_sz, GFP_KERNEL); 3140 kzalloc(ioc->req_sz, GFP_KERNEL);
3132 if (!prequest) { 3141 if (!prequest) {
@@ -3498,12 +3507,12 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3498static int 3507static int
3499mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) 3508mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3500{ 3509{
3501 MPT_ADAPTER *iocp=NULL;
3502 u32 diag0val; 3510 u32 diag0val;
3503 u32 doorbell; 3511 u32 doorbell;
3504 int hard_reset_done = 0; 3512 int hard_reset_done = 0;
3505 int count = 0; 3513 int count = 0;
3506 u32 diag1val = 0; 3514 u32 diag1val = 0;
3515 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3507 3516
3508 /* Clear any existing interrupts */ 3517 /* Clear any existing interrupts */
3509 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 3518 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
@@ -3635,22 +3644,24 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3635 } 3644 }
3636 3645
3637 if (ioc->cached_fw) 3646 if (ioc->cached_fw)
3638 iocp = ioc; 3647 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3639 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) 3648 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3640 iocp = ioc->alt_ioc; 3649 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3641 if (iocp) { 3650 else
3651 cached_fw = NULL;
3652 if (cached_fw) {
3642 /* If the DownloadBoot operation fails, the 3653 /* If the DownloadBoot operation fails, the
3643 * IOC will be left unusable. This is a fatal error 3654 * IOC will be left unusable. This is a fatal error
3644 * case. _diag_reset will return < 0 3655 * case. _diag_reset will return < 0
3645 */ 3656 */
3646 for (count = 0; count < 30; count ++) { 3657 for (count = 0; count < 30; count ++) {
3647 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic); 3658 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3648 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { 3659 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3649 break; 3660 break;
3650 } 3661 }
3651 3662
3652 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n", 3663 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3653 iocp->name, diag0val, count)); 3664 ioc->name, diag0val, count));
3654 /* wait 1 sec */ 3665 /* wait 1 sec */
3655 if (sleepFlag == CAN_SLEEP) { 3666 if (sleepFlag == CAN_SLEEP) {
3656 msleep (1000); 3667 msleep (1000);
@@ -3658,8 +3669,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3658 mdelay (1000); 3669 mdelay (1000);
3659 } 3670 }
3660 } 3671 }
3661 if ((count = mpt_downloadboot(ioc, 3672 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3662 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3663 printk(MYIOC_s_WARN_FMT 3673 printk(MYIOC_s_WARN_FMT
3664 "firmware downloadboot failure (%d)!\n", ioc->name, count); 3674 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3665 } 3675 }
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index d7682e083f59..b49b706c0020 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -907,7 +907,7 @@ extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
907extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); 907extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
908extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); 908extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
909extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); 909extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
910extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); 910extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
911extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 911extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
912extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 912extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
913extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 913extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);