Skip to content

Commit 60b3f35

Browse files
Merge patch series "scsi: hisi_sas: Some misc changes"
chenxiang <chenxiang66@hisilicon.com> says: This series contain some fixes including: - Grab sas_dev lock when traversing sas_dev list to avoid NULL pointer - Handle NCQ error when IPTT is valid - Ensure all enabled PHYs up during controller reset - Exit suspend state when usage count of runtime PM is greater than 0 https://lore.kernel.org/r/1679283265-115066-1-git-send-email-chenxiang66@hisilicon.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2 parents 3d2efb5 + e368d38 commit 60b3f35

5 files changed

Lines changed: 124 additions & 35 deletions

File tree

drivers/scsi/hisi_sas/hisi_sas.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,8 @@ extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy,
656656
extern void hisi_sas_phy_bcast(struct hisi_sas_phy *phy);
657657
extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
658658
struct sas_task *task,
659-
struct hisi_sas_slot *slot);
659+
struct hisi_sas_slot *slot,
660+
bool need_lock);
660661
extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba);
661662
extern void hisi_sas_rst_work_handler(struct work_struct *work);
662663
extern void hisi_sas_sync_rst_work_handler(struct work_struct *work);

drivers/scsi/hisi_sas/hisi_sas_main.c

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba,
205205
}
206206

207207
void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
208-
struct hisi_sas_slot *slot)
208+
struct hisi_sas_slot *slot, bool need_lock)
209209
{
210210
int device_id = slot->device_id;
211211
struct hisi_sas_device *sas_dev = &hisi_hba->devices[device_id];
@@ -239,9 +239,13 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
239239
}
240240
}
241241

242-
spin_lock(&sas_dev->lock);
243-
list_del_init(&slot->entry);
244-
spin_unlock(&sas_dev->lock);
242+
if (need_lock) {
243+
spin_lock(&sas_dev->lock);
244+
list_del_init(&slot->entry);
245+
spin_unlock(&sas_dev->lock);
246+
} else {
247+
list_del_init(&slot->entry);
248+
}
245249

246250
memset(slot, 0, offsetof(struct hisi_sas_slot, buf));
247251

@@ -1081,7 +1085,7 @@ static void hisi_sas_port_notify_formed(struct asd_sas_phy *sas_phy)
10811085
}
10821086

10831087
static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, struct sas_task *task,
1084-
struct hisi_sas_slot *slot)
1088+
struct hisi_sas_slot *slot, bool need_lock)
10851089
{
10861090
if (task) {
10871091
unsigned long flags;
@@ -1098,7 +1102,7 @@ static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, struct sas_task
10981102
spin_unlock_irqrestore(&task->task_state_lock, flags);
10991103
}
11001104

1101-
hisi_sas_slot_task_free(hisi_hba, task, slot);
1105+
hisi_sas_slot_task_free(hisi_hba, task, slot, need_lock);
11021106
}
11031107

11041108
static void hisi_sas_release_task(struct hisi_hba *hisi_hba,
@@ -1107,8 +1111,11 @@ static void hisi_sas_release_task(struct hisi_hba *hisi_hba,
11071111
struct hisi_sas_slot *slot, *slot2;
11081112
struct hisi_sas_device *sas_dev = device->lldd_dev;
11091113

1114+
spin_lock(&sas_dev->lock);
11101115
list_for_each_entry_safe(slot, slot2, &sas_dev->list, entry)
1111-
hisi_sas_do_release_task(hisi_hba, slot->task, slot);
1116+
hisi_sas_do_release_task(hisi_hba, slot->task, slot, false);
1117+
1118+
spin_unlock(&sas_dev->lock);
11121119
}
11131120

11141121
void hisi_sas_release_tasks(struct hisi_hba *hisi_hba)
@@ -1513,13 +1520,41 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba)
15131520
}
15141521
EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_prepare);
15151522

