summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pm8001
diff options
context:
space:
mode:
authorChangyuan Lyu <changyuanl@google.com>2023-04-19 19:55:02 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2023-05-08 13:15:38 +0200
commit14a8f116cdc0cbfdb939f145b02173af82083b91 (patch)
tree2049b8954697cea3f1a2920bbb0c18b85232ad28 /drivers/scsi/pm8001
parentscsi: pm80xx: Update PHY state after hard reset (diff)
downloadlinux-14a8f116cdc0cbfdb939f145b02173af82083b91.tar.xz
linux-14a8f116cdc0cbfdb939f145b02173af82083b91.zip
scsi: pm80xx: Add GET_NVMD timeout during probe
Add a wait timeout to prevent the kernel from waiting for the GET_NVMD response forever during probe. Add a check for the controller state before issuing GET_NVMD request. Signed-off-by: Changyuan Lyu <changyuanl@google.com> Signed-off-by: Pranav Prasad <pranavpp@google.com> Link: https://lore.kernel.org/r/20230419175502.919999-1-pranavpp@google.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/pm8001')
-rw-r--r--drivers/scsi/pm8001/pm8001_init.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index c23250aab4f9..2e886c1d867d 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -667,7 +667,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];
@@ -680,6 +680,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;
@@ -704,16 +710,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) {
@@ -752,6 +765,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;
}
/*
@@ -1167,7 +1181,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)