From: Russell King <rmk+lkml@arm.linux.org.uk>
To: linux-ide@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Subject: 2.6.15-rc1: IDE: fix potential data corruption with SL82C105 interfaces
Date: Sat, 12 Nov 2005 16:55:48 +0000 [thread overview]
Message-ID: <20051112165548.GB28987@flint.arm.linux.org.uk> (raw)
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.
Note: due to the urgency of this fix, I will be applying this to the
ARM tree. Any comments/criticisms can be dealt with further patches.
diff -up -x BitKeeper -x ChangeSet -x SCCS -x _xlk -x *.orig -x *.rej -x .git linus/drivers/ide/pci/sl82c105.c linux/drivers/ide/pci/sl82c105.c
--- linus/drivers/ide/pci/sl82c105.c Sun Nov 6 22:16:04 2005
+++ linux/drivers/ide/pci/sl82c105.c Sat Nov 12 16:50:20 2005
@@ -399,34 +399,6 @@ static unsigned int __devinit init_chips
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(
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
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}},
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core
next reply other threads:[~2005-11-12 16:55 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-12 16:55 Russell King [this message]
2005-11-12 18:03 ` 2.6.15-rc1: IDE: fix potential data corruption with SL82C105 interfaces Alan Cox
2005-11-12 17:46 ` Russell King
2006-05-15 14:32 ` Sergei Shtylyov
2006-05-15 15:25 ` Alan Cox
2006-05-15 16:05 ` Sergei Shtylyov
2006-05-15 16:35 ` Alan Cox
2006-05-15 17:10 ` Russell King
2005-11-15 13:27 ` Bartlomiej Zolnierkiewicz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20051112165548.GB28987@flint.arm.linux.org.uk \
--to=rmk+lkml@arm.linux.org.uk \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=linux-ide@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox