Skip to content

Commit

Permalink
scsi: pm80xx: Fix drives missing during rmmod/insmod loop
Browse files Browse the repository at this point in the history
[ Upstream commit d1acd81 ]

When driver is loaded after rmmod some drives are not showing up during
discovery.

SATA drives are directly attached to the controller connected phys.  During
device discovery, the IDENTIFY command (qc timeout (cmd 0xec)) is timing out
during revalidation. This will trigger abort from host side and controller
successfully aborts the command and returns success. Post this successful
abort response ATA library decides to mark the disk as NODEV.

To overcome this, inside pm8001_scan_start() after phy_start() call, add get
start response and wait for few milliseconds to trigger next phy start.
This millisecond delay will give sufficient time for the controller state
machine to accept next phy start.

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Ajish Koshy <[email protected]>
Signed-off-by: Viswas G <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
Ajish Koshy authored and gregkh committed Jun 3, 2021
1 parent 4414c81 commit 063c784
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 12 deletions.
10 changes: 6 additions & 4 deletions drivers/scsi/pm8001/pm8001_hwi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3709,11 +3709,13 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
case HW_EVENT_PHY_START_STATUS:
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_START_STATUS status = %x\n",
status);
if (status == 0) {
if (status == 0)
phy->phy_state = 1;
if (pm8001_ha->flags == PM8001F_RUN_TIME &&
phy->enable_completion != NULL)
complete(phy->enable_completion);

if (pm8001_ha->flags == PM8001F_RUN_TIME &&
phy->enable_completion != NULL) {
complete(phy->enable_completion);
phy->enable_completion = NULL;
}
break;
case HW_EVENT_SAS_PHY_UP:
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/pm8001/pm8001_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1144,8 +1144,8 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
goto err_out_shost;
}
list_add_tail(&pm8001_ha->list, &hba_list);
scsi_scan_host(pm8001_ha->shost);
pm8001_ha->flags = PM8001F_RUN_TIME;
scsi_scan_host(pm8001_ha->shost);
return 0;

err_out_shost:
Expand Down
7 changes: 6 additions & 1 deletion drivers/scsi/pm8001/pm8001_sas.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,17 @@ void pm8001_scan_start(struct Scsi_Host *shost)
int i;
struct pm8001_hba_info *pm8001_ha;
struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
DECLARE_COMPLETION_ONSTACK(completion);
pm8001_ha = sha->lldd_ha;
/* SAS_RE_INITIALIZATION not available in SPCv/ve */
if (pm8001_ha->chip_id == chip_8001)
PM8001_CHIP_DISP->sas_re_init_req(pm8001_ha);
for (i = 0; i < pm8001_ha->chip->n_phy; ++i)
for (i = 0; i < pm8001_ha->chip->n_phy; ++i) {
pm8001_ha->phy[i].enable_completion = &completion;
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, i);
wait_for_completion(&completion);
msleep(300);
}
}

int pm8001_scan_finished(struct Scsi_Host *shost, unsigned long time)
Expand Down
12 changes: 6 additions & 6 deletions drivers/scsi/pm8001/pm80xx_hwi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3485,13 +3485,13 @@ static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
pm8001_dbg(pm8001_ha, INIT,
"phy start resp status:0x%x, phyid:0x%x\n",
status, phy_id);
if (status == 0) {
if (status == 0)
phy->phy_state = PHY_LINK_DOWN;
if (pm8001_ha->flags == PM8001F_RUN_TIME &&
phy->enable_completion != NULL) {
complete(phy->enable_completion);
phy->enable_completion = NULL;
}

if (pm8001_ha->flags == PM8001F_RUN_TIME &&
phy->enable_completion != NULL) {
complete(phy->enable_completion);
phy->enable_completion = NULL;
}
return 0;

Expand Down

0 comments on commit 063c784

Please sign in to comment.