diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-11-12 16:57:29 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-11-12 16:57:29 +0000 |
commit | 9648f552f9e08548a3979643b99f14c21c7d8f5b (patch) | |
tree | 56ad9baae4679e1fecdb9ba5a754a57b79332b56 /drivers/ide | |
parent | 6460177f42358a744e110cc583adbe8a36f6aa08 (diff) | |
download | linux-9648f552f9e08548a3979643b99f14c21c7d8f5b.tar.gz linux-9648f552f9e08548a3979643b99f14c21c7d8f5b.tar.bz2 linux-9648f552f9e08548a3979643b99f14c21c7d8f5b.zip |
[ARM] Fix broken sl82c105 DMA prevention
We must _never_ _ever_ on pain of death enable IDE DMA on SL82C105
chipsets where the southbridge revision is <= 5, otherwise data
corruption will occur.
Strangely this used to work, but something has changed in the upper
echelons of the IDE layer to break the hosts decision to deny DMA.
Let's make it crystal clear to the IDE layer that we know best.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/pci/sl82c105.c | 80 |
1 files changed, 36 insertions, 44 deletions
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index ea0806c82be0..6466db5f0170 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -399,34 +399,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c return dev->irq; } -static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base) -{ - unsigned int rev; - u8 dma_state; - - DBG(("init_dma_sl82c105(hwif: ide%d, dma_base: 0x%08x)\n", hwif->index, dma_base)); - - hwif->autodma = 0; - - if (!dma_base) - return; - - dma_state = hwif->INB(dma_base + 2); - rev = sl82c105_bridge_revision(hwif->pci_dev); - if (rev <= 5) { - printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", - hwif->name, rev); - dma_state &= ~0x60; - } else { - dma_state |= 0x60; - if (!noautodma) - hwif->autodma = 1; - } - hwif->OUTB(dma_state, dma_base + 2); - - ide_setup_dma(hwif, dma_base, 8); -} - /* * Initialise the chip */ @@ -434,6 +406,8 @@ static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; + unsigned int rev; + u8 dma_state; u32 val; DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); @@ -455,33 +429,51 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) pci_read_config_dword(dev, 0x40, &val); *((u32 *)&hwif->hwif_data) = val; + hwif->atapi_dma = 0; + hwif->mwdma_mask = 0; + hwif->swdma_mask = 0; + hwif->autodma = 0; + if (!hwif->dma_base) return; - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - + dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60; + rev = sl82c105_bridge_revision(hwif->pci_dev); + if (rev <= 5) { + /* + * Never ever EVER under any circumstances enable + * DMA when the bridge is this old. + */ + printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", + hwif->name, rev); + } else { #ifdef CONFIG_BLK_DEV_IDEDMA - hwif->ide_dma_check = &sl82c105_check_drive; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; - hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; - hwif->dma_start = &sl82c105_ide_dma_start; - hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; + dma_state |= 0x60; + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; + + hwif->ide_dma_check = &sl82c105_check_drive; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; + hwif->dma_start = &sl82c105_ide_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; #endif /* CONFIG_BLK_DEV_IDEDMA */ + } + hwif->OUTB(dma_state, hwif->dma_base + 2); } static ide_pci_device_t sl82c105_chipset __devinitdata = { .name = "W82C105", .init_chipset = init_chipset_sl82c105, .init_hwif = init_hwif_sl82c105, - .init_dma = init_dma_sl82c105, .channels = 2, .autodma = NOAUTODMA, .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, |