aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-11-15 20:50:50 -0500
committerTejun Heo <htejun@gmail.com>2006-12-03 03:56:23 -0500
commit3d3cca37559e3ab2b574eda11ed5207ccdb8980a (patch)
treef3f3794cd7d68c681c69e85d50345a22aecc5eac
parent8070217d301d0ceab7d0c255d7b9d796256d37e7 (diff)
[PATCH] libata: implement ATA_FLAG_SETXFER_POLLING and use it in pata_via, take #2
This patch implements ATA_FLAG_SETXFER_POLLING and use in pata_via. If this flag is set, transfer mode setting performed by polling not by interrupt. This should help those controllers which raise interrupt before the command is actually complete on SETXFER. Rationale for this approach. * uses existing facility and relatively simple * no busy sleep in the interrupt handler * updating drivers is easy While at it, kill now unused flag ATA_FLAG_SRST in pata_via. Signed-off-by: Tejun Heo <htejun@gmail.com>
-rw-r--r--drivers/ata/libata-core.c8
-rw-r--r--drivers/ata/pata_via.c12
-rw-r--r--include/linux/libata.h1
3 files changed, 15 insertions, 6 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3fd7c7932707..b35fdcb104ec 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4821,6 +4821,14 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
4821 } 4821 }
4822 } 4822 }
4823 4823
4824 /* Some controllers show flaky interrupt behavior after
4825 * setting xfer mode. Use polling instead.
4826 */
4827 if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES &&
4828 qc->tf.feature == SETFEATURES_XFER) &&
4829 (ap->flags & ATA_FLAG_SETXFER_POLLING))
4830 qc->tf.flags |= ATA_TFLAG_POLLING;
4831
4824 /* select the device */ 4832 /* select the device */
4825 ata_dev_select(ap, qc->dev->devno, 1, 0); 4833 ata_dev_select(ap, qc->dev->devno, 1, 0);
4826 4834
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index ee93dd0169be..a9077b617b8d 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -418,7 +418,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
418 /* Early VIA without UDMA support */ 418 /* Early VIA without UDMA support */
419 static struct ata_port_info via_mwdma_info = { 419 static struct ata_port_info via_mwdma_info = {
420 .sht = &via_sht, 420 .sht = &via_sht,
421 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 421 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
422 .pio_mask = 0x1f, 422 .pio_mask = 0x1f,
423 .mwdma_mask = 0x07, 423 .mwdma_mask = 0x07,
424 .port_ops = &via_port_ops 424 .port_ops = &via_port_ops
@@ -426,7 +426,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
426 /* Ditto with IRQ masking required */ 426 /* Ditto with IRQ masking required */
427 static struct ata_port_info via_mwdma_info_borked = { 427 static struct ata_port_info via_mwdma_info_borked = {
428 .sht = &via_sht, 428 .sht = &via_sht,
429 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 429 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
430 .pio_mask = 0x1f, 430 .pio_mask = 0x1f,
431 .mwdma_mask = 0x07, 431 .mwdma_mask = 0x07,
432 .port_ops = &via_port_ops_noirq, 432 .port_ops = &via_port_ops_noirq,
@@ -434,7 +434,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
434 /* VIA UDMA 33 devices (and borked 66) */ 434 /* VIA UDMA 33 devices (and borked 66) */
435 static struct ata_port_info via_udma33_info = { 435 static struct ata_port_info via_udma33_info = {
436 .sht = &via_sht, 436 .sht = &via_sht,
437 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 437 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
438 .pio_mask = 0x1f, 438 .pio_mask = 0x1f,
439 .mwdma_mask = 0x07, 439 .mwdma_mask = 0x07,
440 .udma_mask = 0x7, 440 .udma_mask = 0x7,
@@ -443,7 +443,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
443 /* VIA UDMA 66 devices */ 443 /* VIA UDMA 66 devices */
444 static struct ata_port_info via_udma66_info = { 444 static struct ata_port_info via_udma66_info = {
445 .sht = &via_sht, 445 .sht = &via_sht,
446 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 446 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
447 .pio_mask = 0x1f, 447 .pio_mask = 0x1f,
448 .mwdma_mask = 0x07, 448 .mwdma_mask = 0x07,
449 .udma_mask = 0x1f, 449 .udma_mask = 0x1f,
@@ -452,7 +452,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
452 /* VIA UDMA 100 devices */ 452 /* VIA UDMA 100 devices */
453 static struct ata_port_info via_udma100_info = { 453 static struct ata_port_info via_udma100_info = {
454 .sht = &via_sht, 454 .sht = &via_sht,
455 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 455 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
456 .pio_mask = 0x1f, 456 .pio_mask = 0x1f,
457 .mwdma_mask = 0x07, 457 .mwdma_mask = 0x07,
458 .udma_mask = 0x3f, 458 .udma_mask = 0x3f,
@@ -461,7 +461,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
461 /* UDMA133 with bad AST (All current 133) */ 461 /* UDMA133 with bad AST (All current 133) */
462 static struct ata_port_info via_udma133_info = { 462 static struct ata_port_info via_udma133_info = {
463 .sht = &via_sht, 463 .sht = &via_sht,
464 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 464 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
465 .pio_mask = 0x1f, 465 .pio_mask = 0x1f,
466 .mwdma_mask = 0x07, 466 .mwdma_mask = 0x07,
467 .udma_mask = 0x7f, /* FIXME: should check north bridge */ 467 .udma_mask = 0x7f, /* FIXME: should check north bridge */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 6013211ac7de..8b57b6a806cc 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -178,6 +178,7 @@ enum {
178 ATA_FLAG_DEBUGMSG = (1 << 13), 178 ATA_FLAG_DEBUGMSG = (1 << 13),
179 ATA_FLAG_DETECT_POLLING = (1 << 14), /* detect device presence by 179 ATA_FLAG_DETECT_POLLING = (1 << 14), /* detect device presence by
180 * polling IDENTIFY */ 180 * polling IDENTIFY */
181 ATA_FLAG_SETXFER_POLLING= (1 << 15), /* use polling for SETXFER */
181 182
182 /* The following flag belongs to ap->pflags but is kept in 183 /* The following flag belongs to ap->pflags but is kept in
183 * ap->flags because it's referenced in many LLDs and will be 184 * ap->flags because it's referenced in many LLDs and will be