scsi: hisi_sas: config ATA de-reset as an constrained command for v3 hw
authorXiang Chen <chenxiang66@hisilicon.com>
Wed, 2 May 2018 15:56:31 +0000 (23:56 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 3 Aug 2018 05:50:36 +0000 (07:50 +0200)
[ Upstream commit 9413532788df7470297dd0475995c5dc5b07f362 ]

As a unconstrained command, a command can be sent to SATA disk even if
SATA disk status is BUSY, ERR or DRQ.

If an ATA reset assert is successful but ATA reset de-assert fails, then
it will retry the reset de-assert. If reset de- assert retry is
successful, we think it is okay to probe the device but actually it
still has Err status.

Apparently we need to retry the ATA reset assertion and de- assertion
instead for this mentioned scenario.

As such, we config ATA reset assert as a constrained command, if ATA
reset de-assert fails, then ATA reset de-assert retry will also
fail. Then we will retry the proper process of ATA reset assert and
de-assert again.

Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c

index 2e5fa9717be89acdcc3b1565c0b1c85a5ab089c1..871962b2e2f64df1ae436a5b2ea8b32ca843d925 100644 (file)
@@ -328,10 +328,11 @@ enum {
 #define DIR_TO_DEVICE 2
 #define DIR_RESERVED 3
 
-#define CMD_IS_UNCONSTRAINT(cmd) \
-       ((cmd == ATA_CMD_READ_LOG_EXT) || \
-       (cmd == ATA_CMD_READ_LOG_DMA_EXT) || \
-       (cmd == ATA_CMD_DEV_RESET))
+#define FIS_CMD_IS_UNCONSTRAINED(fis) \
+       ((fis.command == ATA_CMD_READ_LOG_EXT) || \
+       (fis.command == ATA_CMD_READ_LOG_DMA_EXT) || \
+       ((fis.command == ATA_CMD_DEV_RESET) && \
+       ((fis.control & ATA_SRST) != 0)))
 
 static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
 {
@@ -1044,7 +1045,7 @@ static int prep_ata_v3_hw(struct hisi_hba *hisi_hba,
                << CMD_HDR_FRAME_TYPE_OFF;
        dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
 
-       if (CMD_IS_UNCONSTRAINT(task->ata_task.fis.command))
+       if (FIS_CMD_IS_UNCONSTRAINED(task->ata_task.fis))
                dw1 |= 1 << CMD_HDR_UNCON_CMD_OFF;
 
        hdr->dw1 = cpu_to_le32(dw1);