From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 65 ++++++++++++++++++++++---------- 1 files changed, 44 insertions(+), 21 deletions(-) diff --git a/kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index cd41dc0..0d21c64 100644 --- a/kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -392,6 +392,8 @@ #define CMPLT_HDR_ERROR_PHASE_MSK (0xff << CMPLT_HDR_ERROR_PHASE_OFF) #define CMPLT_HDR_RSPNS_XFRD_OFF 10 #define CMPLT_HDR_RSPNS_XFRD_MSK (0x1 << CMPLT_HDR_RSPNS_XFRD_OFF) +#define CMPLT_HDR_RSPNS_GOOD_OFF 11 +#define CMPLT_HDR_RSPNS_GOOD_MSK (0x1 << CMPLT_HDR_RSPNS_GOOD_OFF) #define CMPLT_HDR_ERX_OFF 12 #define CMPLT_HDR_ERX_MSK (0x1 << CMPLT_HDR_ERX_OFF) #define CMPLT_HDR_ABORT_STAT_OFF 13 @@ -464,6 +466,9 @@ #define RX_DATA_LEN_UNDERFLOW_OFF 6 #define RX_DATA_LEN_UNDERFLOW_MSK (1 << RX_DATA_LEN_UNDERFLOW_OFF) + +#define RX_FIS_STATUS_ERR_OFF 0 +#define RX_FIS_STATUS_ERR_MSK (1 << RX_FIS_STATUS_ERR_OFF) #define HISI_SAS_COMMAND_ENTRIES_V3_HW 4096 #define HISI_SAS_MSI_COUNT_V3_HW 32 @@ -2115,7 +2120,7 @@ return IRQ_HANDLED; } -static void +static bool slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot) { @@ -2128,11 +2133,22 @@ hisi_sas_status_buf_addr_mem(slot); u32 dma_rx_err_type = le32_to_cpu(record->dma_rx_err_type); u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type); + u16 sipc_rx_err_type = le16_to_cpu(record->sipc_rx_err_type); u32 dw3 = le32_to_cpu(complete_hdr->dw3); + u32 dw0 = le32_to_cpu(complete_hdr->dw0); switch (task->task_proto) { case SAS_PROTOCOL_SSP: if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { + /* + * If returned response frame is incorrect because of data underflow, + * but I/O information has been written to the host memory, we examine + * response IU. + */ + if (!(dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) && + (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)) + return false; + ts->residual = trans_tx_fail_type; ts->stat = SAS_DATA_UNDERRUN; } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { @@ -2146,7 +2162,10 @@ case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: - if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { + if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && + (sipc_rx_err_type & RX_FIS_STATUS_ERR_MSK)) { + ts->stat = SAS_PROTO_RESPONSE; + } else if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { ts->residual = trans_tx_fail_type; ts->stat = SAS_DATA_UNDERRUN; } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { @@ -2156,14 +2175,16 @@ ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; } - hisi_sas_sata_done(task, slot); + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) + hisi_sas_sata_done(task, slot); break; case SAS_PROTOCOL_SMP: - ts->stat = SAM_STAT_CHECK_CONDITION; + ts->stat = SAS_SAM_STAT_CHECK_CONDITION; break; default: break; } + return true; } static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, @@ -2238,18 +2259,20 @@ if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { u32 *error_info = hisi_sas_status_buf_addr_mem(slot); - slot_err_v3_hw(hisi_hba, task, slot); - if (ts->stat != SAS_DATA_UNDERRUN) - dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", - slot->idx, task, sas_dev->device_id, - dw0, dw1, complete_hdr->act, dw3, - error_info[0], error_info[1], - error_info[2], error_info[3]); - if (unlikely(slot->abort)) { - sas_task_abort(task); - return; + if (slot_err_v3_hw(hisi_hba, task, slot)) { + if (ts->stat != SAS_DATA_UNDERRUN) + dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr=%016llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", + slot->idx, task, sas_dev->device_id, + SAS_ADDR(device->sas_addr), + dw0, dw1, complete_hdr->act, dw3, + error_info[0], error_info[1], + error_info[2], error_info[3]); + if (unlikely(slot->abort)) { + sas_task_abort(task); + return; + } + goto out; } - goto out; } switch (task->task_proto) { @@ -2265,7 +2288,7 @@ struct scatterlist *sg_resp = &task->smp_task.smp_resp; void *to = page_address(sg_page(sg_resp)); - ts->stat = SAM_STAT_GOOD; + ts->stat = SAS_SAM_STAT_GOOD; dma_unmap_sg(dev, &task->smp_task.smp_req, 1, DMA_TO_DEVICE); @@ -2278,11 +2301,12 @@ case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: - ts->stat = SAM_STAT_GOOD; - hisi_sas_sata_done(task, slot); + ts->stat = SAS_SAM_STAT_GOOD; + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) + hisi_sas_sata_done(task, slot); break; default: - ts->stat = SAM_STAT_CHECK_CONDITION; + ts->stat = SAS_SAM_STAT_CHECK_CONDITION; break; } @@ -2402,8 +2426,7 @@ hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW; shost->nr_hw_queues = hisi_hba->cq_nvecs; - devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev); - return 0; + return devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev); } static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) -- Gitblit v1.6.2