aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas.h7
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c44
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v2_hw.c1
3 files changed, 49 insertions, 3 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 515aee9318a4..9bfa9f12d81e 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -18,6 +18,7 @@
18#include <linux/dmapool.h> 18#include <linux/dmapool.h>
19#include <linux/iopoll.h> 19#include <linux/iopoll.h>
20#include <linux/lcm.h> 20#include <linux/lcm.h>
21#include <linux/libata.h>
21#include <linux/mfd/syscon.h> 22#include <linux/mfd/syscon.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/of_address.h> 24#include <linux/of_address.h>
@@ -94,6 +95,11 @@ enum {
94 PORT_TYPE_SATA = (1U << 0), 95 PORT_TYPE_SATA = (1U << 0),
95}; 96};
96 97
98enum dev_status {
99 HISI_SAS_DEV_INIT,
100 HISI_SAS_DEV_NORMAL,
101};
102
97enum { 103enum {
98 HISI_SAS_INT_ABT_CMD = 0, 104 HISI_SAS_INT_ABT_CMD = 0,
99 HISI_SAS_INT_ABT_DEV = 1, 105 HISI_SAS_INT_ABT_DEV = 1,
@@ -195,6 +201,7 @@ struct hisi_sas_device {
195 struct hisi_sas_dq *dq; 201 struct hisi_sas_dq *dq;
196 struct list_head list; 202 struct list_head list;
197 enum sas_device_type dev_type; 203 enum sas_device_type dev_type;
204 enum dev_status dev_status;
198 int device_id; 205 int device_id;
199 int sata_idx; 206 int sata_idx;
200 spinlock_t lock; /* For protecting slots */ 207 spinlock_t lock; /* For protecting slots */
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index d8204bc3931b..d12924256964 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -708,6 +708,7 @@ static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)
708 708
709 hisi_hba->devices[i].device_id = i; 709 hisi_hba->devices[i].device_id = i;
710 sas_dev = &hisi_hba->devices[i]; 710 sas_dev = &hisi_hba->devices[i];
711 sas_dev->dev_status = HISI_SAS_DEV_INIT;
711 sas_dev->dev_type = device->dev_type; 712 sas_dev->dev_type = device->dev_type;
712 sas_dev->hisi_hba = hisi_hba; 713 sas_dev->hisi_hba = hisi_hba;
713 sas_dev->sas_device = device; 714 sas_dev->sas_device = device;
@@ -732,6 +733,8 @@ static int hisi_sas_init_device(struct domain_device *device)
732 struct hisi_sas_tmf_task tmf_task; 733 struct hisi_sas_tmf_task tmf_task;
733 int retry = HISI_SAS_SRST_ATA_DISK_CNT; 734 int retry = HISI_SAS_SRST_ATA_DISK_CNT;
734 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); 735 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
736 struct device *dev = hisi_hba->dev;
737 struct sas_phy *local_phy;
735 738
736 switch (device->dev_type) { 739 switch (device->dev_type) {
737 case SAS_END_DEVICE: 740 case SAS_END_DEVICE:
@@ -747,6 +750,31 @@ static int hisi_sas_init_device(struct domain_device *device)
747 case SAS_SATA_PM: 750 case SAS_SATA_PM:
748 case SAS_SATA_PM_PORT: 751 case SAS_SATA_PM_PORT:
749 case SAS_SATA_PENDING: 752 case SAS_SATA_PENDING:
753 /*
754 * send HARD RESET to clear previous affiliation of
755 * STP target port
756 */
757 local_phy = sas_get_local_phy(device);
758 if (!scsi_is_sas_phy_local(local_phy)) {
759 unsigned long deadline = ata_deadline(jiffies, 20000);
760 struct sata_device *sata_dev = &device->sata_dev;
761 struct ata_host *ata_host = sata_dev->ata_host;
762 struct ata_port_operations *ops = ata_host->ops;
763 struct ata_port *ap = sata_dev->ap;
764 struct ata_link *link;
765 unsigned int classes;
766
767 ata_for_each_link(link, ap, EDGE)
768 rc = ops->hardreset(link, &classes,
769 deadline);
770 }
771 sas_put_local_phy(local_phy);
772 if (rc) {
773 dev_warn(dev, "SATA disk hardreset fail: 0x%x\n",
774 rc);
775 return rc;
776 }
777
750 while (retry-- > 0) { 778 while (retry-- > 0) {
751 rc = hisi_sas_softreset_ata_disk(device); 779 rc = hisi_sas_softreset_ata_disk(device);
752 if (!rc) 780 if (!rc)
@@ -809,6 +837,7 @@ static int hisi_sas_dev_found(struct domain_device *device)
809 rc = hisi_sas_init_device(device); 837 rc = hisi_sas_init_device(device);
810 if (rc) 838 if (rc)
811 goto err_out; 839 goto err_out;
840 sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
812 return 0; 841 return 0;
813 842
814err_out: 843err_out:
@@ -1715,20 +1744,23 @@ static int hisi_sas_clear_aca(struct domain_device *device, u8 *lun)
1715static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) 1744static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
1716{ 1745{
1717 struct sas_phy *local_phy = sas_get_local_phy(device); 1746 struct sas_phy *local_phy = sas_get_local_phy(device);
1718 int rc, reset_type = (device->dev_type == SAS_SATA_DEV || 1747 struct hisi_sas_device *sas_dev = device->lldd_dev;
1719 (device->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;
1720 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); 1748 struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
1721 struct sas_ha_struct *sas_ha = &hisi_hba->sha; 1749 struct sas_ha_struct *sas_ha = &hisi_hba->sha;
1722 struct asd_sas_phy *sas_phy = sas_ha->sas_phy[local_phy->number]; 1750 struct asd_sas_phy *sas_phy = sas_ha->sas_phy[local_phy->number];
1723 struct hisi_sas_phy *phy = container_of(sas_phy, 1751 struct hisi_sas_phy *phy = container_of(sas_phy,
1724 struct hisi_sas_phy, sas_phy); 1752 struct hisi_sas_phy, sas_phy);
1725 DECLARE_COMPLETION_ONSTACK(phyreset); 1753 DECLARE_COMPLETION_ONSTACK(phyreset);
1754 int rc, reset_type;
1726 1755
1727 if (scsi_is_sas_phy_local(local_phy)) { 1756 if (scsi_is_sas_phy_local(local_phy)) {
1728 phy->in_reset = 1; 1757 phy->in_reset = 1;
1729 phy->reset_completion = &phyreset; 1758 phy->reset_completion = &phyreset;
1730 } 1759 }
1731 1760
1761 reset_type = (sas_dev->dev_status == HISI_SAS_DEV_INIT ||
1762 !dev_is_sata(device)) ? 1 : 0;
1763
1732 rc = sas_phy_reset(local_phy, reset_type); 1764 rc = sas_phy_reset(local_phy, reset_type);
1733 sas_put_local_phy(local_phy); 1765 sas_put_local_phy(local_phy);
1734 1766
@@ -1744,8 +1776,13 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
1744 /* report PHY down if timed out */ 1776 /* report PHY down if timed out */
1745 if (!ret) 1777 if (!ret)
1746 hisi_sas_phy_down(hisi_hba, sas_phy->id, 0); 1778 hisi_sas_phy_down(hisi_hba, sas_phy->id, 0);
1747 } else 1779 } else if (sas_dev->dev_status != HISI_SAS_DEV_INIT) {
1780 /*
1781 * If in init state, we rely on caller to wait for link to be
1782 * ready; otherwise, delay.
1783 */
1748 msleep(2000); 1784 msleep(2000);
1785 }
1749 1786
1750 return rc; 1787 return rc;
1751} 1788}
@@ -2264,6 +2301,7 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba)
2264 for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) { 2301 for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
2265 hisi_hba->devices[i].dev_type = SAS_PHY_UNUSED; 2302 hisi_hba->devices[i].dev_type = SAS_PHY_UNUSED;
2266 hisi_hba->devices[i].device_id = i; 2303 hisi_hba->devices[i].device_id = i;
2304 hisi_hba->devices[i].dev_status = HISI_SAS_DEV_INIT;
2267 } 2305 }
2268 2306
2269 for (i = 0; i < hisi_hba->queue_count; i++) { 2307 for (i = 0; i < hisi_hba->queue_count; i++) {
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index e40cc6b3b67b..89160ab3efb0 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -868,6 +868,7 @@ hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device)
868 868
869 hisi_hba->devices[i].device_id = i; 869 hisi_hba->devices[i].device_id = i;
870 sas_dev = &hisi_hba->devices[i]; 870 sas_dev = &hisi_hba->devices[i];
871 sas_dev->dev_status = HISI_SAS_DEV_INIT;
871 sas_dev->dev_type = device->dev_type; 872 sas_dev->dev_type = device->dev_type;
872 sas_dev->hisi_hba = hisi_hba; 873 sas_dev->hisi_hba = hisi_hba;
873 sas_dev->sas_device = device; 874 sas_dev->sas_device = device;