mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 09:19:51 +00:00
ahci: redo stopping DMA engines on empty ports
Commit 96d60303fd
(ahci: Turn off DMA engines when there's no device)
implemented stopping DMA engines on empty ports but it used single
sampling of status registers to determine device presence which led to
disabling of DMA engines on occupied ports. Do it after all EH
actions are complete using device presence state determined by EH.
This avoids spurious disabling of DMA engines and simplifies the code.
Signed-off-by: Tejun Heo <tj@kernel.org>
Tested-by: Marc Dionne <marc.c.dionne@gmail.com>
Cc: Matthew Garrett <mjg@redhat.com>
Cc: Robert Hancock <hancockrwd@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
7a4f876b87
commit
0ee7195272
1 changed files with 3 additions and 18 deletions
|
@ -541,29 +541,11 @@ static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ahci_is_device_present(void __iomem *port_mmio)
|
|
||||||
{
|
|
||||||
u8 status = readl(port_mmio + PORT_TFDATA) & 0xff;
|
|
||||||
|
|
||||||
/* Make sure PxTFD.STS.BSY and PxTFD.STS.DRQ are 0 */
|
|
||||||
if (status & (ATA_BUSY | ATA_DRQ))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Make sure PxSSTS.DET is 3h */
|
|
||||||
status = readl(port_mmio + PORT_SCR_STAT) & 0xf;
|
|
||||||
if (status != 3)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ahci_start_engine(struct ata_port *ap)
|
void ahci_start_engine(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
void __iomem *port_mmio = ahci_port_base(ap);
|
void __iomem *port_mmio = ahci_port_base(ap);
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
if (!ahci_is_device_present(port_mmio))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* start DMA */
|
/* start DMA */
|
||||||
tmp = readl(port_mmio + PORT_CMD);
|
tmp = readl(port_mmio + PORT_CMD);
|
||||||
tmp |= PORT_CMD_START;
|
tmp |= PORT_CMD_START;
|
||||||
|
@ -1892,6 +1874,9 @@ static void ahci_error_handler(struct ata_port *ap)
|
||||||
}
|
}
|
||||||
|
|
||||||
sata_pmp_error_handler(ap);
|
sata_pmp_error_handler(ap);
|
||||||
|
|
||||||
|
if (!ata_dev_enabled(ap->link.device))
|
||||||
|
ahci_stop_engine(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
|
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
|
||||||
|
|
Loading…
Reference in a new issue