1523+
static void hisi_sas_async_init_wait_phyup(void *data, async_cookie_t cookie)
1524+
{
1525+
struct hisi_sas_phy *phy = data;
1526+
struct hisi_hba *hisi_hba = phy->hisi_hba;
1527+
struct device *dev = hisi_hba->dev;
1528+
DECLARE_COMPLETION_ONSTACK(completion);
1529+
int phy_no = phy->sas_phy.id;
1530+
1531+
phy->reset_completion = &completion;
1532+
hisi_sas_phy_enable(hisi_hba, phy_no, 1);
1533+
if (!wait_for_completion_timeout(&completion,
1534+
HISI_SAS_WAIT_PHYUP_TIMEOUT))
1535+
dev_warn(dev, "phy%d wait phyup timed out\n", phy_no);
1536+
1537+
phy->reset_completion = NULL;
1538+
}
1539+
15161540
void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba)
15171541
{
15181542
struct Scsi_Host *shost = hisi_hba->shost;
1543+
ASYNC_DOMAIN_EXCLUSIVE(async);
1544+
int phy_no;
15191545

15201546
/* Init and wait for PHYs to come up and all libsas event finished. */
1521-
hisi_hba->hw->phys_init(hisi_hba);
1522-
msleep(1000);
1547+
for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
1548+
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
1549+
1550+
if (!(hisi_hba->phy_state & BIT(phy_no)))
1551+
continue;
1552+
1553+
async_schedule_domain(hisi_sas_async_init_wait_phyup,
1554+
phy, &async);
1555+
}
1556+
1557+
async_synchronize_full_domain(&async);
15231558
hisi_sas_refresh_port_id(hisi_hba);
15241559
clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
15251560

@@ -1634,7 +1669,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
16341669
*/
16351670
if (rc == TMF_RESP_FUNC_COMPLETE && rc2 != TMF_RESP_FUNC_SUCC) {
16361671
if (task->lldd_task)
1637-
hisi_sas_do_release_task(hisi_hba, task, slot);
1672+
hisi_sas_do_release_task(hisi_hba, task, slot, true);
16381673
}
16391674
} else if (task->task_proto & SAS_PROTOCOL_SATA ||
16401675
task->task_proto & SAS_PROTOCOL_STP) {
@@ -1654,7 +1689,7 @@ static int hisi_sas_abort_task(struct sas_task *task)
16541689
*/
16551690
if ((sas_dev->dev_status == HISI_SAS_DEV_NCQ_ERR) &&
16561691
qc && qc->scsicmd) {
1657-
hisi_sas_do_release_task(hisi_hba, task, slot);
1692+
hisi_sas_do_release_task(hisi_hba, task, slot, true);
16581693
rc = TMF_RESP_FUNC_COMPLETE;
16591694
} else {
16601695
rc = hisi_sas_softreset_ata_disk(device);

drivers/scsi/hisi_sas/hisi_sas_v1_hw.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,7 +1258,11 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba,
12581258

12591259
slot_err_v1_hw(hisi_hba, task, slot);
12601260
if (unlikely(slot->abort)) {
1261-
sas_task_abort(task);
1261+
if (dev_is_sata(device) && task->ata_task.use_ncq)
1262+
sas_ata_device_link_abort(device, true);
1263+
else
1264+
sas_task_abort(task);
1265+
12621266
return;
12631267
}
12641268
goto out;
@@ -1306,7 +1310,7 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba,
13061310
}
13071311

13081312
out:
1309-
hisi_sas_slot_task_free(hisi_hba, task, slot);
1313+
hisi_sas_slot_task_free(hisi_hba, task, slot, true);
13101314

13111315
if (task->task_done)
13121316
task->task_done(task);

drivers/scsi/hisi_sas/hisi_sas_v2_hw.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,7 +2404,11 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,
24042404
error_info[2], error_info[3]);
24052405

24062406
if (unlikely(slot->abort)) {
2407-
sas_task_abort(task);
2407+
if (dev_is_sata(device) && task->ata_task.use_ncq)
2408+
sas_ata_device_link_abort(device, true);
2409+
else
2410+
sas_task_abort(task);
2411+
24082412
return;
24092413
}
24102414
goto out;
@@ -2462,7 +2466,7 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,
24622466
}
24632467
task->task_state_flags |= SAS_TASK_STATE_DONE;
24642468
spin_unlock_irqrestore(&task->task_state_lock, flags);
2465-
hisi_sas_slot_task_free(hisi_hba, task, slot);
2469+
hisi_sas_slot_task_free(hisi_hba, task, slot, true);
24662470

24672471
if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) {
24682472
spin_lock_irqsave(&device->done_lock, flags);

drivers/scsi/hisi_sas/hisi_sas_v3_hw.c

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,27 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
604604
readl_poll_timeout_atomic(regs, val, cond, delay_us, timeout_us);\
605605
})
606606

607+
static void interrupt_enable_v3_hw(struct hisi_hba *hisi_hba)
608+
{
609+
int i;
610+
611+
for (i = 0; i < hisi_hba->queue_count; i++)
612+
hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0);
613+
614+
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe);
615+
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe);
616+
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffc220ff);
617+
hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x155555);
618+
619+
for (i = 0; i < hisi_hba->n_phy; i++) {
620+
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xf2057fff);
621+
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe);
622+
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0);
623+
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0);
624+
hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0);
625+
}
626+
}
627+
607628
static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
608629
{
609630
int i, j;
@@ -624,20 +645,14 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
624645
hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff);
625646
hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff);
626647
hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff);
627-
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe);
628-
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe);
629-
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffc220ff);
630648
hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0);
631649
hisi_sas_write32(hisi_hba, CHNL_ENT_INT_MSK, 0x0);
632650
hisi_sas_write32(hisi_hba, HGC_COM_INT_MSK, 0x0);
633-
hisi_sas_write32(hisi_hba, SAS_ECC_INTR_MSK, 0x155555);
634651
hisi_sas_write32(hisi_hba, AWQOS_AWCACHE_CFG, 0xf0f0);
635652
hisi_sas_write32(hisi_hba, ARQOS_ARCACHE_CFG, 0xf0f0);
636-
for (i = 0; i < hisi_hba->queue_count; i++)
637-
hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0);
638-
639653
hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1);
640654

655+
interrupt_enable_v3_hw(hisi_hba);
641656
for (i = 0; i < hisi_hba->n_phy; i++) {
642657
enum sas_linkrate max;
643658
struct hisi_sas_phy *phy = &hisi_hba->phy[i];
@@ -660,13 +675,8 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
660675
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
661676
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff);
662677
hisi_sas_phy_write32(hisi_hba, i, RXOP_CHECK_CFG_H, 0x1000);
663-
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1_MSK, 0xf2057fff);
664-
hisi_sas_phy_write32(hisi_hba, i, CHL_INT2_MSK, 0xffffbfe);
665678
hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL_RDY_MSK, 0x0);
666-
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_NOT_RDY_MSK, 0x0);
667679
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0);
668-
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0);
669-
hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0);
670680
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x1);
671681
hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120);
672682
hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01);
@@ -888,13 +898,15 @@ static void dereg_device_v3_hw(struct hisi_hba *hisi_hba,
888898

889899
cfg_abt_set_query_iptt = hisi_sas_read32(hisi_hba,
890900
CFG_ABT_SET_QUERY_IPTT);
901+
spin_lock(&sas_dev->lock);
891902
list_for_each_entry_safe(slot, slot2, &sas_dev->list, entry) {
892903
cfg_abt_set_query_iptt &= ~CFG_SET_ABORTED_IPTT_MSK;
893904
cfg_abt_set_query_iptt |= (1 << CFG_SET_ABORTED_EN_OFF) |
894905
(slot->idx << CFG_SET_ABORTED_IPTT_OFF);
895906
hisi_sas_write32(hisi_hba, CFG_ABT_SET_QUERY_IPTT,
896907
cfg_abt_set_query_iptt);
897908
}
909+
spin_unlock(&sas_dev->lock);
898910
cfg_abt_set_query_iptt &= ~(1 << CFG_SET_ABORTED_EN_OFF);
899911
hisi_sas_write32(hisi_hba, CFG_ABT_SET_QUERY_IPTT,
900912
cfg_abt_set_query_iptt);
@@ -2325,7 +2337,11 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
23252337
error_info[0], error_info[1],
23262338
error_info[2], error_info[3]);
23272339
if (unlikely(slot->abort)) {
2328-
sas_task_abort(task);
2340+
if (dev_is_sata(device) && task->ata_task.use_ncq)
2341+
sas_ata_device_link_abort(device, true);
2342+
else
2343+
sas_task_abort(task);
2344+
23292345
return;
23302346
}
23312347
goto out;
@@ -2379,7 +2395,7 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
23792395
}
23802396
task->task_state_flags |= SAS_TASK_STATE_DONE;
23812397
spin_unlock_irqrestore(&task->task_state_lock, flags);
2382-
hisi_sas_slot_task_free(hisi_hba, task, slot);
2398+
hisi_sas_slot_task_free(hisi_hba, task, slot, true);
23832399

