提交 f7a803ae 编写于 作者: L Luo Jiaxing 提交者: Xie XiuQi

scsi: hisi_sas: fix bug of LM fail to add list which caused by IO release when receive underflow cq

when we unplug the disk with IO running,sas controller will retry IO for
5s. As disk havn't receive any response from initiator for long time ,
it will return underflow to tell controller that initiator response timeout
have happened.

At current handle of receive underflow, we direct release IPTT of io
without clean the residue of IPTT remained at hardware logic.If we
reuse this IPTT and send a new IO to logic before logic clean the
residue,it will cause LM fail to add list.

So we should modify the handle of underflow to avoid directly release
IPTT but to enter error handle base on flag: CMPLT_HDR_IO_IN_TARGET_MSK

And we should enable the verify of Data transfer length for rw IO only,
so we can prevent the generate of underflow cq when scan the disk.
we should ensure not to enter the error handle when inquiry the disk.

For the different command we use to inquiry the SAS(INQUIRY) and SATA
(IDENTIFY DEVICE), underflow will not be report during SATA disk
inquiry, so we only check for rw IO at func:prep_ssp_v3_hw.

BTW, we also add some print to get the sensekey of underflow at
func:slot_complete_v3_hw to help debug.
Signed-off-by: NLuo Jiaxing <luojiaxing@huawei.com>

Feature or Bugfix:Bugfix
Signed-off-by: Nluojiaxing <luojiaxing@huawei.com>
Reviewed-by: Nchenxiang <chenxiang66@hisilicon.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 fdfa3532
...@@ -407,6 +407,13 @@ struct hisi_sas_err_record_v3 { ...@@ -407,6 +407,13 @@ struct hisi_sas_err_record_v3 {
#define HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW 16 #define HISI_SAS_CQ_INT_BASE_VECTORS_V3_HW 16
#define HISI_SAS_IS_RW_CMD(op) \
((op == READ_6) || (op == WRITE_6) || \
(op == READ_10) || (op == WRITE_10) || \
(op == READ_12) || (op == WRITE_12) || \
(op == READ_16) || (op == WRITE_16) || \
(op == READ_32) || (op == WRITE_32))
static bool hisi_sas_intr_conv; static bool hisi_sas_intr_conv;
MODULE_PARM_DESC(intr_conv, "interrupt converge on or off:0 or 1(def=0)"); MODULE_PARM_DESC(intr_conv, "interrupt converge on or off:0 or 1(def=0)");
...@@ -1119,6 +1126,17 @@ static void hisi_sas_fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd, ...@@ -1119,6 +1126,17 @@ static void hisi_sas_fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd,
prot->dw0 |= INCR_LBRT_MSK; prot->dw0 |= INCR_LBRT_MSK;
} }
static u32 set_hdr_vdtl(u8 *cmnd)
{
u32 res;
if (!HISI_SAS_IS_RW_CMD(cmnd[0]))
res = 0 << CMD_HDR_VDTL_OFF;
else
res = 1 << CMD_HDR_VDTL_OFF;
return res;
}
static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot) struct hisi_sas_slot *slot)
{ {
...@@ -1140,11 +1158,11 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, ...@@ -1140,11 +1158,11 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
(priority << CMD_HDR_PRIORITY_OFF) | (priority << CMD_HDR_PRIORITY_OFF) |
(1 << CMD_HDR_CMD_OFF)); /* ssp */ (1 << CMD_HDR_CMD_OFF)); /* ssp */
dw1 = 1 << CMD_HDR_VDTL_OFF;
if (tmf) { if (tmf) {
dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF; dw1 |= 2 << CMD_HDR_FRAME_TYPE_OFF;
dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF; dw1 |= DIR_NO_DATA << CMD_HDR_DIR_OFF;
} else { } else {
dw1 = set_hdr_vdtl(&scsi_cmnd->cmnd[0]);
dw1 |= 1 << CMD_HDR_FRAME_TYPE_OFF; dw1 |= 1 << CMD_HDR_FRAME_TYPE_OFF;
switch (scsi_cmnd->sc_data_direction) { switch (scsi_cmnd->sc_data_direction) {
case DMA_TO_DEVICE: case DMA_TO_DEVICE:
...@@ -1873,17 +1891,10 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, ...@@ -1873,17 +1891,10 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
hisi_hba->complete_hdr[slot->cmplt_queue]; hisi_hba->complete_hdr[slot->cmplt_queue];
struct hisi_sas_complete_v3_hdr *complete_hdr = struct hisi_sas_complete_v3_hdr *complete_hdr =
&complete_queue[slot->cmplt_queue_slot]; &complete_queue[slot->cmplt_queue_slot];
struct hisi_sas_err_record_v3 *record =
hisi_sas_status_buf_addr_mem(slot);
u32 dma_rx_err_type = record->dma_rx_err_type;
u32 trans_tx_fail_type = record->trans_tx_fail_type;
switch (task->task_proto) { switch (task->task_proto) {
case SAS_PROTOCOL_SSP: case SAS_PROTOCOL_SSP:
if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
ts->residual = trans_tx_fail_type;
ts->stat = SAS_DATA_UNDERRUN;
} else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
ts->stat = SAS_QUEUE_FULL; ts->stat = SAS_QUEUE_FULL;
slot->abort = 1; slot->abort = 1;
} else { } else {
...@@ -1894,10 +1905,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, ...@@ -1894,10 +1905,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_SATA:
case SAS_PROTOCOL_STP: case SAS_PROTOCOL_STP:
case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
ts->residual = trans_tx_fail_type;
ts->stat = SAS_DATA_UNDERRUN;
} else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
ts->stat = SAS_PHY_DOWN; ts->stat = SAS_PHY_DOWN;
slot->abort = 1; slot->abort = 1;
} else { } else {
...@@ -1993,6 +2001,13 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) ...@@ -1993,6 +2001,13 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
complete_hdr->act, complete_hdr->dw3, complete_hdr->act, complete_hdr->dw3,
error_info[0], error_info[1], error_info[0], error_info[1],
error_info[2], error_info[3]); error_info[2], error_info[3]);
if (error_info[3] & RX_DATA_LEN_UNDERFLOW_MSK) {
u32 *tmp_err = hisi_sas_status_buf_addr_mem(slot) +
sizeof(struct hisi_sas_err_record);
dev_info(dev, "underflow, sensekey:0x%x, code:0x%x.\n",
((*(tmp_err + 6)) & 0xff0000) >> 16,
((*(tmp_err + 9)) & 0xff));
}
if (unlikely(slot->abort)) if (unlikely(slot->abort))
return ts->stat; return ts->stat;
goto out; goto out;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册