aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBradley Grove <bgrove@attotech.com>2014-07-09 07:50:23 -0400
committerChristoph Hellwig <hch@lst.de>2014-07-25 17:17:04 -0400
commit9f17609968af25a4082d4329abbc6e4f52eda7cd (patch)
tree55bf6d580cb30d34a70bc82dd4b1cbf8d8e28d9a
parent4dc06fd84645c323a1f20482b9b571cab6dc7d93 (diff)
pm8001: Fix hibernation issue
During hibernation, the HBA firmware may lose power and forget the device id info. This causes the HBA to reject IO upon resume. The fix is to call the libsas power management routines to make the domain device forgetful. This fixes bug 76681: https://bugzilla.kernel.org/show_bug.cgi?id=76681 Signed-off-by: Bradley Grove <bgrove@attotech.com> Acked-by: Jack Wang <xjtuwjp@gmail.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/pm8001/pm8001_init.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index e90c89f1d480..aad060aa3c0c 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -964,6 +964,7 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
964 int i, j; 964 int i, j;
965 u32 device_state; 965 u32 device_state;
966 pm8001_ha = sha->lldd_ha; 966 pm8001_ha = sha->lldd_ha;
967 sas_suspend_ha(sha);
967 flush_workqueue(pm8001_wq); 968 flush_workqueue(pm8001_wq);
968 scsi_block_requests(pm8001_ha->shost); 969 scsi_block_requests(pm8001_ha->shost);
969 if (!pdev->pm_cap) { 970 if (!pdev->pm_cap) {
@@ -1013,6 +1014,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
1013 int rc; 1014 int rc;
1014 u8 i = 0, j; 1015 u8 i = 0, j;
1015 u32 device_state; 1016 u32 device_state;
1017 DECLARE_COMPLETION_ONSTACK(completion);
1016 pm8001_ha = sha->lldd_ha; 1018 pm8001_ha = sha->lldd_ha;
1017 device_state = pdev->current_state; 1019 device_state = pdev->current_state;
1018 1020
@@ -1033,7 +1035,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
1033 rc = pci_go_44(pdev); 1035 rc = pci_go_44(pdev);
1034 if (rc) 1036 if (rc)
1035 goto err_out_disable; 1037 goto err_out_disable;
1036 1038 sas_prep_resume_ha(sha);
1037 /* chip soft rst only for spc */ 1039 /* chip soft rst only for spc */
1038 if (pm8001_ha->chip_id == chip_8001) { 1040 if (pm8001_ha->chip_id == chip_8001) {
1039 PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha); 1041 PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
@@ -1065,7 +1067,13 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
1065 for (i = 1; i < pm8001_ha->number_of_intr; i++) 1067 for (i = 1; i < pm8001_ha->number_of_intr; i++)
1066 PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i); 1068 PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i);
1067 } 1069 }
1068 scsi_unblock_requests(pm8001_ha->shost); 1070 pm8001_ha->flags = PM8001F_RUN_TIME;
1071 for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
1072 pm8001_ha->phy[i].enable_completion = &completion;
1073 PM8001_CHIP_DISP->phy_start_req(pm8001_ha, i);
1074 wait_for_completion(&completion);
1075 }
1076 sas_resume_ha(sha);
1069 return 0; 1077 return 0;
1070 1078
1071err_out_disable: 1079err_out_disable: