198 lines
6.8 KiB
Diff
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
|
|
|