]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
libata: add extra internal command
authorJens Axboe <axboe@kernel.dk>
Fri, 11 May 2018 18:51:09 +0000 (12:51 -0600)
committerTejun Heo <tj@kernel.org>
Fri, 11 May 2018 20:10:44 +0000 (13:10 -0700)
Bump the internal tag to 32, instead of stealing the last tag in
our regular command space. This works just fine, since we don't
actually need a separate hardware tag for this. Internal commands
cannot coexist with NCQ commands.

As a bonus, we get rid of the special casing of what tag to use
for the internal command.

This is in preparation for utilizing all 32 commands for normal IO.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Tejun Heo <tj@kernel.org>
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
include/linux/libata.h

index 8fd352d4c19046f799a5c3986f98c478c476fbf3..5e2f679322cc6f7b0343631d3742613247bb77f1 100644 (file)
@@ -1570,7 +1570,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
        u8 command = tf->command;
        int auto_timeout = 0;
        struct ata_queued_cmd *qc;
-       unsigned int tag, preempted_tag;
+       unsigned int preempted_tag;
        u32 preempted_sactive;
        u64 preempted_qc_active;
        int preempted_nr_active_links;
@@ -1588,20 +1588,10 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
        }
 
        /* initialize internal qc */
+       qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL);
 
-       /* XXX: Tag 0 is used for drivers with legacy EH as some
-        * drivers choke if any other tag is given.  This breaks
-        * ata_tag_internal() test for those drivers.  Don't use new
-        * EH stuff without converting to it.
-        */
-       if (ap->ops->error_handler)
-               tag = ATA_TAG_INTERNAL;
-       else
-               tag = 0;
-
-       qc = __ata_qc_from_tag(ap, tag);
-
-       qc->tag = qc->hw_tag = tag;
+       qc->tag = ATA_TAG_INTERNAL;
+       qc->hw_tag = 0;
        qc->scsicmd = NULL;
        qc->ap = ap;
        qc->dev = dev;
@@ -5156,7 +5146,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
 
        qc->flags = 0;
        tag = qc->tag;
-       if (likely(ata_tag_valid(tag))) {
+       if (ata_tag_valid(tag)) {
                qc->tag = ATA_TAG_POISON;
                if (ap->flags & ATA_FLAG_SAS_HOST)
                        ata_sas_free_tag(tag, ap);
@@ -5415,7 +5405,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
                WARN_ON_ONCE(link->sactive);
 
                ap->nr_active_links++;
-               link->active_tag = qc->hw_tag;
+               link->active_tag = qc->tag;
        }
 
        qc->flags |= ATA_QCFLAG_ACTIVE;
index 9f9aad77fbcd91c875f4b2f448d198109e66b478..eadbe26ba3dc3b4ff8954361b240967e5b035d82 100644 (file)
@@ -1057,7 +1057,8 @@ static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link)
        /* we're gonna abort all commands, no need for fast drain */
        ata_eh_set_pending(ap, 0);
 
-       for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+       /* include internal tag in iteration */
+       for (tag = 0; tag <= ATA_MAX_QUEUE; tag++) {
                struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
 
                if (qc && (!link || qc->dev->link == link)) {
index 60ce1ba26fdd822e5174f80730c13e831f1cf3d3..1d026719461b21326448207483b59421ae572209 100644 (file)
@@ -125,9 +125,8 @@ enum {
        LIBATA_MAX_PRD          = ATA_MAX_PRD / 2,
        LIBATA_DUMB_MAX_PRD     = ATA_MAX_PRD / 4,      /* Worst case */
        ATA_DEF_QUEUE           = 1,
-       /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */
        ATA_MAX_QUEUE           = 32,
-       ATA_TAG_INTERNAL        = ATA_MAX_QUEUE - 1,
+       ATA_TAG_INTERNAL        = ATA_MAX_QUEUE,
        ATA_SHORT_PAUSE         = 16,
 
        ATAPI_MAX_DRAIN         = 16 << 10,
@@ -850,7 +849,7 @@ struct ata_port {
        unsigned int            udma_mask;
        unsigned int            cbl;    /* cable type; ATA_CBL_xxx */
 
-       struct ata_queued_cmd   qcmd[ATA_MAX_QUEUE];
+       struct ata_queued_cmd   qcmd[ATA_MAX_QUEUE + 1];
        unsigned long           sas_tag_allocated; /* for sas tag allocation only */
        u64                     qc_active;
        int                     nr_active_links; /* #links with active qcs */
@@ -1486,14 +1485,14 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
                               const char *name);
 #endif
 
-static inline unsigned int ata_tag_valid(unsigned int tag)
+static inline bool ata_tag_internal(unsigned int tag)
 {
-       return (tag < ATA_MAX_QUEUE) ? 1 : 0;
+       return tag == ATA_TAG_INTERNAL;
 }
 
-static inline bool ata_tag_internal(unsigned int tag)
+static inline bool ata_tag_valid(unsigned int tag)
 {
-       return tag == ATA_TAG_INTERNAL;
+       return tag < ATA_MAX_QUEUE || ata_tag_internal(tag);
 }
 
 /*
@@ -1656,7 +1655,7 @@ static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
 static inline struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
                                                       unsigned int tag)
 {
-       if (likely(ata_tag_valid(tag)))
+       if (ata_tag_valid(tag))
                return &ap->qcmd[tag];
        return NULL;
 }