[SCSI] lpfc 8.3.36: Fixed boot from san failure

Fixed boot from san failure when SLI4 FC device presented on the same PCI bus

The request_firmware interface can induce delays while looking
for firmware files, even if no fw file is present. In some situations
the delays exceeded scan_wait timeouts, resulting in situations in which
the boot device had not been discovered in time.  Boot Device does not
need to be on a lpfc device.

Change request_firmware use to be module paramater driven. Default is to
not attempt firmware download on boot. Add sysfs parameter to invoke
firmware update.

Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
James Smart
2012-10-31 14:44:33 -04:00
committed by James Bottomley
parent 286aa03166
commit c71ab8616d
5 changed files with 120 additions and 13 deletions

View File

@@ -9450,7 +9450,7 @@ lpfc_write_firmware(const struct firmware *fw, void *context)
struct lpfc_dmabuf *dmabuf, *next;
uint32_t offset = 0, temp_offset = 0;
/* It can be null, sanity check */
/* It can be null in no-wait mode, sanity check */
if (!fw) {
rc = -ENXIO;
goto out;
@@ -9528,10 +9528,47 @@ release_out:
release_firmware(fw);
out:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3024 Firmware update done: %d.", rc);
"3024 Firmware update done: %d.\n", rc);
return;
}
/**
* lpfc_sli4_request_firmware_update - Request linux generic firmware upgrade
* @phba: pointer to lpfc hba data structure.
*
* This routine is called to perform Linux generic firmware upgrade on device
* that supports such feature.
**/
int
lpfc_sli4_request_firmware_update(struct lpfc_hba *phba, uint8_t fw_upgrade)
{
uint8_t file_name[ELX_MODEL_NAME_SIZE];
int ret;
const struct firmware *fw;
/* Only supported on SLI4 interface type 2 for now */
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
LPFC_SLI_INTF_IF_TYPE_2)
return -EPERM;
snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp", phba->ModelName);
if (fw_upgrade == INT_FW_UPGRADE) {
ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
file_name, &phba->pcidev->dev,
GFP_KERNEL, (void *)phba,
lpfc_write_firmware);
} else if (fw_upgrade == RUN_FW_UPGRADE) {
ret = request_firmware(&fw, file_name, &phba->pcidev->dev);
if (!ret)
lpfc_write_firmware(fw, (void *)phba);
} else {
ret = -EINVAL;
}
return ret;
}
/**
* lpfc_pci_probe_one_s4 - PCI probe func to reg SLI-4 device to PCI subsys
* @pdev: pointer to PCI device
@@ -9560,7 +9597,6 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
uint32_t cfg_mode, intr_mode;
int mcnt;
int adjusted_fcp_io_channel;
uint8_t file_name[ELX_MODEL_NAME_SIZE];
/* Allocate memory for HBA structure */
phba = lpfc_hba_alloc(pdev);
@@ -9703,16 +9739,9 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
/* Perform post initialization setup */
lpfc_post_init_setup(phba);
/* check for firmware upgrade or downgrade (if_type 2 only) */
if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
LPFC_SLI_INTF_IF_TYPE_2) {
snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp",
phba->ModelName);
ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
file_name, &phba->pcidev->dev,
GFP_KERNEL, (void *)phba,
lpfc_write_firmware);
}
/* check for firmware upgrade or downgrade */
if (phba->cfg_request_firmware_upgrade)
ret = lpfc_sli4_request_firmware_update(phba, INT_FW_UPGRADE);
/* Check if there are static vports to be created. */
lpfc_create_static_vport(phba);