scsi: pm80xx: Set RETFIS when requested by libsas
authorIgor Pylypiv <ipylypiv@google.com>
Sat, 19 Aug 2023 21:30:40 +0000 (14:30 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 21 Aug 2023 21:11:41 +0000 (17:11 -0400)
By default PM80xx HBAs return FIS only when a drive reports an error.
The RETFIS bit forces the controller to populate FIS even when a drive
reports no error.

Signed-off-by: Igor Pylypiv <ipylypiv@google.com>
Link: https://lore.kernel.org/r/20230819213040.1101044-3-ipylypiv@google.com
Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/pm8001/pm8001_hwi.c
drivers/scsi/pm8001/pm8001_hwi.h
drivers/scsi/pm8001/pm80xx_hwi.c
drivers/scsi/pm8001/pm80xx_hwi.h

index 73cd25f..649724a 100644 (file)
@@ -4095,7 +4095,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
        u32 hdr_tag, ncg_tag = 0;
        u64 phys_addr;
        u32 ATAP = 0x0;
-       u32 dir;
+       u32 dir, retfis = 0;
        u32  opc = OPC_INB_SATA_HOST_OPSTART;
 
        memset(&sata_cmd, 0, sizeof(sata_cmd));
@@ -4124,8 +4124,11 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
        sata_cmd.tag = cpu_to_le32(tag);
        sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
        sata_cmd.data_len = cpu_to_le32(task->total_xfer_len);
-       sata_cmd.ncqtag_atap_dir_m =
-               cpu_to_le32(((ncg_tag & 0xff)<<16)|((ATAP & 0x3f) << 10) | dir);
+       if (task->ata_task.return_fis_on_success)
+               retfis = 1;
+       sata_cmd.retfis_ncqtag_atap_dir_m =
+               cpu_to_le32((retfis << 24) | ((ncg_tag & 0xff) << 16) |
+                           ((ATAP & 0x3f) << 10) | dir);
        sata_cmd.sata_fis = task->ata_task.fis;
        if (likely(!task->ata_task.device_control_reg_update))
                sata_cmd.sata_fis.flags |= 0x80;/* C=1: update ATA cmd reg */
index 961d046..fc2127d 100644 (file)
@@ -515,7 +515,7 @@ struct sata_start_req {
        __le32  tag;
        __le32  device_id;
        __le32  data_len;
-       __le32  ncqtag_atap_dir_m;
+       __le32  retfis_ncqtag_atap_dir_m;
        struct host_to_dev_fis  sata_fis;
        u32     reserved1;
        u32     reserved2;
index 39a12ee..a502157 100644 (file)
@@ -4457,7 +4457,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
        u64 phys_addr, end_addr;
        u32 end_addr_high, end_addr_low;
        u32 ATAP = 0x0;
-       u32 dir;
+       u32 dir, retfis = 0;
        u32 opc = OPC_INB_SATA_HOST_OPSTART;
        memset(&sata_cmd, 0, sizeof(sata_cmd));
 
@@ -4487,7 +4487,8 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
        sata_cmd.tag = cpu_to_le32(tag);
        sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
        sata_cmd.data_len = cpu_to_le32(task->total_xfer_len);
-
+       if (task->ata_task.return_fis_on_success)
+               retfis = 1;
        sata_cmd.sata_fis = task->ata_task.fis;
        if (likely(!task->ata_task.device_control_reg_update))
                sata_cmd.sata_fis.flags |= 0x80;/* C=1: update ATA cmd reg */
@@ -4500,12 +4501,10 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
                           "Encryption enabled.Sending Encrypt SATA cmd 0x%x\n",
                           sata_cmd.sata_fis.command);
                opc = OPC_INB_SATA_DIF_ENC_IO;
-
-               /* set encryption bit */
-               sata_cmd.ncqtag_atap_dir_m_dad =
-                       cpu_to_le32(((ncg_tag & 0xff)<<16)|
-                               ((ATAP & 0x3f) << 10) | 0x20 | dir);
-                                                       /* dad (bit 0-1) is 0 */
+               /* set encryption bit; dad (bits 0-1) is 0 */
+               sata_cmd.retfis_ncqtag_atap_dir_m_dad =
+                       cpu_to_le32((retfis << 24) | ((ncg_tag & 0xff) << 16) |
+                                   ((ATAP & 0x3f) << 10) | 0x20 | dir);
                /* fill in PRD (scatter/gather) table, if any */
                if (task->num_scatter > 1) {
                        pm8001_chip_make_sg(task->scatter,
@@ -4568,11 +4567,10 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
                pm8001_dbg(pm8001_ha, IO,
                           "Sending Normal SATA command 0x%x inb %x\n",
                           sata_cmd.sata_fis.command, q_index);
-               /* dad (bit 0-1) is 0 */
-               sata_cmd.ncqtag_atap_dir_m_dad =
-                       cpu_to_le32(((ncg_tag & 0xff)<<16) |
-                                       ((ATAP & 0x3f) << 10) | dir);
-
+               /* dad (bits 0-1) is 0 */
+               sata_cmd.retfis_ncqtag_atap_dir_m_dad =
+                       cpu_to_le32((retfis << 24) | ((ncg_tag & 0xff) << 16) |
+                                   ((ATAP & 0x3f) << 10) | dir);
                /* fill in PRD (scatter/gather) table, if any */
                if (task->num_scatter > 1) {
                        pm8001_chip_make_sg(task->scatter,
index acf6e30..eb8fd37 100644 (file)
@@ -731,7 +731,7 @@ struct sata_start_req {
        __le32  tag;
        __le32  device_id;
        __le32  data_len;
-       __le32  ncqtag_atap_dir_m_dad;
+       __le32  retfis_ncqtag_atap_dir_m_dad;
        struct host_to_dev_fis  sata_fis;
        u32     reserved1;
        u32     reserved2;      /* dword 11. rsvd for normal I/O. */