diff options
author | Tejun Heo <htejun@gmail.com> | 2007-05-27 15:10:40 +0200 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-06-04 16:48:34 -0400 |
commit | 464cf177df7727efcc5506322fc5d0c8b896f545 (patch) | |
tree | 7b6546aab9c5a7f326ddc27c7a456287172f3c64 /drivers/ata/libata-core.c | |
parent | a862b5c8cd5d847779a049a5fc8cf5b1e6f5fa07 (diff) |
libata: always use polling SETXFER
Several people have reported LITE-ON LTR-48246S detection failed
because SETXFER fails. It seems the device raises IRQ too early after
SETXFER. This is controller independent. The same problem has been
reported for different controllers.
So, now we have pata_via where the controller raises IRQ before it's
ready after SETXFER and a device which does similar thing. This patch
makes libata always execute SETXFER via polling. As this only happens
during EH, performance impact is nil. Setting ATA_TFLAG_POLLING is
also moved from issue hot path to ata_dev_set_xfermode() - the only
place where SETXFER can be issued.
Note that ATA_TFLAG_POLLING applies only to drivers which implement
SFF TF interface and use libata HSM. More advanced controllers ignore
the flag. This doesn't matter for this fix as SFF TF controllers are
the problematic ones.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 13 |
1 files changed, 4 insertions, 9 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index af625147df6..4733f009c7c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3933,10 +3933,13 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) /* set up set-features taskfile */ DPRINTK("set features - xfer mode\n"); + /* Some controllers and ATAPI devices show flaky interrupt + * behavior after setting xfer mode. Use polling instead. + */ ata_tf_init(dev, &tf); tf.command = ATA_CMD_SET_FEATURES; tf.feature = SETFEATURES_XFER; - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_POLLING; tf.protocol = ATA_PROT_NODATA; tf.nsect = dev->xfer_mode; @@ -5414,14 +5417,6 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) } } - /* Some controllers show flaky interrupt behavior after - * setting xfer mode. Use polling instead. - */ - if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES && - qc->tf.feature == SETFEATURES_XFER) && - (ap->flags & ATA_FLAG_SETXFER_POLLING)) - qc->tf.flags |= ATA_TFLAG_POLLING; - /* select the device */ ata_dev_select(ap, qc->dev->devno, 1, 0); |