diff options
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7a981d1956d6..56cddd87894c 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -9309,23 +9309,28 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba) | |||
9309 | 9309 | ||
9310 | /** | 9310 | /** |
9311 | * lpfc_write_firmware - attempt to write a firmware image to the port | 9311 | * lpfc_write_firmware - attempt to write a firmware image to the port |
9312 | * @phba: pointer to lpfc hba data structure. | ||
9313 | * @fw: pointer to firmware image returned from request_firmware. | 9312 | * @fw: pointer to firmware image returned from request_firmware. |
9313 | * @phba: pointer to lpfc hba data structure. | ||
9314 | * | 9314 | * |
9315 | * returns the number of bytes written if write is successful. | ||
9316 | * returns a negative error value if there were errors. | ||
9317 | * returns 0 if firmware matches currently active firmware on port. | ||
9318 | **/ | 9315 | **/ |
9319 | int | 9316 | static void |
9320 | lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | 9317 | lpfc_write_firmware(const struct firmware *fw, void *context) |
9321 | { | 9318 | { |
9319 | struct lpfc_hba *phba = (struct lpfc_hba *)context; | ||
9322 | char fwrev[FW_REV_STR_SIZE]; | 9320 | char fwrev[FW_REV_STR_SIZE]; |
9323 | struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data; | 9321 | struct lpfc_grp_hdr *image; |
9324 | struct list_head dma_buffer_list; | 9322 | struct list_head dma_buffer_list; |
9325 | int i, rc = 0; | 9323 | int i, rc = 0; |
9326 | struct lpfc_dmabuf *dmabuf, *next; | 9324 | struct lpfc_dmabuf *dmabuf, *next; |
9327 | uint32_t offset = 0, temp_offset = 0; | 9325 | uint32_t offset = 0, temp_offset = 0; |
9328 | 9326 | ||
9327 | /* It can be null, sanity check */ | ||
9328 | if (!fw) { | ||
9329 | rc = -ENXIO; | ||
9330 | goto out; | ||
9331 | } | ||
9332 | image = (struct lpfc_grp_hdr *)fw->data; | ||
9333 | |||
9329 | INIT_LIST_HEAD(&dma_buffer_list); | 9334 | INIT_LIST_HEAD(&dma_buffer_list); |
9330 | if ((be32_to_cpu(image->magic_number) != LPFC_GROUP_OJECT_MAGIC_NUM) || | 9335 | if ((be32_to_cpu(image->magic_number) != LPFC_GROUP_OJECT_MAGIC_NUM) || |
9331 | (bf_get_be32(lpfc_grp_hdr_file_type, image) != | 9336 | (bf_get_be32(lpfc_grp_hdr_file_type, image) != |
@@ -9338,12 +9343,13 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | |||
9338 | be32_to_cpu(image->magic_number), | 9343 | be32_to_cpu(image->magic_number), |
9339 | bf_get_be32(lpfc_grp_hdr_file_type, image), | 9344 | bf_get_be32(lpfc_grp_hdr_file_type, image), |
9340 | bf_get_be32(lpfc_grp_hdr_id, image)); | 9345 | bf_get_be32(lpfc_grp_hdr_id, image)); |
9341 | return -EINVAL; | 9346 | rc = -EINVAL; |
9347 | goto release_out; | ||
9342 | } | 9348 | } |
9343 | lpfc_decode_firmware_rev(phba, fwrev, 1); | 9349 | lpfc_decode_firmware_rev(phba, fwrev, 1); |
9344 | if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) { | 9350 | if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) { |
9345 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9351 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
9346 | "3023 Updating Firmware. Current Version:%s " | 9352 | "3023 Updating Firmware, Current Version:%s " |
9347 | "New Version:%s\n", | 9353 | "New Version:%s\n", |
9348 | fwrev, image->revision); | 9354 | fwrev, image->revision); |
9349 | for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) { | 9355 | for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) { |
@@ -9351,7 +9357,7 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | |||
9351 | GFP_KERNEL); | 9357 | GFP_KERNEL); |
9352 | if (!dmabuf) { | 9358 | if (!dmabuf) { |
9353 | rc = -ENOMEM; | 9359 | rc = -ENOMEM; |
9354 | goto out; | 9360 | goto release_out; |
9355 | } | 9361 | } |
9356 | dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev, | 9362 | dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev, |
9357 | SLI4_PAGE_SIZE, | 9363 | SLI4_PAGE_SIZE, |
@@ -9360,7 +9366,7 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | |||
9360 | if (!dmabuf->virt) { | 9366 | if (!dmabuf->virt) { |
9361 | kfree(dmabuf); | 9367 | kfree(dmabuf); |
9362 | rc = -ENOMEM; | 9368 | rc = -ENOMEM; |
9363 | goto out; | 9369 | goto release_out; |
9364 | } | 9370 | } |
9365 | list_add_tail(&dmabuf->list, &dma_buffer_list); | 9371 | list_add_tail(&dmabuf->list, &dma_buffer_list); |
9366 | } | 9372 | } |
@@ -9380,23 +9386,24 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw) | |||
9380 | } | 9386 | } |
9381 | rc = lpfc_wr_object(phba, &dma_buffer_list, | 9387 | rc = lpfc_wr_object(phba, &dma_buffer_list, |
9382 | (fw->size - offset), &offset); | 9388 | (fw->size - offset), &offset); |
9383 | if (rc) { | 9389 | if (rc) |
9384 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 9390 | goto release_out; |
9385 | "3024 Firmware update failed. " | ||
9386 | "%d\n", rc); | ||
9387 | goto out; | ||
9388 | } | ||
9389 | } | 9391 | } |
9390 | rc = offset; | 9392 | rc = offset; |
9391 | } | 9393 | } |
9392 | out: | 9394 | |
9395 | release_out: | ||
9393 | list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) { | 9396 | list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) { |
9394 | list_del(&dmabuf->list); | 9397 | list_del(&dmabuf->list); |
9395 | dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE, | 9398 | dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE, |
9396 | dmabuf->virt, dmabuf->phys); | 9399 | dmabuf->virt, dmabuf->phys); |
9397 | kfree(dmabuf); | 9400 | kfree(dmabuf); |
9398 | } | 9401 | } |
9399 | return rc; | 9402 | release_firmware(fw); |
9403 | out: | ||
9404 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
9405 | "3024 Firmware update done: %d.", rc); | ||
9406 | return; | ||
9400 | } | 9407 | } |
9401 | 9408 | ||
9402 | /** | 9409 | /** |
@@ -9423,11 +9430,10 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
9423 | struct lpfc_hba *phba; | 9430 | struct lpfc_hba *phba; |
9424 | struct lpfc_vport *vport = NULL; | 9431 | struct lpfc_vport *vport = NULL; |
9425 | struct Scsi_Host *shost = NULL; | 9432 | struct Scsi_Host *shost = NULL; |
9426 | int error; | 9433 | int error, ret; |
9427 | uint32_t cfg_mode, intr_mode; | 9434 | uint32_t cfg_mode, intr_mode; |
9428 | int mcnt; | 9435 | int mcnt; |
9429 | int adjusted_fcp_io_channel; | 9436 | int adjusted_fcp_io_channel; |
9430 | const struct firmware *fw; | ||
9431 | uint8_t file_name[ELX_MODEL_NAME_SIZE]; | 9437 | uint8_t file_name[ELX_MODEL_NAME_SIZE]; |
9432 | 9438 | ||
9433 | /* Allocate memory for HBA structure */ | 9439 | /* Allocate memory for HBA structure */ |
@@ -9576,11 +9582,10 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
9576 | LPFC_SLI_INTF_IF_TYPE_2) { | 9582 | LPFC_SLI_INTF_IF_TYPE_2) { |
9577 | snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp", | 9583 | snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp", |
9578 | phba->ModelName); | 9584 | phba->ModelName); |
9579 | error = request_firmware(&fw, file_name, &phba->pcidev->dev); | 9585 | ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, |
9580 | if (!error) { | 9586 | file_name, &phba->pcidev->dev, |
9581 | lpfc_write_firmware(phba, fw); | 9587 | GFP_KERNEL, (void *)phba, |
9582 | release_firmware(fw); | 9588 | lpfc_write_firmware); |
9583 | } | ||
9584 | } | 9589 | } |
9585 | 9590 | ||
9586 | /* Check if there are static vports to be created. */ | 9591 | /* Check if there are static vports to be created. */ |