From 8fdd6417b411b8614315fa191de49775a35aa056 Mon Sep 17 00:00:00 2001 From: Xingui Yang Date: Fri, 13 May 2022 08:34:37 +0000 Subject: [PATCH] scsi: hisi_sas: Fix SAS disk sense info print incorrectly sometimes driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4ZO9V CVE: NA ---------------------------------- Sometimes disk response sense info, but driver print data underflow without sense, and it's not correct. we use scsi_normalize_sense instead of hisi_sas_get_sense_data to parse the sense info. before: data underflow without sense, rsp_code:0xf0, rc:-2. after: data underflow, rsp_code:0x70, sensekey:0x5, ASC:0x21, ASCQ:0x0. Signed-off-by: Xingui Yang Reviewed-by: kang fenglong Signed-off-by: Yongqiang Liu --- drivers/scsi/hisi_sas/hisi_sas.h | 7 +-- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 72 ++++++++------------------ 2 files changed, 23 insertions(+), 56 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 2a70af0191af..f3bb10da8f86 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -572,12 +573,6 @@ struct hisi_sas_slot_dif_buf_table { struct hisi_sas_sge_dif_page sge_dif_page; }; -struct hisi_sas_sense_data { - int sense_key; - int add_sense_code; - int add_sense_code_qua; -}; - extern bool hisi_sas_debugfs_enable; extern struct dentry *hisi_sas_debugfs_dir; extern int skip_bus_flag; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 3c662fa5f6c0..a268a2ec686c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2291,56 +2291,24 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, } } -static int hisi_sas_get_sense_data(struct ssp_response_iu *iu, - struct hisi_sas_sense_data *sense_data) -{ - int rc = 0; - - switch (iu->resp_data[0]) { - case 0x70: - case 0x71: { - if (iu->sense_data_len > 13) { - sense_data->sense_key = (iu->resp_data[2] & 0xF); - sense_data->add_sense_code = iu->resp_data[12]; - sense_data->add_sense_code_qua = iu->resp_data[13]; - } else - rc = -1; - break; - } - case 0x72: - case 0x73: { - if (iu->sense_data_len > 4) { - sense_data->sense_key = (iu->resp_data[1] & 0xF); - sense_data->add_sense_code = iu->resp_data[2]; - sense_data->add_sense_code_qua = iu->resp_data[3]; - } else - rc = -1; - break; - } - default: - rc = -2; - break; - } - - return rc; -} - static int ssp_need_spin_up(struct hisi_sas_slot *slot) { - int rc; - struct hisi_sas_sense_data sense_data; + 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); - rc = hisi_sas_get_sense_data(iu, &sense_data); + sb_len = iu->sense_data_len; + sense_buffer = iu->sense_data; + rc = scsi_normalize_sense(sense_buffer, sb_len, &sshdr); /* * if the SAS disk response with ASC=04h, * ASCQ=11h, host should send NOTIFY primitive. */ - if (rc == 0 && - sense_data.add_sense_code == 0x4 && - sense_data.add_sense_code_qua == 0x11) + if (rc && sshdr.asc == 0x4 && sshdr.ascq == 0x11) return 1; return 0; @@ -2444,22 +2412,26 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) if ((error_info[3] & RX_DATA_LEN_UNDERFLOW_MSK) && (task->task_proto == SAS_PROTOCOL_SSP)) { /*print detail sense info when data underflow happened*/ - int rc; - struct hisi_sas_sense_data sense_data; + 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); - rc = hisi_sas_get_sense_data(iu, &sense_data); - if (!rc) + 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", - iu->resp_data[0], - sense_data.sense_key, - sense_data.add_sense_code, - sense_data.add_sense_code_qua); + sshdr.response_code, + sshdr.sense_key, + sshdr.asc, + sshdr.ascq); else - dev_info(dev, "data underflow without sense, rsp_code:0x%x, rc:%d.\n", - iu->resp_data[0], rc); + dev_info(dev, "data underflow without sense, rsp_code:0x%02x.\n", + iu->resp_data[0]); } if (unlikely(slot->abort)) { sas_task_abort(task); -- GitLab