Skip to content

Commit a351771

Browse files
Merge patch series "scsi: hisi_sas: Some fixes for hisi_sas"
Yihang Li <liyihang9@huawei.com> says: This series contains some fixes including: - Adjust priority of registering and exiting debugfs for security; - Create trigger_dump at the end of the debugfs initialization; - Add firmware information check; - Enable all PHYs that are not disabled by user during controller reset; - Reset PHY again if phyup timeout; - Check usage count only when the runtime PM status is RPM_SUSPENDING; - Add cond_resched() for no forced preemption model; - Default enable interrupt coalescing; - Update disk locked timeout to 7 seconds; - Add time interval between two H2D FIS following soft reset spec; - Update v3 hw STP_LINK_TIMER setting; - Create all dump files during debugfs initialization; - Add latest_dump for the debugfs dump; Link: https://lore.kernel.org/r/20241008021822.2617339-1-liyihang9@huawei.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2 parents a0113b4 + cae6681 commit a351771

5 files changed

Lines changed: 204 additions & 51 deletions

File tree

drivers/scsi/hisi_sas/hisi_sas.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ enum {
307307

308308
struct hisi_sas_hw {
309309
int (*hw_init)(struct hisi_hba *hisi_hba);
310+
int (*fw_info_check)(struct hisi_hba *hisi_hba);
310311
int (*interrupt_preinit)(struct hisi_hba *hisi_hba);
311312
void (*setup_itct)(struct hisi_hba *hisi_hba,
312313
struct hisi_sas_device *device);

drivers/scsi/hisi_sas/hisi_sas_main.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
13211321
}
13221322

13231323
if (rc == TMF_RESP_FUNC_COMPLETE) {
1324+
usleep_range(900, 1000);
13241325
ata_for_each_link(link, ap, EDGE) {
13251326
int pmp = sata_srst_pmp(link);
13261327

@@ -1384,6 +1385,7 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba)
13841385

13851386
static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
13861387
{
1388+
u32 new_state = hisi_hba->hw->get_phys_state(hisi_hba);
13871389
struct asd_sas_port *_sas_port = NULL;
13881390
int phy_no;
13891391

@@ -1397,7 +1399,7 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
13971399
continue;
13981400

13991401
/* Report PHY state change to libsas */
1400-
if (state & BIT(phy_no)) {
1402+
if (new_state & BIT(phy_no)) {
14011403
if (do_port_check && sas_port && sas_port->port_dev) {
14021404
struct domain_device *dev = sas_port->port_dev;
14031405

@@ -1410,6 +1412,16 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
14101412
}
14111413
} else {
14121414
hisi_sas_phy_down(hisi_hba, phy_no, 0, GFP_KERNEL);
1415+
1416+
/*
1417+
* The new_state is not ready but old_state is ready,
1418+
* the two possible causes:
1419+
* 1. The connected device is removed
1420+
* 2. Device exists but phyup timed out
1421+
*/
1422+
if (state & BIT(phy_no))
1423+
hisi_sas_notify_phy_event(phy,
1424+
HISI_PHYE_LINK_RESET);
14131425
}
14141426
}
14151427
}
@@ -1545,9 +1557,15 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba)
15451557
/* Init and wait for PHYs to come up and all libsas event finished. */
15461558
for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
15471559
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
1560+
struct asd_sas_phy *sas_phy = &phy->sas_phy;
15481561

1549-
if (!(hisi_hba->phy_state & BIT(phy_no)))
1562+
if (!sas_phy->phy->enabled)
1563+
continue;
1564+
1565+
if (!(hisi_hba->phy_state & BIT(phy_no))) {
1566+
hisi_sas_phy_enable(hisi_hba, phy_no, 1);
15501567
continue;
1568+
}
15511569

15521570
async_schedule_domain(hisi_sas_async_init_wait_phyup,
15531571
phy, &async);
@@ -2450,6 +2468,11 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev,
24502468
if (hisi_sas_get_fw_info(hisi_hba) < 0)
24512469
goto err_out;
24522470

2471+
if (hisi_hba->hw->fw_info_check) {
2472+
if (hisi_hba->hw->fw_info_check(hisi_hba))
2473+
goto err_out;
2474+
}
2475+
24532476
error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
24542477
if (error) {
24552478
dev_err(dev, "No usable DMA addressing method\n");
@@ -2630,10 +2653,10 @@ static __init int hisi_sas_init(void)
26302653

26312654
static __exit void hisi_sas_exit(void)
26322655
{
2633-
sas_release_transport(hisi_sas_stt);
2634-
26352656
if (hisi_sas_debugfs_enable)
26362657
debugfs_remove(hisi_sas_debugfs_dir);
2658+
2659+
sas_release_transport(hisi_sas_stt);
26372660
}
26382661

26392662
module_init(hisi_sas_init);

drivers/scsi/hisi_sas/hisi_sas_v1_hw.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,23 @@ static struct attribute *host_v1_hw_attrs[] = {
17341734

17351735
ATTRIBUTE_GROUPS(host_v1_hw);
17361736

1737+
static int check_fw_info_v1_hw(struct hisi_hba *hisi_hba)
1738+
{
1739+
struct device *dev = hisi_hba->dev;
1740+
1741+
if (hisi_hba->n_phy < 0 || hisi_hba->n_phy > 9) {
1742+
dev_err(dev, "invalid phy number from FW\n");
1743+
return -EINVAL;
1744+
}
1745+
1746+
if (hisi_hba->queue_count < 0 || hisi_hba->queue_count > 32) {
1747+
dev_err(dev, "invalid queue count from FW\n");
1748+
return -EINVAL;
1749+
}
1750+
1751+
return 0;
1752+
}
1753+
17371754
static const struct scsi_host_template sht_v1_hw = {
17381755
LIBSAS_SHT_BASE_NO_SLAVE_INIT
17391756
.device_configure = hisi_sas_device_configure,
@@ -1747,6 +1764,7 @@ static const struct scsi_host_template sht_v1_hw = {
17471764

17481765
static const struct hisi_sas_hw hisi_sas_v1_hw = {
17491766
.hw_init = hisi_sas_v1_init,
1767+
.fw_info_check = check_fw_info_v1_hw,
17501768
.setup_itct = setup_itct_v1_hw,
17511769
.sl_notify_ssp = sl_notify_ssp_v1_hw,
17521770
.clear_itct = clear_itct_v1_hw,

drivers/scsi/hisi_sas/hisi_sas_v2_hw.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3566,6 +3566,23 @@ static void map_queues_v2_hw(struct Scsi_Host *shost)
35663566
}
35673567
}
35683568

3569+
static int check_fw_info_v2_hw(struct hisi_hba *hisi_hba)
3570+
{
3571+
struct device *dev = hisi_hba->dev;
3572+
3573+
if (hisi_hba->n_phy < 0 || hisi_hba->n_phy > 9) {
3574+
dev_err(dev, "invalid phy number from FW\n");
3575+
return -EINVAL;
3576+
}
3577+
3578+
if (hisi_hba->queue_count < 0 || hisi_hba->queue_count > 16) {
3579+
dev_err(dev, "invalid queue count from FW\n");
3580+
return -EINVAL;
3581+
}
3582+
3583+
return 0;
3584+
}
3585+
35693586
static const struct scsi_host_template sht_v2_hw = {
35703587
LIBSAS_SHT_BASE_NO_SLAVE_INIT
35713588
.device_configure = hisi_sas_device_configure,
@@ -3582,6 +3599,7 @@ static const struct scsi_host_template sht_v2_hw = {
35823599

35833600
static const struct hisi_sas_hw hisi_sas_v2_hw = {
35843601
.hw_init = hisi_sas_v2_init,
3602+
.fw_info_check = check_fw_info_v2_hw,
35853603
.interrupt_preinit = hisi_sas_v2_interrupt_preinit,
35863604
.setup_itct = setup_itct_v2_hw,
35873605
.slot_index_alloc = slot_index_alloc_quirk_v2_hw,

0 commit comments

Comments
 (0)