From: Changyuan Lyu <changyuanl@xxxxxxxxxx> Added a wait timeout to prevent the kernel from waiting for the GET_NVMD response forever during probe. Added a check for the controller state before issuing GET_NVMD request. Signed-off-by: Changyuan Lyu <changyuanl@xxxxxxxxxx> Signed-off-by: Pranav Prasad <pranavpp@xxxxxxxxxx> --- drivers/scsi/pm8001/pm8001_init.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 7e589fe3e010..5ca20ccdce34 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -666,7 +666,7 @@ static void pm8001_post_sas_ha_init(struct Scsi_Host *shost, * Currently we just set the fixed SAS address to our HBA, for manufacture, * it should read from the EEPROM */ -static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) +static int pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) { u8 i, j; u8 sas_add[8]; @@ -679,6 +679,12 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) struct pm8001_ioctl_payload payload; u16 deviceid; int rc; + unsigned long time_remaining; + + if (PM8001_CHIP_DISP->fatal_errors(pm8001_ha)) { + pm8001_dbg(pm8001_ha, FAIL, "controller is in fatal error state\n"); + return -EIO; + } pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid); pm8001_ha->nvmd_completion = &completion; @@ -703,16 +709,23 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) payload.offset = 0; payload.func_specific = kzalloc(payload.rd_length, GFP_KERNEL); if (!payload.func_specific) { - pm8001_dbg(pm8001_ha, INIT, "mem alloc fail\n"); - return; + pm8001_dbg(pm8001_ha, FAIL, "mem alloc fail\n"); + return -ENOMEM; } rc = PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); if (rc) { kfree(payload.func_specific); - pm8001_dbg(pm8001_ha, INIT, "nvmd failed\n"); - return; + pm8001_dbg(pm8001_ha, FAIL, "nvmd failed\n"); + return -EIO; + } + time_remaining = wait_for_completion_timeout(&completion, + msecs_to_jiffies(60*1000)); // 1 min + if (!time_remaining) { + kfree(payload.func_specific); + pm8001_dbg(pm8001_ha, FAIL, "get_nvmd_req timeout\n"); + return -EIO; } - wait_for_completion(&completion); + for (i = 0, j = 0; i <= 7; i++, j++) { if (pm8001_ha->chip_id == chip_8001) { @@ -751,6 +764,7 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) memcpy(pm8001_ha->sas_addr, &pm8001_ha->phy[0].dev_sas_addr, SAS_ADDR_SIZE); #endif + return 0; } /* @@ -1166,7 +1180,8 @@ static int pm8001_pci_probe(struct pci_dev *pdev, pm80xx_set_thermal_config(pm8001_ha); } - pm8001_init_sas_add(pm8001_ha); + if (pm8001_init_sas_add(pm8001_ha)) + goto err_out_shost; /* phy setting support for motherboard controller */ rc = pm8001_configure_phy_settings(pm8001_ha); if (rc) -- 2.40.0.634.g4ca3ef3211-goog