04_libata_implement-sactive.patch
This patch implements generic ap->sactive handling for NCQ
commands.
Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>
drivers/scsi/libata-core.c | 37 ++++++++++++++++++++++++-------------
drivers/scsi/libata-scsi.c | 6 +++---
include/linux/libata.h | 5 ++---
3 files changed, 29 insertions(+), 19 deletions(-)
Index: work/drivers/scsi/libata-core.c
===================================================================
--- work.orig/drivers/scsi/libata-core.c 2005-07-07 22:08:35.000000000
+0900
+++ work/drivers/scsi/libata-core.c 2005-07-07 22:08:36.000000000 +0900
@@ -3140,14 +3140,20 @@ void ata_qc_free(struct ata_queued_cmd *
assert(ata_tag_valid(qc->tag));
if (likely(qc->flags & ATA_QCFLAG_ACTIVE)) {
- assert(ap->queue_depth);
- ap->queue_depth--;
+ assert(ap->flags & ATA_FLAG_INFLIGHT);
- if (!ap->queue_depth)
- ap->flags &= ~ATA_FLAG_NCQ_QUEUED;
- if (tag == ap->active_tag) {
+ if (ap->active_tag == ATA_TAG_POISON) {
+ assert(ap->sactive & (1 << tag));
+ ap->sactive &= ~(1 << tag);
+ if (!ap->sactive)
+ ap->flags &= ~ATA_FLAG_INFLIGHT;
+ } else {
+ assert(ap->active_tag == tag &&
+ (qc->flags & ATA_QCFLAG_PREEMPT ||
!ap->sactive));
ap->active_tag = ap->preempted_tag;
ap->preempted_tag = ATA_TAG_POISON;
+ if (ap->active_tag == ATA_TAG_POISON && !ap->sactive)
+ ap->flags &= ~ATA_FLAG_INFLIGHT;
}
}
@@ -3304,7 +3310,7 @@ static inline int ata_qc_issue_ok(struct
/*
* If nothing is queued, it's always ok to continue.
*/
- if (!ap->queue_depth)
+ if (!(ap->flags & ATA_FLAG_INFLIGHT))
return 1;
/*
@@ -3318,7 +3324,7 @@ static inline int ata_qc_issue_ok(struct
* Command is NCQ, allow it to be queued if the commands that are
* currently running are also NCQ
*/
- if (ap->flags & ATA_FLAG_NCQ_QUEUED)
+ if (ap->sactive)
return 1;
return 0;
@@ -3396,20 +3402,25 @@ int ata_qc_issue(struct ata_queued_cmd *
ap->ops->qc_prep(qc);
- qc->ap->active_tag = qc->tag;
qc->flags |= ATA_QCFLAG_ACTIVE;
assert(ap->preempted_tag == ATA_TAG_POISON);
- if (qc->flags & ATA_QCFLAG_PREEMPT) {
+ if (!(qc->flags & ATA_QCFLAG_PREEMPT)) {
+ assert(ap->active_tag == ATA_TAG_POISON);
+
+ if (qc->flags & ATA_QCFLAG_NCQ)
+ ap->sactive |= 1 << qc->tag;
+ else {
+ assert(!ap->sactive);
+ ap->active_tag = qc->tag;
+ }
+ } else {
ap->preempted_tag = ap->active_tag;
ap->active_tag = qc->tag;
}
- if (qc->flags & ATA_QCFLAG_NCQ)
- ap->flags |= ATA_FLAG_NCQ_QUEUED;
-
- ap->queue_depth++;
+ ap->flags |= ATA_FLAG_INFLIGHT;
rc = ap->ops->qc_issue(qc);
if (rc != ATA_QC_ISSUE_OK)
Index: work/drivers/scsi/libata-scsi.c
===================================================================
--- work.orig/drivers/scsi/libata-scsi.c 2005-07-07 22:08:35.000000000
+0900
+++ work/drivers/scsi/libata-scsi.c 2005-07-07 22:08:36.000000000 +0900
@@ -164,10 +164,10 @@ struct ata_queued_cmd *ata_scsi_qc_new(s
return NULL;
if (ap->cmd_waiters)
return NULL;
- if (ap->queue_depth) {
+ if (ap->flags & ATA_FLAG_INFLIGHT) {
if (!scsi_rw_ncq_request(dev, cmd))
return NULL;
- if (!(ap->flags & ATA_FLAG_NCQ_QUEUED))
+ if (!ap->sactive)
return NULL;
}
@@ -517,7 +517,7 @@ int ata_scsi_error(struct Scsi_Host *hos
ap->ops->error_handler(ap);
spin_lock_irq(&ap->host_set->lock);
- assert(!ap->queue_depth && !ap->host->host_busy);
+ assert(!(ap->flags & ATA_FLAG_INFLIGHT) && !ap->host->host_busy);
host->host_failed = 0;
ap->flags &= ~(ATA_FLAG_ERROR | ATA_FLAG_RECOVERY);
if (ap->cmd_waiters)
Index: work/include/linux/libata.h
===================================================================
--- work.orig/include/linux/libata.h 2005-07-07 22:08:35.000000000 +0900
+++ work/include/linux/libata.h 2005-07-07 22:08:36.000000000 +0900
@@ -116,7 +116,7 @@ enum {
ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */
ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */
ATA_FLAG_NCQ = (1 << 9), /* Can do NCQ */
- ATA_FLAG_NCQ_QUEUED = (1 << 10), /* NCQ commands are queued */
+ ATA_FLAG_INFLIGHT = (1 << 10), /* Command(s) in flight */
ATA_FLAG_ERROR = (1 << 11), /* Error met and EH scheduled */
ATA_FLAG_RECOVERY = (1 << 12), /* Recovery in progress */
@@ -323,9 +323,8 @@ struct ata_port {
struct ata_device device[ATA_MAX_DEVICES];
struct ata_queued_cmd qcmd[ATA_MAX_CMDS];
- unsigned long qactive;
+ unsigned long qactive, sactive;
unsigned int active_tag, preempted_tag;
- unsigned int queue_depth;
wait_queue_head_t cmd_wait_queue;
unsigned int cmd_waiters;
-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html