* [PATCH 1/3] libata: separate out ata_ncq_enabled()
@ 2007-02-20 14:20 Tejun Heo
2007-02-20 14:27 ` [PATCH 2/3] libata: fix ata_scmd_need_defer() Tejun Heo
2007-02-20 16:02 ` [PATCH 1/3] libata: separate out ata_ncq_enabled() Jeff Garzik
0 siblings, 2 replies; 4+ messages in thread
From: Tejun Heo @ 2007-02-20 14:20 UTC (permalink / raw)
To: Jeff Garzik, linux-ide; +Cc: haebler, lkml
Separate out ata_ncq_enabled().
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/ata/libata-core.c | 4 +---
include/linux/libata.h | 15 +++++++++++++++
2 files changed, 16 insertions(+), 3 deletions(-)
Index: work/drivers/ata/libata-core.c
===================================================================
--- work.orig/drivers/ata/libata-core.c
+++ work/drivers/ata/libata-core.c
@@ -311,9 +311,7 @@ int ata_build_rw_tf(struct ata_taskfile
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->flags |= tf_flags;
- if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
- ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ &&
- likely(tag != ATA_TAG_INTERNAL)) {
+ if (ata_ncq_enabled(dev) && likely(tag != ATA_TAG_INTERNAL)) {
/* yay, NCQ */
if (!lba_48_ok(block, n_block))
return -ERANGE;
Index: work/include/linux/libata.h
===================================================================
--- work.orig/include/linux/libata.h
+++ work/include/linux/libata.h
@@ -1026,6 +1026,21 @@ static inline u8 ata_chk_status(struct a
return ap->ops->check_status(ap);
}
+/**
+ * ata_ncq_enabled - Test whether NCQ is enabled
+ * @dev: ATA device to test for
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ *
+ * RETURNS:
+ * 1 if NCQ is enabled for @dev, 0 otherwise.
+ */
+static inline int ata_ncq_enabled(struct ata_device *dev)
+{
+ return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
+ ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ;
+}
/**
* ata_pause - Flush writes and pause 400 nanoseconds.
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/3] libata: fix ata_scmd_need_defer()
2007-02-20 14:20 [PATCH 1/3] libata: separate out ata_ncq_enabled() Tejun Heo
@ 2007-02-20 14:27 ` Tejun Heo
2007-02-20 14:31 ` [PATCH 3/3] libata: fix ata_scsi_change_queue_depth() Tejun Heo
2007-02-20 16:02 ` [PATCH 1/3] libata: separate out ata_ncq_enabled() Jeff Garzik
1 sibling, 1 reply; 4+ messages in thread
From: Tejun Heo @ 2007-02-20 14:27 UTC (permalink / raw)
To: Jeff Garzik, linux-ide; +Cc: haebler, lkml
Fix ata_scmd_need_defer() such that...
* whether NCQ is used or not is exactly determined using the same
criteria as the issue path.
* defer-check is performed in all cases.
This fixes race condition where turning off NCQ on the fly causes
non-NCQ commands sneak into NCQ phase.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/ata/libata-scsi.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
Index: work/drivers/ata/libata-scsi.c
===================================================================
--- work.orig/drivers/ata/libata-scsi.c
+++ work/drivers/ata/libata-scsi.c
@@ -1495,11 +1495,9 @@ static void ata_scsi_qc_complete(struct
static int ata_scmd_need_defer(struct ata_device *dev, int is_io)
{
struct ata_port *ap = dev->ap;
+ int is_ncq = is_io && ata_ncq_enabled(dev);
- if (!(dev->flags & ATA_DFLAG_NCQ))
- return 0;
-
- if (is_io) {
+ if (is_ncq) {
if (!ata_tag_valid(ap->active_tag))
return 0;
} else {
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 3/3] libata: fix ata_scsi_change_queue_depth()
2007-02-20 14:27 ` [PATCH 2/3] libata: fix ata_scmd_need_defer() Tejun Heo
@ 2007-02-20 14:31 ` Tejun Heo
0 siblings, 0 replies; 4+ messages in thread
From: Tejun Heo @ 2007-02-20 14:31 UTC (permalink / raw)
To: Jeff Garzik, linux-ide; +Cc: haebler, lkml
Fix ata_scsi_change_queue_depth() such that...
* NCQ on/off is exactly determined using the same logic as the issue path.
* queue depth is adjusted to 1 if NCQ is not enabled.
* -EINVAL is returned if requested action is ignored due to limitations.
This fixes the bug which allows queue depth to be increased on
blacklisted NCQ hosts/devices.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
drivers/ata/libata-scsi.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
Index: work/drivers/ata/libata-scsi.c
===================================================================
--- work.orig/drivers/ata/libata-scsi.c
+++ work/drivers/ata/libata-scsi.c
@@ -986,29 +986,32 @@ int ata_scsi_change_queue_depth(struct s
struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev;
unsigned long flags;
- int max_depth;
- if (queue_depth < 1)
+ if (queue_depth < 1 || queue_depth == sdev->queue_depth)
return sdev->queue_depth;
dev = ata_scsi_find_dev(ap, sdev);
if (!dev || !ata_dev_enabled(dev))
return sdev->queue_depth;
- max_depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id));
- max_depth = min(ATA_MAX_QUEUE - 1, max_depth);
- if (queue_depth > max_depth)
- queue_depth = max_depth;
-
- scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth);
-
+ /* NCQ enabled? */
spin_lock_irqsave(ap->lock, flags);
- if (queue_depth > 1)
- dev->flags &= ~ATA_DFLAG_NCQ_OFF;
- else
+ dev->flags &= ~ATA_DFLAG_NCQ_OFF;
+ if (queue_depth == 1 || !ata_ncq_enabled(dev)) {
dev->flags |= ATA_DFLAG_NCQ_OFF;
+ queue_depth = 1;
+ }
spin_unlock_irqrestore(ap->lock, flags);
+ /* limit and apply queue depth */
+ queue_depth = min(queue_depth, sdev->host->can_queue);
+ queue_depth = min(queue_depth, ata_id_queue_depth(dev->id));
+ queue_depth = min(queue_depth, ATA_MAX_QUEUE - 1);
+
+ if (sdev->queue_depth == queue_depth)
+ return -EINVAL;
+
+ scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth);
return queue_depth;
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/3] libata: separate out ata_ncq_enabled()
2007-02-20 14:20 [PATCH 1/3] libata: separate out ata_ncq_enabled() Tejun Heo
2007-02-20 14:27 ` [PATCH 2/3] libata: fix ata_scmd_need_defer() Tejun Heo
@ 2007-02-20 16:02 ` Jeff Garzik
1 sibling, 0 replies; 4+ messages in thread
From: Jeff Garzik @ 2007-02-20 16:02 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, haebler, lkml
Tejun Heo wrote:
> Separate out ata_ncq_enabled().
>
> Signed-off-by: Tejun Heo <htejun@gmail.com>
> ---
> drivers/ata/libata-core.c | 4 +---
> include/linux/libata.h | 15 +++++++++++++++
> 2 files changed, 16 insertions(+), 3 deletions(-)
applied 1-3
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-02-20 16:02 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-02-20 14:20 [PATCH 1/3] libata: separate out ata_ncq_enabled() Tejun Heo
2007-02-20 14:27 ` [PATCH 2/3] libata: fix ata_scmd_need_defer() Tejun Heo
2007-02-20 14:31 ` [PATCH 3/3] libata: fix ata_scsi_change_queue_depth() Tejun Heo
2007-02-20 16:02 ` [PATCH 1/3] libata: separate out ata_ncq_enabled() Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).