Commit 28361c40 authored by Jens Axboe's avatar Jens Axboe Committed by Tejun Heo

libata: add extra internal command

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: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent ba80c3a5
...@@ -1570,7 +1570,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1570,7 +1570,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
u8 command = tf->command; u8 command = tf->command;
int auto_timeout = 0; int auto_timeout = 0;
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
unsigned int tag, preempted_tag; unsigned int preempted_tag;
u32 preempted_sactive; u32 preempted_sactive;
u64 preempted_qc_active; u64 preempted_qc_active;
int preempted_nr_active_links; int preempted_nr_active_links;
...@@ -1588,20 +1588,10 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -1588,20 +1588,10 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
} }
/* initialize internal qc */ /* initialize internal qc */
qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL);
/* XXX: Tag 0 is used for drivers with legacy EH as some qc->tag = ATA_TAG_INTERNAL;
* drivers choke if any other tag is given. This breaks qc->hw_tag = 0;
* 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->scsicmd = NULL; qc->scsicmd = NULL;
qc->ap = ap; qc->ap = ap;
qc->dev = dev; qc->dev = dev;
...@@ -5156,7 +5146,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) ...@@ -5156,7 +5146,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
qc->flags = 0; qc->flags = 0;
tag = qc->tag; tag = qc->tag;
if (likely(ata_tag_valid(tag))) { if (ata_tag_valid(tag)) {
qc->tag = ATA_TAG_POISON; qc->tag = ATA_TAG_POISON;
if (ap->flags & ATA_FLAG_SAS_HOST) if (ap->flags & ATA_FLAG_SAS_HOST)
ata_sas_free_tag(tag, ap); ata_sas_free_tag(tag, ap);
...@@ -5415,7 +5405,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) ...@@ -5415,7 +5405,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
WARN_ON_ONCE(link->sactive); WARN_ON_ONCE(link->sactive);
ap->nr_active_links++; ap->nr_active_links++;
link->active_tag = qc->hw_tag; link->active_tag = qc->tag;
} }
qc->flags |= ATA_QCFLAG_ACTIVE; qc->flags |= ATA_QCFLAG_ACTIVE;
......
...@@ -1057,7 +1057,8 @@ static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link) ...@@ -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 */ /* we're gonna abort all commands, no need for fast drain */
ata_eh_set_pending(ap, 0); 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); struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag);
if (qc && (!link || qc->dev->link == link)) { if (qc && (!link || qc->dev->link == link)) {
......
...@@ -125,9 +125,8 @@ enum { ...@@ -125,9 +125,8 @@ enum {
LIBATA_MAX_PRD = ATA_MAX_PRD / 2, LIBATA_MAX_PRD = ATA_MAX_PRD / 2,
LIBATA_DUMB_MAX_PRD = ATA_MAX_PRD / 4, /* Worst case */ LIBATA_DUMB_MAX_PRD = ATA_MAX_PRD / 4, /* Worst case */
ATA_DEF_QUEUE = 1, ATA_DEF_QUEUE = 1,
/* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */
ATA_MAX_QUEUE = 32, ATA_MAX_QUEUE = 32,
ATA_TAG_INTERNAL = ATA_MAX_QUEUE - 1, ATA_TAG_INTERNAL = ATA_MAX_QUEUE,
ATA_SHORT_PAUSE = 16, ATA_SHORT_PAUSE = 16,
ATAPI_MAX_DRAIN = 16 << 10, ATAPI_MAX_DRAIN = 16 << 10,
...@@ -850,7 +849,7 @@ struct ata_port { ...@@ -850,7 +849,7 @@ struct ata_port {
unsigned int udma_mask; unsigned int udma_mask;
unsigned int cbl; /* cable type; ATA_CBL_xxx */ 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 */ unsigned long sas_tag_allocated; /* for sas tag allocation only */
u64 qc_active; u64 qc_active;
int nr_active_links; /* #links with active qcs */ 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, ...@@ -1486,14 +1485,14 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
const char *name); const char *name);
#endif #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) ...@@ -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, static inline struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap,
unsigned int tag) unsigned int tag)
{ {
if (likely(ata_tag_valid(tag))) if (ata_tag_valid(tag))
return &ap->qcmd[tag]; return &ap->qcmd[tag];
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment