diff options
-rw-r--r-- | drivers/message/fusion/mptbase.c | 94 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 2 |
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 | * |
3051 | void | 3047 | * Return 0 if successfull, or non-zero for failure |
3048 | **/ | ||
3049 | int | ||
3052 | mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) | 3050 | mpt_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 | **/ |
3073 | void | 3086 | void |
3074 | mpt_free_fw_memory(MPT_ADAPTER *ioc) | 3087 | mpt_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) | |||
3498 | static int | 3507 | static int |
3499 | mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | 3508 | mpt_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); | |||
907 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); | 907 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); |
908 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); | 908 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); |
909 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); | 909 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); |
910 | extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); | 910 | extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); |
911 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); | 911 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); |
912 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); | 912 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); |
913 | extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); | 913 | extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); |