提交 8fdd6417 编写于 作者: X Xingui Yang 提交者: Yongqiang Liu

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: NXingui Yang <yangxingui@huawei.com>
Reviewed-by: Nkang fenglong <kangfenglong@huawei.com>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
上级 fec3e16d
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <scsi/scsi_common.h>
#include <scsi/sas_ata.h> #include <scsi/sas_ata.h>
#include <scsi/libsas.h> #include <scsi/libsas.h>
...@@ -572,12 +573,6 @@ struct hisi_sas_slot_dif_buf_table { ...@@ -572,12 +573,6 @@ struct hisi_sas_slot_dif_buf_table {
struct hisi_sas_sge_dif_page sge_dif_page; 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 bool hisi_sas_debugfs_enable;
extern struct dentry *hisi_sas_debugfs_dir; extern struct dentry *hisi_sas_debugfs_dir;
extern int skip_bus_flag; extern int skip_bus_flag;
......
...@@ -2291,56 +2291,24 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, ...@@ -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) static int ssp_need_spin_up(struct hisi_sas_slot *slot)
{ {
int rc; bool rc;
struct hisi_sas_sense_data sense_data; int sb_len;
u8 *sense_buffer;
struct scsi_sense_hdr sshdr;
struct ssp_response_iu *iu = struct ssp_response_iu *iu =
hisi_sas_status_buf_addr_mem(slot) + hisi_sas_status_buf_addr_mem(slot) +
sizeof(struct hisi_sas_err_record); 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, * if the SAS disk response with ASC=04h,
* ASCQ=11h, host should send NOTIFY primitive. * ASCQ=11h, host should send NOTIFY primitive.
*/ */
if (rc == 0 && if (rc && sshdr.asc == 0x4 && sshdr.ascq == 0x11)
sense_data.add_sense_code == 0x4 &&
sense_data.add_sense_code_qua == 0x11)
return 1; return 1;
return 0; return 0;
...@@ -2444,22 +2412,26 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) ...@@ -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) && if ((error_info[3] & RX_DATA_LEN_UNDERFLOW_MSK) &&
(task->task_proto == SAS_PROTOCOL_SSP)) { (task->task_proto == SAS_PROTOCOL_SSP)) {
/*print detail sense info when data underflow happened*/ /*print detail sense info when data underflow happened*/
int rc; bool rc;
struct hisi_sas_sense_data sense_data; int sb_len;
u8 *sense_buffer;
struct scsi_sense_hdr sshdr;
struct ssp_response_iu *iu = struct ssp_response_iu *iu =
hisi_sas_status_buf_addr_mem(slot) + hisi_sas_status_buf_addr_mem(slot) +
sizeof(struct hisi_sas_err_record); 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", dev_info(dev, "data underflow, rsp_code:0x%x, sensekey:0x%x, ASC:0x%x, ASCQ:0x%x.\n",
iu->resp_data[0], sshdr.response_code,
sense_data.sense_key, sshdr.sense_key,
sense_data.add_sense_code, sshdr.asc,
sense_data.add_sense_code_qua); sshdr.ascq);
else else
dev_info(dev, "data underflow without sense, rsp_code:0x%x, rc:%d.\n", dev_info(dev, "data underflow without sense, rsp_code:0x%02x.\n",
iu->resp_data[0], rc); iu->resp_data[0]);
} }
if (unlikely(slot->abort)) { if (unlikely(slot->abort)) {
sas_task_abort(task); sas_task_abort(task);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册