Skip to content

Commit

Permalink
libata: add extra internal command
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
axboe authored and htejun committed May 11, 2018
1 parent ba80c3a commit 28361c4
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 25 deletions.
22 changes: 6 additions & 16 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion drivers/ata/libata-eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
15 changes: 7 additions & 8 deletions include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
}

/*
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 28361c4

Please sign in to comment.