Commit 3d3cca37 authored by Tejun Heo's avatar Tejun Heo

[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: default avatarTejun Heo <htejun@gmail.com>
parent 8070217d
...@@ -4821,6 +4821,14 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) ...@@ -4821,6 +4821,14 @@ 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 */ /* select the device */
ata_dev_select(ap, qc->dev->devno, 1, 0); ata_dev_select(ap, qc->dev->devno, 1, 0);
......
...@@ -418,7 +418,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -418,7 +418,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Early VIA without UDMA support */ /* Early VIA without UDMA support */
static struct ata_port_info via_mwdma_info = { static struct ata_port_info via_mwdma_info = {
.sht = &via_sht, .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f, .pio_mask = 0x1f,
.mwdma_mask = 0x07, .mwdma_mask = 0x07,
.port_ops = &via_port_ops .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,7 +426,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Ditto with IRQ masking required */ /* Ditto with IRQ masking required */
static struct ata_port_info via_mwdma_info_borked = { static struct ata_port_info via_mwdma_info_borked = {
.sht = &via_sht, .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f, .pio_mask = 0x1f,
.mwdma_mask = 0x07, .mwdma_mask = 0x07,
.port_ops = &via_port_ops_noirq, .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,7 +434,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* VIA UDMA 33 devices (and borked 66) */ /* VIA UDMA 33 devices (and borked 66) */
static struct ata_port_info via_udma33_info = { static struct ata_port_info via_udma33_info = {
.sht = &via_sht, .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f, .pio_mask = 0x1f,
.mwdma_mask = 0x07, .mwdma_mask = 0x07,
.udma_mask = 0x7, .udma_mask = 0x7,
...@@ -443,7 +443,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -443,7 +443,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* VIA UDMA 66 devices */ /* VIA UDMA 66 devices */
static struct ata_port_info via_udma66_info = { static struct ata_port_info via_udma66_info = {
.sht = &via_sht, .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f, .pio_mask = 0x1f,
.mwdma_mask = 0x07, .mwdma_mask = 0x07,
.udma_mask = 0x1f, .udma_mask = 0x1f,
...@@ -452,7 +452,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -452,7 +452,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* VIA UDMA 100 devices */ /* VIA UDMA 100 devices */
static struct ata_port_info via_udma100_info = { static struct ata_port_info via_udma100_info = {
.sht = &via_sht, .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f, .pio_mask = 0x1f,
.mwdma_mask = 0x07, .mwdma_mask = 0x07,
.udma_mask = 0x3f, .udma_mask = 0x3f,
...@@ -461,7 +461,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -461,7 +461,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* UDMA133 with bad AST (All current 133) */ /* UDMA133 with bad AST (All current 133) */
static struct ata_port_info via_udma133_info = { static struct ata_port_info via_udma133_info = {
.sht = &via_sht, .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f, .pio_mask = 0x1f,
.mwdma_mask = 0x07, .mwdma_mask = 0x07,
.udma_mask = 0x7f, /* FIXME: should check north bridge */ .udma_mask = 0x7f, /* FIXME: should check north bridge */
......
...@@ -178,6 +178,7 @@ enum { ...@@ -178,6 +178,7 @@ enum {
ATA_FLAG_DEBUGMSG = (1 << 13), ATA_FLAG_DEBUGMSG = (1 << 13),
ATA_FLAG_DETECT_POLLING = (1 << 14), /* detect device presence by ATA_FLAG_DETECT_POLLING = (1 << 14), /* detect device presence by
* polling IDENTIFY */ * polling IDENTIFY */
ATA_FLAG_SETXFER_POLLING= (1 << 15), /* use polling for SETXFER */
/* The following flag belongs to ap->pflags but is kept in /* The following flag belongs to ap->pflags but is kept in
* ap->flags because it's referenced in many LLDs and will be * ap->flags because it's referenced in many LLDs and will be
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment