From ea266ba1591d28889645a245e1df6f889c574640 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 17 Feb 2007 02:40:22 +0100 Subject: sl82c105: DMA support fixes Fix a number of issues with the DMA support code: - driver claims support for all SW/MW DMA modes while supporting only MWDMA2; - ide_dma_check() method tries to enable DMA on the "known good" drives which don't support MWDMA2; - ide_dma_on() method upon failure to set drive to MWDMA2 re-tunes already tuned PIO mode and calls ide_dma_off() method instead of returning error; - ide_dma_off() method sets drive->current_speed while it doesn't actually change (only the PIO timings are re-loaded into the chip's registers); - init_hwif() method forcibly sets/resets both "drive DMA capable" bits while this is properly handled by ide_dma_{on,off}() methods being called later... Signed-off-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sl82c105.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'drivers/ide/pci/sl82c105.c') diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 170a26199050..1cb8afe9cb3c 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -164,7 +164,7 @@ static int sl82c105_check_drive (ide_drive_t *drive) return hwif->ide_dma_on(drive); } - if (__ide_dma_good_drive(drive)) + if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) return hwif->ide_dma_on(drive); } while (0); @@ -259,10 +259,8 @@ static int sl82c105_ide_dma_on (ide_drive_t *drive) { DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); - if (config_for_dma(drive)) { - config_for_pio(drive, 4, 0, 0); - return HWIF(drive)->ide_dma_off_quietly(drive); - } + if (config_for_dma(drive)) + return 1; printk(KERN_INFO "%s: DMA enabled\n", drive->name); return __ide_dma_on(drive); } @@ -278,7 +276,6 @@ static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive) if (drive->pio_speed) speed = drive->pio_speed - XFER_PIO_0; config_for_pio(drive, speed, 0, 1); - drive->current_speed = drive->pio_speed; return rc; } @@ -401,11 +398,9 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c /* * Initialise the chip */ - static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { unsigned int rev; - u8 dma_state; DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); @@ -431,7 +426,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) if (!hwif->dma_base) return; - dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60; rev = sl82c105_bridge_revision(hwif->pci_dev); if (rev <= 5) { /* @@ -441,11 +435,8 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", hwif->name, rev); } else { - dma_state |= 0x60; - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; + hwif->mwdma_mask = 0x04; hwif->ide_dma_check = &sl82c105_check_drive; hwif->ide_dma_on = &sl82c105_ide_dma_on; @@ -462,7 +453,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) if (hwif->mate) hwif->serialized = hwif->mate->serialized = 1; } - hwif->OUTB(dma_state, hwif->dma_base + 2); } static ide_pci_device_t sl82c105_chipset __devinitdata = { -- cgit v1.2.3 From 0ecdca26e556eae9668ce6de9554757dddb942ef Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 17 Feb 2007 02:40:25 +0100 Subject: ide: use PIO/MMIO operations directly where possible (v2) This results in smaller/faster/simpler code and allows future optimizations. Also remove no longer needed ide[_mm]_{inl,outl}() and ide_hwif_t.{INL,OUTL}. v2: * updated for scc_pata Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sl82c105.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ide/pci/sl82c105.c') diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 1cb8afe9cb3c..c7025858f237 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -215,7 +215,7 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) * Was DMA enabled? If so, disable it - we're resetting the * host. The IDE layer will be handling the drive for us. */ - val = hwif->INB(dma_base); + val = inb(dma_base); if (val & 1) { outb(val & ~1, dma_base); printk("sl82c105: DMA was enabled\n"); -- cgit v1.2.3 From 3608b5d71a52c053787dbad6af20c25f7e0b75a9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 17 Feb 2007 02:40:26 +0100 Subject: ide: add ide_set_dma() helper (v2) * add ide_set_dma() helper and make ide_hwif_t.ide_dma_check return -1 when DMA needs to be disabled (== need to call ->ide_dma_off_quietly) 0 when DMA needs to be enabled (== need to call ->ide_dma_on) 1 when DMA setting shouldn't be changed * fix IDE code to use ide_set_dma() instead if using ->ide_dma_check directly v2: * updated for scc_pata Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sl82c105.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/ide/pci/sl82c105.c') diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index c7025858f237..27b21e120260 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -161,14 +161,14 @@ static int sl82c105_check_drive (ide_drive_t *drive) if (id->field_valid & 2) { if ((id->dma_mword & hwif->mwdma_mask) || (id->dma_1word & hwif->swdma_mask)) - return hwif->ide_dma_on(drive); + return 0; } if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) - return hwif->ide_dma_on(drive); + return 0; } while (0); - return hwif->ide_dma_off_quietly(drive); + return -1; } /* -- cgit v1.2.3 From 7469aaf6a30f4187ed6de7c0aed5c2dd2d1c2d31 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 17 Feb 2007 02:40:26 +0100 Subject: ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void (v2) * since ide_hwif_t.ide_dma_{host_off,off_quietly} always return '0' make these functions void and while at it drop "ide_" prefix * fix comment for __ide_dma_off_quietly() * make __ide_dma_{host_off,off_quietly,off}() void and drop "__" prefix v2: * while at it rename atiixp_ide_dma_host_off() to atiixp_dma_host_off(), sgiioc4_ide_dma_{host_off,off_quietly}() to sgiioc4_dma_{host_off,off_quietly}() and sl82c105_ide_dma_off_quietly() to sl82c105_dma_off_quietly() [ Noticed by Sergei Shtylyov . ] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sl82c105.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers/ide/pci/sl82c105.c') diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 27b21e120260..3a8a76fc78c7 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -265,19 +265,16 @@ static int sl82c105_ide_dma_on (ide_drive_t *drive) return __ide_dma_on(drive); } -static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive) +static void sl82c105_dma_off_quietly(ide_drive_t *drive) { u8 speed = XFER_PIO_0; - int rc; - - DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name)); - rc = __ide_dma_off_quietly(drive); + DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); + + ide_dma_off_quietly(drive); if (drive->pio_speed) speed = drive->pio_speed - XFER_PIO_0; config_for_pio(drive, speed, 0, 1); - - return rc; } /* @@ -440,7 +437,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) 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->dma_off_quietly = &sl82c105_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; -- cgit v1.2.3