]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
scsi: pm8001: Fix NCQ NON DATA command task initialization
authorDamien Le Moal <damien.lemoal@opensource.wdc.com>
Sun, 20 Feb 2022 03:17:53 +0000 (12:17 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Apr 2022 11:58:11 +0000 (13:58 +0200)
[ Upstream commit aa028141ab0bc62c44a84d42f09db35d82df82a2 ]

In the pm8001_chip_sata_req() and pm80xx_chip_sata_req() functions, all
tasks with a DMA direction of DMA_NONE (no data transfer) are initialized
using the ATAP value 0x04. However, NCQ NON DATA commands, while being
DMA_NONE commands are NCQ commands and need to be initialized using the
value 0x07 for ATAP, similarly to other NCQ commands.

Make sure that NCQ NON DATA command tasks are initialized similarly to
other NCQ commands by also testing the task "use_ncq" field in addition to
the DMA direction. While at it, reorganize the code into a chain of if -
else if - else to avoid useless affectations and debug messages.

Link: https://lore.kernel.org/r/20220220031810.738362-15-damien.lemoal@opensource.wdc.com
Fixes: dbf9bfe61571 ("[SCSI] pm8001: add SAS/SATA HBA driver")
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/pm8001/pm8001_hwi.c
drivers/scsi/pm8001/pm80xx_hwi.c

index 43c2ab90f7114977419c1eb8c7f9e8d9c439ea8a..9d982eb970feaddf7d9991fd1b78c03018616dd9 100644 (file)
@@ -4271,22 +4271,22 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
        u32  opc = OPC_INB_SATA_HOST_OPSTART;
        memset(&sata_cmd, 0, sizeof(sata_cmd));
        circularQ = &pm8001_ha->inbnd_q_tbl[0];
-       if (task->data_dir == DMA_NONE) {
+
+       if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
                ATAP = 0x04;  /* no data*/
                pm8001_dbg(pm8001_ha, IO, "no data\n");
        } else if (likely(!task->ata_task.device_control_reg_update)) {
-               if (task->ata_task.dma_xfer) {
+               if (task->ata_task.use_ncq &&
+                   dev->sata_dev.class != ATA_DEV_ATAPI) {
+                       ATAP = 0x07; /* FPDMA */
+                       pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
+               } else if (task->ata_task.dma_xfer) {
                        ATAP = 0x06; /* DMA */
                        pm8001_dbg(pm8001_ha, IO, "DMA\n");
                } else {
                        ATAP = 0x05; /* PIO*/
                        pm8001_dbg(pm8001_ha, IO, "PIO\n");
                }
-               if (task->ata_task.use_ncq &&
-                       dev->sata_dev.class != ATA_DEV_ATAPI) {
-                       ATAP = 0x07; /* FPDMA */
-                       pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
-               }
        }
        if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) {
                task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
index 0b4261735c03b257b58ad58e5eeee747f0d85e84..4c19691a2bce20309650230de30e4ac69fb0255a 100644 (file)
@@ -4552,22 +4552,21 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
        q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
        circularQ = &pm8001_ha->inbnd_q_tbl[q_index];
 
-       if (task->data_dir == DMA_NONE) {
+       if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
                ATAP = 0x04; /* no data*/
                pm8001_dbg(pm8001_ha, IO, "no data\n");
        } else if (likely(!task->ata_task.device_control_reg_update)) {
-               if (task->ata_task.dma_xfer) {
+               if (task->ata_task.use_ncq &&
+                   dev->sata_dev.class != ATA_DEV_ATAPI) {
+                       ATAP = 0x07; /* FPDMA */
+                       pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
+               } else if (task->ata_task.dma_xfer) {
                        ATAP = 0x06; /* DMA */
                        pm8001_dbg(pm8001_ha, IO, "DMA\n");
                } else {
                        ATAP = 0x05; /* PIO*/
                        pm8001_dbg(pm8001_ha, IO, "PIO\n");
                }
-               if (task->ata_task.use_ncq &&
-                   dev->sata_dev.class != ATA_DEV_ATAPI) {
-                       ATAP = 0x07; /* FPDMA */
-                       pm8001_dbg(pm8001_ha, IO, "FPDMA\n");
-               }
        }
        if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) {
                task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);