[SCSI] lpfc 8.3.35: Correct request_firmware use that was increasing boot times
Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
committed by
James Bottomley
parent
2a94aea436
commit
ce3962829d
@@ -9309,23 +9309,28 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* lpfc_write_firmware - attempt to write a firmware image to the port
|
* lpfc_write_firmware - attempt to write a firmware image to the port
|
||||||
* @phba: pointer to lpfc hba data structure.
|
|
||||||
* @fw: pointer to firmware image returned from request_firmware.
|
* @fw: pointer to firmware image returned from request_firmware.
|
||||||
|
* @phba: pointer to lpfc hba data structure.
|
||||||
*
|
*
|
||||||
* returns the number of bytes written if write is successful.
|
|
||||||
* returns a negative error value if there were errors.
|
|
||||||
* returns 0 if firmware matches currently active firmware on port.
|
|
||||||
**/
|
**/
|
||||||
int
|
static void
|
||||||
lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
|
lpfc_write_firmware(const struct firmware *fw, void *context)
|
||||||
{
|
{
|
||||||
|
struct lpfc_hba *phba = (struct lpfc_hba *)context;
|
||||||
char fwrev[FW_REV_STR_SIZE];
|
char fwrev[FW_REV_STR_SIZE];
|
||||||
struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data;
|
struct lpfc_grp_hdr *image;
|
||||||
struct list_head dma_buffer_list;
|
struct list_head dma_buffer_list;
|
||||||
int i, rc = 0;
|
int i, rc = 0;
|
||||||
struct lpfc_dmabuf *dmabuf, *next;
|
struct lpfc_dmabuf *dmabuf, *next;
|
||||||
uint32_t offset = 0, temp_offset = 0;
|
uint32_t offset = 0, temp_offset = 0;
|
||||||
|
|
||||||
|
/* It can be null, sanity check */
|
||||||
|
if (!fw) {
|
||||||
|
rc = -ENXIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
image = (struct lpfc_grp_hdr *)fw->data;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&dma_buffer_list);
|
INIT_LIST_HEAD(&dma_buffer_list);
|
||||||
if ((be32_to_cpu(image->magic_number) != LPFC_GROUP_OJECT_MAGIC_NUM) ||
|
if ((be32_to_cpu(image->magic_number) != LPFC_GROUP_OJECT_MAGIC_NUM) ||
|
||||||
(bf_get_be32(lpfc_grp_hdr_file_type, image) !=
|
(bf_get_be32(lpfc_grp_hdr_file_type, image) !=
|
||||||
@@ -9338,12 +9343,13 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
|
|||||||
be32_to_cpu(image->magic_number),
|
be32_to_cpu(image->magic_number),
|
||||||
bf_get_be32(lpfc_grp_hdr_file_type, image),
|
bf_get_be32(lpfc_grp_hdr_file_type, image),
|
||||||
bf_get_be32(lpfc_grp_hdr_id, image));
|
bf_get_be32(lpfc_grp_hdr_id, image));
|
||||||
return -EINVAL;
|
rc = -EINVAL;
|
||||||
|
goto release_out;
|
||||||
}
|
}
|
||||||
lpfc_decode_firmware_rev(phba, fwrev, 1);
|
lpfc_decode_firmware_rev(phba, fwrev, 1);
|
||||||
if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
|
if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) {
|
||||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||||
"3023 Updating Firmware. Current Version:%s "
|
"3023 Updating Firmware, Current Version:%s "
|
||||||
"New Version:%s\n",
|
"New Version:%s\n",
|
||||||
fwrev, image->revision);
|
fwrev, image->revision);
|
||||||
for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) {
|
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)
|
|||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!dmabuf) {
|
if (!dmabuf) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto out;
|
goto release_out;
|
||||||
}
|
}
|
||||||
dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev,
|
dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev,
|
||||||
SLI4_PAGE_SIZE,
|
SLI4_PAGE_SIZE,
|
||||||
@@ -9360,7 +9366,7 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
|
|||||||
if (!dmabuf->virt) {
|
if (!dmabuf->virt) {
|
||||||
kfree(dmabuf);
|
kfree(dmabuf);
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto out;
|
goto release_out;
|
||||||
}
|
}
|
||||||
list_add_tail(&dmabuf->list, &dma_buffer_list);
|
list_add_tail(&dmabuf->list, &dma_buffer_list);
|
||||||
}
|
}
|
||||||
@@ -9380,23 +9386,24 @@ lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
|
|||||||
}
|
}
|
||||||
rc = lpfc_wr_object(phba, &dma_buffer_list,
|
rc = lpfc_wr_object(phba, &dma_buffer_list,
|
||||||
(fw->size - offset), &offset);
|
(fw->size - offset), &offset);
|
||||||
if (rc) {
|
if (rc)
|
||||||
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
goto release_out;
|
||||||
"3024 Firmware update failed. "
|
|
||||||
"%d\n", rc);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
rc = offset;
|
rc = offset;
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
|
release_out:
|
||||||
list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) {
|
list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) {
|
||||||
list_del(&dmabuf->list);
|
list_del(&dmabuf->list);
|
||||||
dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE,
|
dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE,
|
||||||
dmabuf->virt, dmabuf->phys);
|
dmabuf->virt, dmabuf->phys);
|
||||||
kfree(dmabuf);
|
kfree(dmabuf);
|
||||||
}
|
}
|
||||||
return rc;
|
release_firmware(fw);
|
||||||
|
out:
|
||||||
|
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
|
||||||
|
"3024 Firmware update done: %d.", rc);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9423,11 +9430,10 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
|
|||||||
struct lpfc_hba *phba;
|
struct lpfc_hba *phba;
|
||||||
struct lpfc_vport *vport = NULL;
|
struct lpfc_vport *vport = NULL;
|
||||||
struct Scsi_Host *shost = NULL;
|
struct Scsi_Host *shost = NULL;
|
||||||
int error;
|
int error, ret;
|
||||||
uint32_t cfg_mode, intr_mode;
|
uint32_t cfg_mode, intr_mode;
|
||||||
int mcnt;
|
int mcnt;
|
||||||
int adjusted_fcp_io_channel;
|
int adjusted_fcp_io_channel;
|
||||||
const struct firmware *fw;
|
|
||||||
uint8_t file_name[ELX_MODEL_NAME_SIZE];
|
uint8_t file_name[ELX_MODEL_NAME_SIZE];
|
||||||
|
|
||||||
/* Allocate memory for HBA structure */
|
/* Allocate memory for HBA structure */
|
||||||
@@ -9576,11 +9582,10 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
|
|||||||
LPFC_SLI_INTF_IF_TYPE_2) {
|
LPFC_SLI_INTF_IF_TYPE_2) {
|
||||||
snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp",
|
snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp",
|
||||||
phba->ModelName);
|
phba->ModelName);
|
||||||
error = request_firmware(&fw, file_name, &phba->pcidev->dev);
|
ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
|
||||||
if (!error) {
|
file_name, &phba->pcidev->dev,
|
||||||
lpfc_write_firmware(phba, fw);
|
GFP_KERNEL, (void *)phba,
|
||||||
release_firmware(fw);
|
lpfc_write_firmware);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if there are static vports to be created. */
|
/* Check if there are static vports to be created. */
|
||||||
|
Reference in New Issue
Block a user