23842400
if (!is_internal && (task->task_proto != SAS_PROTOCOL_SMP)) {
23852401
spin_lock_irqsave(&device->done_lock, flags);
@@ -2655,7 +2671,6 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba)
26552671
u32 status, reg_val;
26562672
int rc;
26572673

2658-
interrupt_disable_v3_hw(hisi_hba);
26592674
hisi_sas_sync_poll_cqs(hisi_hba);
26602675
hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0);
26612676

@@ -2686,6 +2701,7 @@ static int soft_reset_v3_hw(struct hisi_hba *hisi_hba)
26862701
struct device *dev = hisi_hba->dev;
26872702
int rc;
26882703

2704+
interrupt_disable_v3_hw(hisi_hba);
26892705
rc = disable_host_v3_hw(hisi_hba);
26902706
if (rc) {
26912707
dev_err(dev, "soft reset: disable host failed rc=%d\n", rc);
@@ -5054,6 +5070,7 @@ static void hisi_sas_reset_prepare_v3_hw(struct pci_dev *pdev)
50545070
set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags);
50555071
hisi_sas_controller_reset_prepare(hisi_hba);
50565072

5073+
interrupt_disable_v3_hw(hisi_hba);
50575074
rc = disable_host_v3_hw(hisi_hba);
50585075
if (rc)
50595076
dev_err(dev, "FLR: disable host failed rc=%d\n", rc);
@@ -5083,6 +5100,21 @@ enum {
50835100
hip08,
50845101
};
50855102

5103+
static void enable_host_v3_hw(struct hisi_hba *hisi_hba)
5104+
{
5105+
u32 reg_val;
5106+
5107+
hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE,
5108+
(u32)((1ULL << hisi_hba->queue_count) - 1));
5109+
5110+
phys_init_v3_hw(hisi_hba);
5111+
reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE +
5112+
AM_CTRL_GLOBAL);
5113+
reg_val &= ~AM_CTRL_SHUTDOWN_REQ_MSK;
5114+
hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE +
5115+
AM_CTRL_GLOBAL, reg_val);
5116+
}
5117+
50865118
static int _suspend_v3_hw(struct device *device)
50875119
{
50885120
struct pci_dev *pdev = to_pci_dev(device);
@@ -5105,14 +5137,18 @@ static int _suspend_v3_hw(struct device *device)
51055137
scsi_block_requests(shost);
51065138
set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
51075139
flush_workqueue(hisi_hba->wq);
5140+
interrupt_disable_v3_hw(hisi_hba);
5141+
5142+
if (atomic_read(&device->power.usage_count)) {
5143+
dev_err(dev, "PM suspend: host status cannot be suspended\n");
5144+
rc = -EBUSY;
5145+
goto err_out;
5146+
}
51085147

51095148
rc = disable_host_v3_hw(hisi_hba);
51105149
if (rc) {
51115150
dev_err(dev, "PM suspend: disable host failed rc=%d\n", rc);
5112-
clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
5113-
clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags);
5114-
scsi_unblock_requests(shost);
5115-
return rc;
5151+
goto err_out_recover_host;
51165152
}
51175153

51185154
hisi_sas_init_mem(hisi_hba);
@@ -5123,6 +5159,15 @@ static int _suspend_v3_hw(struct device *device)
51235159

51245160
dev_warn(dev, "end of suspending controller\n");
51255161
return 0;
5162+
5163+
err_out_recover_host:
5164+
enable_host_v3_hw(hisi_hba);
5165+
err_out:
5166+
interrupt_enable_v3_hw(hisi_hba);
5167+
clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
5168+
clear_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags);
5169+
scsi_unblock_requests(shost);
5170+
return rc;
51265171
}
51275172

51285173
static int _resume_v3_hw(struct device *device)

0 commit comments

Comments
 (0)