aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorShane Huang <shane.huang@amd.com>2010-03-16 06:08:55 -0400
committerJeff Garzik <jgarzik@redhat.com>2010-03-17 15:54:55 -0400
commit5db5b0215af94a36d4bf10900ff9707b6d5c1610 (patch)
tree282907c4f5cc0b9193f2c863351f025f3bc1d1a1 /drivers/ata
parent9deb343189b3cf45e84dd08480f330575ffe2004 (diff)
ahci: pp->active_link is not reliable when FBS is enabled
pp->active_link is not reliable when FBS is enabled. Both PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because mixed NCQ and non-NCQ commands may be in flight. Signed-off-by: Shane Huang <shane.huang@amd.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index e7e2c7a147f1..fdc9bcbe55a2 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -2278,7 +2278,7 @@ static void ahci_port_intr(struct ata_port *ap)
2278 struct ahci_port_priv *pp = ap->private_data; 2278 struct ahci_port_priv *pp = ap->private_data;
2279 struct ahci_host_priv *hpriv = ap->host->private_data; 2279 struct ahci_host_priv *hpriv = ap->host->private_data;
2280 int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); 2280 int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING);
2281 u32 status, qc_active; 2281 u32 status, qc_active = 0;
2282 int rc; 2282 int rc;
2283 2283
2284 status = readl(port_mmio + PORT_IRQ_STAT); 2284 status = readl(port_mmio + PORT_IRQ_STAT);
@@ -2336,11 +2336,22 @@ static void ahci_port_intr(struct ata_port *ap)
2336 } 2336 }
2337 } 2337 }
2338 2338
2339 /* pp->active_link is valid iff any command is in flight */ 2339 /* pp->active_link is not reliable once FBS is enabled, both
2340 if (ap->qc_active && pp->active_link->sactive) 2340 * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because
2341 qc_active = readl(port_mmio + PORT_SCR_ACT); 2341 * NCQ and non-NCQ commands may be in flight at the same time.
2342 else 2342 */
2343 qc_active = readl(port_mmio + PORT_CMD_ISSUE); 2343 if (pp->fbs_enabled) {
2344 if (ap->qc_active) {
2345 qc_active = readl(port_mmio + PORT_SCR_ACT);
2346 qc_active |= readl(port_mmio + PORT_CMD_ISSUE);
2347 }
2348 } else {
2349 /* pp->active_link is valid iff any command is in flight */
2350 if (ap->qc_active && pp->active_link->sactive)
2351 qc_active = readl(port_mmio + PORT_SCR_ACT);
2352 else
2353 qc_active = readl(port_mmio + PORT_CMD_ISSUE);
2354 }
2344 2355
2345 rc = ata_qc_complete_multiple(ap, qc_active); 2356 rc = ata_qc_complete_multiple(ap, qc_active);
2346 2357