kernel/patches/0738-scsi-hisi_sas-Modify-v3-HW-SSP-underflow-error-proce.patch

198 lines
6.8 KiB
Diff

From e6d56756c53e62a83a3372e3480bebdd0d01d774 Mon Sep 17 00:00:00 2001
From: Xingui Yang <yangxingui@huawei.com>
Date: Tue, 15 Nov 2022 23:03:44 +0800
Subject: [PATCH 090/108] scsi: hisi_sas: Modify v3 HW SSP underflow error
processing
mainline inclusion
from mainline-v5.18-rc1
commit 62413199cd6d2906c121c2dfa3d7b82fd05f08db
category: feature
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8F84O
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=62413199cd6d2906c121c2dfa3d7b82fd05f08db
----------------------------------------------------------------------
In case of SSP underflow allow the response frame IU to be examined for
setting the response stat value rather than always setting
SAS_DATA_UNDERRUN.
This will mean that we call sas_ssp_task_response() in those scenarios and
may send sense data to upper layer.
Such a condition would be for bad blocks were we just reporting an
underflow error to upper layer, but now the sense data will tell
immediately that the media is faulty.
Link: https://lore.kernel.org/r/1645703489-87194-7-git-send-email-john.garry@huawei.com
Signed-off-by: Xingui Yang <yangxingui@huawei.com>
Signed-off-by: Qi Liu <liuqi115@huawei.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: xiabing <xiabing12@h-partners.com>
Reviewed-by: Xiang Chen <chenxiang66@hisilicon.com>
Reviewed-by: Jason Yan <yanaijie@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
---
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 113 ++++++++++++++-----------
1 file changed, 62 insertions(+), 51 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index adeddff88326..d56bca524f79 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -2333,7 +2333,7 @@ static void set_aborted_iptt(struct hisi_hba *hisi_hba,
1 << CFG_ABT_SET_IPTT_DONE_OFF);
}
-static void
+static bool
slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
struct hisi_sas_slot *slot)
{
@@ -2353,6 +2353,15 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
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 (!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) &&
+ (complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))
+ return false;
+
ts->residual = trans_tx_fail_type;
ts->stat = SAS_DATA_UNDERRUN;
if (!(dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) &&
@@ -2401,6 +2410,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
default:
break;
}
+ return true;
}
static int ssp_need_spin_up(struct hisi_sas_slot *slot)
@@ -2502,61 +2512,62 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
struct hisi_sas_itct *itct = &hisi_hba->itct[device_id];
set_aborted_iptt(hisi_hba, slot);
- slot_err_v3_hw(hisi_hba, task, slot);
- dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr%016llx sas_addr=0x%llx 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), itct->sas_addr,
- dw0, dw1,
- complete_hdr->act, dw3,
- error_info[0], error_info[1],
- error_info[2], error_info[3]);
-
- if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) &&
- (task->task_proto & SAS_PROTOCOL_SATA ||
- task->task_proto & SAS_PROTOCOL_STP)) {
- struct hisi_sas_status_buffer *status_buf =
+ if (slot_err_v3_hw(hisi_hba, task, slot)) {
+ dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr%016llx sas_addr=0x%llx 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), itct->sas_addr,
+ dw0, dw1,
+ complete_hdr->act, dw3,
+ error_info[0], error_info[1],
+ error_info[2], error_info[3]);
+
+ if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) &&
+ (task->task_proto & SAS_PROTOCOL_SATA ||
+ task->task_proto & SAS_PROTOCOL_STP)) {
+ struct hisi_sas_status_buffer *status_buf =
hisi_sas_status_buf_addr_mem(slot);
- u8 *iu = &status_buf->iu[0];
- struct dev_to_host_fis *d2h =
- (struct dev_to_host_fis *)iu;
+ u8 *iu = &status_buf->iu[0];
+ struct dev_to_host_fis *d2h =
+ (struct dev_to_host_fis *)iu;
- dev_info(dev, "sata d2h status 0x%02x, error 0x%02x\n",
- d2h->status, d2h->error);
- }
+ dev_info(dev, "sata d2h status 0x%02x, error 0x%02x\n",
+ d2h->status, d2h->error);
+ }
- if ((error_info[3] & RX_DATA_LEN_UNDERFLOW_MSK) &&
- (task->task_proto == SAS_PROTOCOL_SSP)) {
- /*print detail sense info when data underflow happened*/
- bool rc;
- int sb_len;
- u8 *sense_buffer;
- struct scsi_sense_hdr sshdr;
- struct ssp_response_iu *iu =
- hisi_sas_status_buf_addr_mem(slot) +
- sizeof(struct hisi_sas_err_record);
-
- sb_len = iu->sense_data_len;
- sense_buffer = iu->sense_data;
- rc = scsi_normalize_sense(sense_buffer, sb_len, &sshdr);
- if (rc)
- dev_info(dev, "data underflow, rsp_code:0x%x, sensekey:0x%x, ASC:0x%x, ASCQ:0x%x.\n",
- sshdr.response_code,
- sshdr.sense_key,
- sshdr.asc,
- sshdr.ascq);
- else
- dev_info(dev, "data underflow without sense, rsp_code:0x%02x.\n",
- iu->resp_data[0]);
- }
- if (unlikely(slot->abort)) {
- if (dev_is_sata(device) && task->ata_task.use_ncq)
- hisi_sas_ata_device_link_abort(device);
- else
- sas_task_abort(task);
+ if ((error_info[3] & RX_DATA_LEN_UNDERFLOW_MSK) &&
+ (task->task_proto == SAS_PROTOCOL_SSP)) {
+ /*print detail sense info when data underflow happened*/
+ bool rc;
+ int sb_len;
+ u8 *sense_buffer;
+ struct scsi_sense_hdr sshdr;
+ struct ssp_response_iu *iu =
+ hisi_sas_status_buf_addr_mem(slot) +
+ sizeof(struct hisi_sas_err_record);
+
+ sb_len = iu->sense_data_len;
+ sense_buffer = iu->sense_data;
+ rc = scsi_normalize_sense(sense_buffer, sb_len, &sshdr);
+ if (rc)
+ dev_info(dev, "data underflow, rsp_code:0x%x, sensekey:0x%x, ASC:0x%x, ASCQ:0x%x.\n",
+ sshdr.response_code,
+ sshdr.sense_key,
+ sshdr.asc,
+ sshdr.ascq);
+ else
+ dev_info(dev, "data underflow without sense, rsp_code:0x%02x.\n",
+ iu->resp_data[0]);
+ }
+ if (unlikely(slot->abort)) {
+ if (dev_is_sata(device) && task->ata_task.use_ncq)
+ hisi_sas_ata_device_link_abort(device);
+ else
+ sas_task_abort(task);
- return;
+ return;
+ }
+ goto out;
}
- goto out;
}
switch (task->task_proto) {
--
2.27.0