scsi: hisi_sas: Modify v3 HW SSP underflow error processing
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>
This commit is contained in:
parent
286ce4c65f
commit
62413199cd
@ -406,6 +406,8 @@
|
||||
#define CMPLT_HDR_ERROR_PHASE_MSK (0xff << CMPLT_HDR_ERROR_PHASE_OFF)
|
||||
#define CMPLT_HDR_RSPNS_XFRD_OFF 10
|
||||
#define CMPLT_HDR_RSPNS_XFRD_MSK (0x1 << CMPLT_HDR_RSPNS_XFRD_OFF)
|
||||
#define CMPLT_HDR_RSPNS_GOOD_OFF 11
|
||||
#define CMPLT_HDR_RSPNS_GOOD_MSK (0x1 << CMPLT_HDR_RSPNS_GOOD_OFF)
|
||||
#define CMPLT_HDR_ERX_OFF 12
|
||||
#define CMPLT_HDR_ERX_MSK (0x1 << CMPLT_HDR_ERX_OFF)
|
||||
#define CMPLT_HDR_ABORT_STAT_OFF 13
|
||||
@ -2140,7 +2142,7 @@ static irqreturn_t fatal_axi_int_v3_hw(int irq_no, void *p)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
|
||||
struct hisi_sas_slot *slot)
|
||||
{
|
||||
@ -2158,6 +2160,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;
|
||||
} else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
|
||||
@ -2189,6 +2200,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
|
||||
@ -2262,19 +2274,20 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
|
||||
if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) {
|
||||
u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
|
||||
|
||||
slot_err_v3_hw(hisi_hba, task, slot);
|
||||
if (ts->stat != SAS_DATA_UNDERRUN)
|
||||
dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr=%016llx 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),
|
||||
dw0, dw1, complete_hdr->act, dw3,
|
||||
error_info[0], error_info[1],
|
||||
error_info[2], error_info[3]);
|
||||
if (unlikely(slot->abort)) {
|
||||
sas_task_abort(task);
|
||||
return;
|
||||
if (slot_err_v3_hw(hisi_hba, task, slot)) {
|
||||
if (ts->stat != SAS_DATA_UNDERRUN)
|
||||
dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr=%016llx 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),
|
||||
dw0, dw1, complete_hdr->act, dw3,
|
||||
error_info[0], error_info[1],
|
||||
error_info[2], error_info[3]);
|
||||
if (unlikely(slot->abort)) {
|
||||
sas_task_abort(task);
|
||||
return;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (task->task_proto) {
|
||||
|
Loading…
Reference in New Issue
Block a user