summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorXiang Chen <chenxiang66@hisilicon.com>2018-05-21 06:09:17 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2018-05-28 22:40:32 -0400
commitd5a60dfdb364bd1fa59c2c11be54be80f6990a3d (patch)
tree0011a7119f7384f3df8e167cf8abaf0eaa01f503 /drivers/scsi
parent428f1b3424f4fe750943d8cdd1b0dafad99b0b75 (diff)
scsi: hisi_sas: Reset disks when discovered
When a disk is discovered, it may be in an error state, or there may be residual commands remaining in the disk. To ensure any disk is in good state after discovery, reset via TMF (for SAS disk) or softreset (for a SATA disk). Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com> Signed-off-by: John Garry <john.garry@huawei.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index a7e4c6e77068..c8e647a65b30 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -24,6 +24,9 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
24static int hisi_sas_softreset_ata_disk(struct domain_device *device); 24static int hisi_sas_softreset_ata_disk(struct domain_device *device);
25static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, 25static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
26 void *funcdata); 26 void *funcdata);
27static void hisi_sas_release_task(struct hisi_hba *hisi_hba,
28 struct domain_device *device);
29static void hisi_sas_dev_gone(struct domain_device *device);
27 30
28u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction) 31u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction)
29{ 32{
@@ -624,12 +627,49 @@ static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)
624 return sas_dev; 627 return sas_dev;
625} 628}
626 629
630#define HISI_SAS_SRST_ATA_DISK_CNT 3
631static int hisi_sas_init_device(struct domain_device *device)
632{
633 int rc = TMF_RESP_FUNC_COMPLETE;
634 struct scsi_lun lun;
635 struct hisi_sas_tmf_task tmf_task;
636 int retry = HISI_SAS_SRST_ATA_DISK_CNT;
637 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
638
639 switch (device->dev_type) {
640 case SAS_END_DEVICE:
641 int_to_scsilun(0, &lun);
642
643 tmf_task.tmf = TMF_CLEAR_TASK_SET;
644 rc = hisi_sas_debug_issue_ssp_tmf(device, lun.scsi_lun,
645 &tmf_task);
646 if (rc == TMF_RESP_FUNC_COMPLETE)
647 hisi_sas_release_task(hisi_hba, device);
648 break;
649 case SAS_SATA_DEV:
650 case SAS_SATA_PM:
651 case SAS_SATA_PM_PORT:
652 case SAS_SATA_PENDING:
653 while (retry-- > 0) {
654 rc = hisi_sas_softreset_ata_disk(device);
655 if (!rc)
656 break;
657 }
658 break;
659 default:
660 break;
661 }
662
663 return rc;
664}
665
627static int hisi_sas_dev_found(struct domain_device *device) 666static int hisi_sas_dev_found(struct domain_device *device)
628{ 667{
629 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); 668 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
630 struct domain_device *parent_dev = device->parent; 669 struct domain_device *parent_dev = device->parent;
631 struct hisi_sas_device *sas_dev; 670 struct hisi_sas_device *sas_dev;
632 struct device *dev = hisi_hba->dev; 671 struct device *dev = hisi_hba->dev;
672 int rc;
633 673
634 if (hisi_hba->hw->alloc_dev) 674 if (hisi_hba->hw->alloc_dev)
635 sas_dev = hisi_hba->hw->alloc_dev(device); 675 sas_dev = hisi_hba->hw->alloc_dev(device);
@@ -661,14 +701,22 @@ static int hisi_sas_dev_found(struct domain_device *device)
661 "dev:%016llx at ex:%016llx\n", 701 "dev:%016llx at ex:%016llx\n",
662 SAS_ADDR(device->sas_addr), 702 SAS_ADDR(device->sas_addr),
663 SAS_ADDR(parent_dev->sas_addr)); 703 SAS_ADDR(parent_dev->sas_addr));
664 return -EINVAL; 704 rc = -EINVAL;
705 goto err_out;
665 } 706 }
666 } 707 }
667 708
668 dev_info(dev, "dev[%d:%x] found\n", 709 dev_info(dev, "dev[%d:%x] found\n",
669 sas_dev->device_id, sas_dev->dev_type); 710 sas_dev->device_id, sas_dev->dev_type);
670 711
712 rc = hisi_sas_init_device(device);
713 if (rc)
714 goto err_out;
671 return 0; 715 return 0;
716
717err_out:
718 hisi_sas_dev_gone(device);
719 return rc;
672} 720}
673 721
674static int hisi_sas_slave_configure(struct scsi_device *sdev) 722static int hisi_sas_slave_configure(struct scsi_device *sdev)