aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-05-27 09:10:40 -0400
committerJeff Garzik <jeff@garzik.org>2007-06-04 16:48:34 -0400
commit464cf177df7727efcc5506322fc5d0c8b896f545 (patch)
tree7b6546aab9c5a7f326ddc27c7a456287172f3c64
parenta862b5c8cd5d847779a049a5fc8cf5b1e6f5fa07 (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>
-rw-r--r--drivers/ata/libata-core.c13
-rw-r--r--drivers/ata/pata_via.c12
-rw-r--r--include/linux/libata.h1
3 files changed, 10 insertions, 16 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index af625147df62..4733f009c7c9 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)
3933 /* set up set-features taskfile */ 3933 /* set up set-features taskfile */
3934 DPRINTK("set features - xfer mode\n"); 3934 DPRINTK("set features - xfer mode\n");
3935 3935
3936 /* Some controllers and ATAPI devices show flaky interrupt
3937 * behavior after setting xfer mode. Use polling instead.
3938 */
3936 ata_tf_init(dev, &tf); 3939 ata_tf_init(dev, &tf);
3937 tf.command = ATA_CMD_SET_FEATURES; 3940 tf.command = ATA_CMD_SET_FEATURES;
3938 tf.feature = SETFEATURES_XFER; 3941 tf.feature = SETFEATURES_XFER;
3939 tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 3942 tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_POLLING;
3940 tf.protocol = ATA_PROT_NODATA; 3943 tf.protocol = ATA_PROT_NODATA;
3941 tf.nsect = dev->xfer_mode; 3944 tf.nsect = dev->xfer_mode;
3942 3945
@@ -5414,14 +5417,6 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
5414 } 5417 }
5415 } 5418 }
5416 5419
5417 /* Some controllers show flaky interrupt behavior after
5418 * setting xfer mode. Use polling instead.
5419 */
5420 if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES &&
5421 qc->tf.feature == SETFEATURES_XFER) &&
5422 (ap->flags & ATA_FLAG_SETXFER_POLLING))
5423 qc->tf.flags |= ATA_TFLAG_POLLING;
5424
5425 /* select the device */ 5420 /* select the device */
5426 ata_dev_select(ap, qc->dev->devno, 1, 0); 5421 ata_dev_select(ap, qc->dev->devno, 1, 0);
5427 5422
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index a8462f1e890b..63eca299c62b 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -452,7 +452,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
452 /* Early VIA without UDMA support */ 452 /* Early VIA without UDMA support */
453 static const struct ata_port_info via_mwdma_info = { 453 static const struct ata_port_info via_mwdma_info = {
454 .sht = &via_sht, 454 .sht = &via_sht,
455 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 455 .flags = ATA_FLAG_SLAVE_POSS,
456 .pio_mask = 0x1f, 456 .pio_mask = 0x1f,
457 .mwdma_mask = 0x07, 457 .mwdma_mask = 0x07,
458 .port_ops = &via_port_ops 458 .port_ops = &via_port_ops
@@ -460,7 +460,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
460 /* Ditto with IRQ masking required */ 460 /* Ditto with IRQ masking required */
461 static const struct ata_port_info via_mwdma_info_borked = { 461 static const struct ata_port_info via_mwdma_info_borked = {
462 .sht = &via_sht, 462 .sht = &via_sht,
463 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 463 .flags = ATA_FLAG_SLAVE_POSS,
464 .pio_mask = 0x1f, 464 .pio_mask = 0x1f,
465 .mwdma_mask = 0x07, 465 .mwdma_mask = 0x07,
466 .port_ops = &via_port_ops_noirq, 466 .port_ops = &via_port_ops_noirq,
@@ -468,7 +468,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
468 /* VIA UDMA 33 devices (and borked 66) */ 468 /* VIA UDMA 33 devices (and borked 66) */
469 static const struct ata_port_info via_udma33_info = { 469 static const struct ata_port_info via_udma33_info = {
470 .sht = &via_sht, 470 .sht = &via_sht,
471 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 471 .flags = ATA_FLAG_SLAVE_POSS,
472 .pio_mask = 0x1f, 472 .pio_mask = 0x1f,
473 .mwdma_mask = 0x07, 473 .mwdma_mask = 0x07,
474 .udma_mask = 0x7, 474 .udma_mask = 0x7,
@@ -477,7 +477,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
477 /* VIA UDMA 66 devices */ 477 /* VIA UDMA 66 devices */
478 static const struct ata_port_info via_udma66_info = { 478 static const struct ata_port_info via_udma66_info = {
479 .sht = &via_sht, 479 .sht = &via_sht,
480 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 480 .flags = ATA_FLAG_SLAVE_POSS,
481 .pio_mask = 0x1f, 481 .pio_mask = 0x1f,
482 .mwdma_mask = 0x07, 482 .mwdma_mask = 0x07,
483 .udma_mask = 0x1f, 483 .udma_mask = 0x1f,
@@ -486,7 +486,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
486 /* VIA UDMA 100 devices */ 486 /* VIA UDMA 100 devices */
487 static const struct ata_port_info via_udma100_info = { 487 static const struct ata_port_info via_udma100_info = {
488 .sht = &via_sht, 488 .sht = &via_sht,
489 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 489 .flags = ATA_FLAG_SLAVE_POSS,
490 .pio_mask = 0x1f, 490 .pio_mask = 0x1f,
491 .mwdma_mask = 0x07, 491 .mwdma_mask = 0x07,
492 .udma_mask = 0x3f, 492 .udma_mask = 0x3f,
@@ -495,7 +495,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
495 /* UDMA133 with bad AST (All current 133) */ 495 /* UDMA133 with bad AST (All current 133) */
496 static const struct ata_port_info via_udma133_info = { 496 static const struct ata_port_info via_udma133_info = {
497 .sht = &via_sht, 497 .sht = &via_sht,
498 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 498 .flags = ATA_FLAG_SLAVE_POSS,
499 .pio_mask = 0x1f, 499 .pio_mask = 0x1f,
500 .mwdma_mask = 0x07, 500 .mwdma_mask = 0x07,
501 .udma_mask = 0x7f, /* FIXME: should check north bridge */ 501 .udma_mask = 0x7f, /* FIXME: should check north bridge */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 85f7b1bd1482..a6a3113120a4 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -171,7 +171,6 @@ enum {
171 ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H 171 ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H
172 * Register FIS clearing BSY */ 172 * Register FIS clearing BSY */
173 ATA_FLAG_DEBUGMSG = (1 << 13), 173 ATA_FLAG_DEBUGMSG = (1 << 13),
174 ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
175 ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */ 174 ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
176 ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */ 175 ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
177 ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */ 176 ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */