scsi: hisi_sas: Fix normally completed I/O analysed as failed
authorXingui Yang <yangxingui@huawei.com>
Tue, 11 Jul 2023 03:14:58 +0000 (11:14 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Sep 2023 07:42:50 +0000 (09:42 +0200)
[ Upstream commit f5393a5602cacfda2014e0ff8220e5a7564e7cd1 ]

The PIO read command has no response frame and the struct iu[1024] won't be
filled. I/Os which are normally completed will be treated as failed in
sas_ata_task_done() when iu contains abnormal dirty data.

Consequently ending_fis should not be filled by iu when the response frame
hasn't been written to memory.

Fixes: d380f55503ed ("scsi: hisi_sas: Don't bother clearing status buffer IU in task prep")
Signed-off-by: Xingui Yang <yangxingui@huawei.com>
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Link: https://lore.kernel.org/r/1689045300-44318-2-git-send-email-chenxiang66@hisilicon.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c

index 02575d81afca2cf77ad8a17d39524845a14345f4..50697672146ad473860fdf255b80aabde636e2af 100644 (file)
@@ -2026,6 +2026,11 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba,
        u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type);
        u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type);
        u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type);
+       struct hisi_sas_complete_v2_hdr *complete_queue =
+                       hisi_hba->complete_hdr[slot->cmplt_queue];
+       struct hisi_sas_complete_v2_hdr *complete_hdr =
+                       &complete_queue[slot->cmplt_queue_slot];
+       u32 dw0 = le32_to_cpu(complete_hdr->dw0);
        int error = -1;
 
        if (err_phase == 1) {
@@ -2310,7 +2315,8 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba,
                        break;
                }
                }
-               hisi_sas_sata_done(task, slot);
+               if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
+                       hisi_sas_sata_done(task, slot);
        }
                break;
        default:
@@ -2443,7 +2449,8 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,
        case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
        {
                ts->stat = SAS_SAM_STAT_GOOD;
-               hisi_sas_sata_done(task, slot);
+               if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
+                       hisi_sas_sata_done(task, slot);
                break;
        }
        default:
index 8544c1554f5ff94fd4e9ad9cc6e2ed45e4e7ce5f..c0e74d768716d036e9ad87cc3b443844ed227484 100644 (file)
@@ -2203,7 +2203,8 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
                        ts->stat = SAS_OPEN_REJECT;
                        ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
                }
-               hisi_sas_sata_done(task, slot);
+               if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
+                       hisi_sas_sata_done(task, slot);
                break;
        case SAS_PROTOCOL_SMP:
                ts->stat = SAS_SAM_STAT_CHECK_CONDITION;
@@ -2330,7 +2331,8 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
        case SAS_PROTOCOL_STP:
        case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
                ts->stat = SAS_SAM_STAT_GOOD;
-               hisi_sas_sata_done(task, slot);
+               if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)
+                       hisi_sas_sata_done(task, slot);
                break;
        default:
                ts->stat = SAS_SAM_STAT_CHECK_CONDITION;