ata: Handle ATA NCQ NO-DATA commands correctly
authorHannes Reinecke <hare@suse.de>
Thu, 14 Jul 2016 00:05:48 +0000 (09:05 +0900)
committerTejun Heo <tj@kernel.org>
Fri, 15 Jul 2016 12:08:13 +0000 (08:08 -0400)
Add a new taskfile protocol ATA_PROT_NCQ_NODATA to handle
ATA NCQ NO-DATA commands correctly.
And fixup ata_scsi_zbc_out_xlat() to use it.

Signed-off-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Tejun Heo <tj@kernel.org>
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/sata_dwc_460ex.c
include/linux/ata.h
include/linux/libata.h
include/trace/events/libata.h

index 5688b86..d551378 100644 (file)
@@ -2611,7 +2611,8 @@ static void ata_eh_link_report(struct ata_link *link)
                                [ATA_PROT_NODATA]       = "nodata",
                                [ATA_PROT_PIO]          = "pio",
                                [ATA_PROT_DMA]          = "dma",
-                               [ATA_PROT_NCQ]          = "ncq",
+                               [ATA_PROT_NCQ]          = "ncq dma",
+                               [ATA_PROT_NCQ_NODATA]   = "ncq nodata",
                                [ATAPI_PROT_NODATA]     = "nodata",
                                [ATAPI_PROT_PIO]        = "pio",
                                [ATAPI_PROT_DMA]        = "dma",
index 0447a39..901b46a 100644 (file)
@@ -3082,6 +3082,9 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
                goto invalid_fld;
        }
 
+       if (ata_is_ncq(tf->protocol) && (cdb[2] & 0x3) == 0)
+               tf->protocol = ATA_PROT_NCQ_NODATA;
+
        /* enable LBA */
        tf->flags |= ATA_TFLAG_LBA;
 
@@ -3548,7 +3551,7 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc)
 
        if (ata_ncq_enabled(qc->dev) &&
            ata_fpdma_zac_mgmt_out_supported(qc->dev)) {
-               tf->protocol = ATA_PROT_NCQ;
+               tf->protocol = ATA_PROT_NCQ_NODATA;
                tf->command = ATA_CMD_NCQ_NON_DATA;
                tf->hob_nsect = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT;
                tf->nsect = qc->tag << 3;
index 00c2af1..fa1530a 100644 (file)
@@ -290,6 +290,8 @@ static const char *get_prot_descript(u8 protocol)
                return "ATA DMA";
        case ATA_PROT_NCQ:
                return "ATA NCQ";
+       case ATA_PROT_NCQ_NODATA:
+               return "ATA NCQ no data";
        case ATAPI_PROT_NODATA:
                return "ATAPI no data";
        case ATAPI_PROT_PIO:
index d20b1ee..35857d1 100644 (file)
@@ -530,6 +530,7 @@ enum ata_tf_protocols {
        ATA_PROT_PIO,           /* PIO data xfer */
        ATA_PROT_DMA,           /* DMA */
        ATA_PROT_NCQ,           /* NCQ */
+       ATA_PROT_NCQ_NODATA,    /* NCQ no data */
        ATAPI_PROT_NODATA,      /* packet command, no data */
        ATAPI_PROT_PIO,         /* packet command, PIO data xfer*/
        ATAPI_PROT_DMA,         /* packet command with special DMA sauce */
index 4e5a09c..1abd669 100644 (file)
@@ -1053,6 +1053,8 @@ static inline unsigned int ata_prot_flags(u8 prot)
                return ATA_PROT_FLAG_DMA;
        case ATA_PROT_NCQ:
                return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ;
+       case ATA_PROT_NCQ_NODATA:
+               return ATA_PROT_FLAG_NCQ;
        case ATAPI_PROT_NODATA:
                return ATA_PROT_FLAG_ATAPI;
        case ATAPI_PROT_PIO:
index 75fff86..2fbbf99 100644 (file)
                ata_protocol_name(ATA_PROT_PIO),        \
                ata_protocol_name(ATA_PROT_DMA),        \
                ata_protocol_name(ATA_PROT_NCQ),        \
+               ata_protocol_name(ATA_PROT_NCQ_NODATA), \
                ata_protocol_name(ATAPI_PROT_NODATA),   \
                ata_protocol_name(ATAPI_PROT_PIO),      \
                ata_protocol_name(ATAPI_PROT_DMA))