diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-07-20 11:21:15 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-07-20 11:21:15 +1000 |
commit | f54da60a37827355523995b28cf1efa9ee9481ec (patch) | |
tree | 2aa08be75302bd826fa97793766f664158d49e1b | |
parent | b59a9124d1fa716377f60d5c583d5542758ca096 (diff) | |
parent | 10d4be2bbb6c017bcbda80fb342dbade51468bc6 (diff) |
Merge commit 'libata/NEXT'
-rw-r--r-- | drivers/ata/libata-eh.c | 6 | ||||
-rw-r--r-- | drivers/ata/sata_sil.c | 13 |
2 files changed, 17 insertions, 2 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 1a07c061f644..fe327821bd00 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -999,7 +999,9 @@ static void __ata_port_freeze(struct ata_port *ap) * ata_port_freeze - abort & freeze port * @ap: ATA port to freeze * - * Abort and freeze @ap. + * Abort and freeze @ap. The freeze operation must be called + * first, because some hardware requires special operations + * before the taskfile registers are accessible. * * LOCKING: * spin_lock_irqsave(host lock) @@ -1013,8 +1015,8 @@ int ata_port_freeze(struct ata_port *ap) WARN_ON(!ap->ops->error_handler); - nr_aborted = ata_port_abort(ap); __ata_port_freeze(ap); + nr_aborted = ata_port_abort(ap); return nr_aborted; } diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 030ec079b184..d41dcebb746a 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -565,6 +565,19 @@ static void sil_freeze(struct ata_port *ap) tmp |= SIL_MASK_IDE0_INT << ap->port_no; writel(tmp, mmio_base + SIL_SYSCFG); readl(mmio_base + SIL_SYSCFG); /* flush */ + + /* Ensure DMA_ENABLE is off. + * + * This is because the controller will not give us access to the + * taskfile registers while a DMA is in progress + */ + iowrite8(ioread8(ap->ioaddr.bmdma_addr) & ~SIL_DMA_ENABLE, + ap->ioaddr.bmdma_addr); + + /* According to ata_bmdma_stop, an HDMA transition requires + * on PIO cycle. But we can't read a taskfile register. + */ + ioread8(ap->ioaddr.bmdma_addr); } static void sil_thaw(struct ata_port *ap) |