Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Tejun Heo and committed by
Jeff Garzik
464cf177 a862b5c8

+10 -16
+4 -9
drivers/ata/libata-core.c
··· 3933 3933 /* set up set-features taskfile */ 3934 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 3939 ata_tf_init(dev, &tf); 3937 3940 tf.command = ATA_CMD_SET_FEATURES; 3938 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 3943 tf.protocol = ATA_PROT_NODATA; 3941 3944 tf.nsect = dev->xfer_mode; 3942 3945 ··· 5416 5413 break; 5417 5414 } 5418 5415 } 5419 - 5420 - /* Some controllers show flaky interrupt behavior after 5421 - * setting xfer mode. Use polling instead. 5422 - */ 5423 - if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES && 5424 - qc->tf.feature == SETFEATURES_XFER) && 5425 - (ap->flags & ATA_FLAG_SETXFER_POLLING)) 5426 - qc->tf.flags |= ATA_TFLAG_POLLING; 5427 5416 5428 5417 /* select the device */ 5429 5418 ata_dev_select(ap, qc->dev->devno, 1, 0);
+6 -6
drivers/ata/pata_via.c
··· 452 452 /* Early VIA without UDMA support */ 453 453 static const struct ata_port_info via_mwdma_info = { 454 454 .sht = &via_sht, 455 - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 455 + .flags = ATA_FLAG_SLAVE_POSS, 456 456 .pio_mask = 0x1f, 457 457 .mwdma_mask = 0x07, 458 458 .port_ops = &via_port_ops ··· 460 460 /* Ditto with IRQ masking required */ 461 461 static const struct ata_port_info via_mwdma_info_borked = { 462 462 .sht = &via_sht, 463 - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 463 + .flags = ATA_FLAG_SLAVE_POSS, 464 464 .pio_mask = 0x1f, 465 465 .mwdma_mask = 0x07, 466 466 .port_ops = &via_port_ops_noirq, ··· 468 468 /* VIA UDMA 33 devices (and borked 66) */ 469 469 static const struct ata_port_info via_udma33_info = { 470 470 .sht = &via_sht, 471 - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 471 + .flags = ATA_FLAG_SLAVE_POSS, 472 472 .pio_mask = 0x1f, 473 473 .mwdma_mask = 0x07, 474 474 .udma_mask = 0x7, ··· 477 477 /* VIA UDMA 66 devices */ 478 478 static const struct ata_port_info via_udma66_info = { 479 479 .sht = &via_sht, 480 - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 480 + .flags = ATA_FLAG_SLAVE_POSS, 481 481 .pio_mask = 0x1f, 482 482 .mwdma_mask = 0x07, 483 483 .udma_mask = 0x1f, ··· 486 486 /* VIA UDMA 100 devices */ 487 487 static const struct ata_port_info via_udma100_info = { 488 488 .sht = &via_sht, 489 - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 489 + .flags = ATA_FLAG_SLAVE_POSS, 490 490 .pio_mask = 0x1f, 491 491 .mwdma_mask = 0x07, 492 492 .udma_mask = 0x3f, ··· 495 495 /* UDMA133 with bad AST (All current 133) */ 496 496 static const struct ata_port_info via_udma133_info = { 497 497 .sht = &via_sht, 498 - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, 498 + .flags = ATA_FLAG_SLAVE_POSS, 499 499 .pio_mask = 0x1f, 500 500 .mwdma_mask = 0x07, 501 501 .udma_mask = 0x7f, /* FIXME: should check north bridge */
-1
include/linux/libata.h
··· 171 171 ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H 172 172 * Register FIS clearing BSY */ 173 173 ATA_FLAG_DEBUGMSG = (1 << 13), 174 - ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */ 175 174 ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */ 176 175 ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */ 177 176 ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */