* [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup @ 2007-02-13 21:43 Sergei Shtylyov 2007-02-14 19:48 ` Bartlomiej Zolnierkiewicz ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Sergei Shtylyov @ 2007-02-13 21:43 UTC (permalink / raw) To: bzolnier; +Cc: linux-ide, linuxppc-dev Fold the now equivalent code in the ide_dma_check() method into a mere call to ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set and call it from the ide_dma_check() method instead of ide_dma_on(). Also, defer writing the DMA timings to the chip registers until DMA is actually turned on (and do not enable IORDY for DMA). Remove unnecessary code from the init_hwif() method, improve its looks overall, and also rename the driver's ide_dma_check() and dma_start() methods. Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> --- The patch has been actually tested at last. :-) Note that now this driver can be joined to the ide-use-fast-pio patch. drivers/ide/pci/sl82c105.c | 114 +++++++++++++++++---------------------------- 1 files changed, 45 insertions(+), 69 deletions(-) Index: linux-2.6/drivers/ide/pci/sl82c105.c =================================================================== --- linux-2.6.orig/drivers/ide/pci/sl82c105.c +++ linux-2.6/drivers/ide/pci/sl82c105.c @@ -11,6 +11,8 @@ * Merge in Russell's HW workarounds, fix various problems * with the timing registers setup. * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org + * + * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> */ #include <linux/types.h> @@ -114,59 +116,32 @@ static void config_for_pio(ide_drive_t * } /* - * Configure the drive and the chipset for DMA + * Configure the drive for DMA. + * We'll program the chipset only when DMA is actually turned on. */ static int config_for_dma (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - unsigned int reg; - DBG(("config_for_dma(drive:%s)\n", drive->name)); - reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) - return 1; + return 0; - pci_write_config_word(dev, reg, 0x0240); - - return 0; + return ide_dma_enable(drive); } /* - * Check to see if the drive and - * chipset is capable of DMA mode + * Check to see if the drive and chipset are capable of DMA mode. */ - -static int sl82c105_check_drive (ide_drive_t *drive) +static int sl82c105_ide_dma_check (ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); + struct hd_driveid *id = drive->id; - DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); - - do { - struct hd_driveid *id = drive->id; - - if (!drive->autodma) - break; - - if (!id || !(id->capability & 1)) - break; - - /* Consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) - break; + DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); - if (id->field_valid & 2) { - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) - return hwif->ide_dma_on(drive); - } - - if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) - return hwif->ide_dma_on(drive); - } while (0); + if (drive->autodma && (id->capability & 1) && + ide_use_dma(drive) && config_for_dma(drive)) + return hwif->ide_dma_on(drive); return hwif->ide_dma_off_quietly(drive); } @@ -235,7 +210,7 @@ static int sl82c105_ide_dma_lost_irq(ide * The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_ide_dma_start(ide_drive_t *drive) +static void sl82c105_dma_start(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -257,12 +232,18 @@ static int sl82c105_ide_dma_timeout(ide_ static int sl82c105_ide_dma_on (ide_drive_t *drive) { + struct pci_dev *dev = HWIF(drive)->pci_dev; + int rc, reg = 0x44 + drive->dn * 4; + DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); - if (config_for_dma(drive)) - return 1; - printk(KERN_INFO "%s: DMA enabled\n", drive->name); - return __ide_dma_on(drive); + rc = __ide_dma_on(drive); + if (rc == 0) { + pci_write_config_word(dev, reg, 0x0200); + + printk(KERN_INFO "%s: DMA enabled\n", drive->name); + } + return rc; } static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive) @@ -396,7 +377,7 @@ static unsigned int __devinit init_chips } /* - * Initialise the chip + * Initialise IDE channel */ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { @@ -418,11 +399,6 @@ static void __devinit init_hwif_sl82c105 hwif->drives[1].pio_speed = XFER_PIO_0; hwif->drives[1].autotune = 1; - hwif->atapi_dma = 0; - hwif->mwdma_mask = 0; - hwif->swdma_mask = 0; - hwif->autodma = 0; - if (!hwif->dma_base) return; @@ -432,27 +408,27 @@ static void __devinit init_hwif_sl82c105 * 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 { - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; - - 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; - - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; + printk(" %s: Winbond W83C553 bridge revision %d, " + "BM-DMA disabled\n", hwif->name, rev); + return; } + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x04; + + hwif->ide_dma_check = &sl82c105_ide_dma_check; + 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_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; + + if (hwif->mate) + hwif->serialized = hwif->mate->serialized = 1; } static ide_pci_device_t sl82c105_chipset __devinitdata = { ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup 2007-02-13 21:43 [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup Sergei Shtylyov @ 2007-02-14 19:48 ` Bartlomiej Zolnierkiewicz 2007-02-23 16:10 ` [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 2) Sergei Shtylyov 2007-02-23 16:13 ` [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3) Sergei Shtylyov 2 siblings, 0 replies; 10+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2007-02-14 19:48 UTC (permalink / raw) To: Sergei Shtylyov; +Cc: linux-ide, linuxppc-dev On Tuesday 13 February 2007 22:43, Sergei Shtylyov wrote: > Fold the now equivalent code in the ide_dma_check() method into a mere call to > ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set > and call it from the ide_dma_check() method instead of ide_dma_on(). > Also, defer writing the DMA timings to the chip registers until DMA is actually > turned on (and do not enable IORDY for DMA). Remove unnecessary code from the > init_hwif() method, improve its looks overall, and also rename the driver's > ide_dma_check() and dma_start() methods. > > Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> > > --- > The patch has been actually tested at last. :-) > Note that now this driver can be joined to the ide-use-fast-pio patch. applied ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 2) 2007-02-13 21:43 [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup Sergei Shtylyov 2007-02-14 19:48 ` Bartlomiej Zolnierkiewicz @ 2007-02-23 16:10 ` Sergei Shtylyov 2007-02-23 16:13 ` [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3) Sergei Shtylyov 2 siblings, 0 replies; 10+ messages in thread From: Sergei Shtylyov @ 2007-02-23 16:10 UTC (permalink / raw) To: bzolnier; +Cc: linux-ide, linuxppc-dev Fold the now equivalent code in the ide_dma_check() method into a mere call to ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set and call it from the ide_dma_check() method instead of ide_dma_on(). Also, defer writing the DMA timings to the chip registers until DMA is actually turned on (and do not enable IORDY for DMA). Remove unnecessary code from the init_hwif() method, improve its looks overall, and also rename the driver's ide_dma_check() and dma_start() methods. --- This version takes into account that the ide-use-fast-pio.patch had been merged to mainline... Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> drivers/ide/pci/sl82c105.c | 112 ++++++++++++++++----------------------------- 1 files changed, 41 insertions(+), 71 deletions(-) Index: linux-2.6/drivers/ide/pci/sl82c105.c =================================================================== --- linux-2.6.orig/drivers/ide/pci/sl82c105.c +++ linux-2.6/drivers/ide/pci/sl82c105.c @@ -11,6 +11,8 @@ * Merge in Russell's HW workarounds, fix various problems * with the timing registers setup. * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org + * + * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> */ #include <linux/types.h> @@ -115,59 +117,28 @@ static void sl82c105_tune_drive(ide_driv } /* - * Configure the drive and the chipset for DMA ++ * Configure the drive for DMA. ++ * We'll program the chipset only when DMA is actually turned on. */ static int config_for_dma (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - unsigned int reg; - DBG(("config_for_dma(drive:%s)\n", drive->name)); - reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) - return 1; - - pci_write_config_word(dev, reg, 0x0240); + return 0; - return 0; + return ide_dma_enable(drive); } /* - * Check to see if the drive and - * chipset is capable of DMA mode + * Check to see if the drive and chipset are capable of DMA mode. */ - -static int sl82c105_check_drive (ide_drive_t *drive) +static int sl82c105_ide_dma_check (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - - DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); - - do { - struct hd_driveid *id = drive->id; - - if (!drive->autodma) - break; + DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); - if (!id || !(id->capability & 1)) - break; - - /* Consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) - break; - - if (id->field_valid & 2) { - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) - return 0; - } - - if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) - return 0; - } while (0); + if (ide_use_dma(drive) && config_for_dma(drive)) + return 0; return -1; } @@ -236,7 +207,7 @@ static int sl82c105_ide_dma_lost_irq(ide * The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_ide_dma_start(ide_drive_t *drive) +static void sl82c105_dma_start(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -258,12 +229,18 @@ static int sl82c105_ide_dma_timeout(ide_ static int sl82c105_ide_dma_on (ide_drive_t *drive) { + struct pci_dev *dev = HWIF(drive)->pci_dev; + int rc, reg = 0x44 + drive->dn * 4; + DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); - if (config_for_dma(drive)) - return 1; - printk(KERN_INFO "%s: DMA enabled\n", drive->name); - return __ide_dma_on(drive); + rc = __ide_dma_on(drive); + if (rc == 0) { + pci_write_config_word(dev, reg, 0x0200); + + printk(KERN_INFO "%s: DMA enabled\n", drive->name); + } + return rc; } static void sl82c105_dma_off_quietly(ide_drive_t *drive) @@ -376,7 +353,7 @@ static unsigned int __devinit init_chips } /* - * Initialise the chip + * Initialise IDE channel */ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { @@ -396,11 +373,6 @@ static void __devinit init_hwif_sl82c105 hwif->drives[0].drive_data = hwif->drives[1].drive_data = 0x0909; hwif->drives[0].autotune = hwif->drives[1].autotune = 1; - hwif->atapi_dma = 0; - hwif->mwdma_mask = 0; - hwif->swdma_mask = 0; - hwif->autodma = 0; - if (!hwif->dma_base) return; @@ -410,27 +382,27 @@ static void __devinit init_hwif_sl82c105 * 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 { - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; - - hwif->ide_dma_check = &sl82c105_check_drive; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - 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; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; - - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; + printk(" %s: Winbond W83C553 bridge revision %d, " + "BM-DMA disabled\n", hwif->name, rev); + return; } + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x04; + + hwif->ide_dma_check = &sl82c105_ide_dma_check; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->dma_off_quietly = &sl82c105_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; + hwif->dma_start = &sl82c105_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; + + if (hwif->mate) + hwif->serialized = hwif->mate->serialized = 1; } static ide_pci_device_t sl82c105_chipset __devinitdata = { ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3) 2007-02-13 21:43 [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup Sergei Shtylyov 2007-02-14 19:48 ` Bartlomiej Zolnierkiewicz 2007-02-23 16:10 ` [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 2) Sergei Shtylyov @ 2007-02-23 16:13 ` Sergei Shtylyov 2007-02-23 23:42 ` Bartlomiej Zolnierkiewicz ` (2 more replies) 2 siblings, 3 replies; 10+ messages in thread From: Sergei Shtylyov @ 2007-02-23 16:13 UTC (permalink / raw) To: bzolnier; +Cc: linux-ide, linuxppc-dev Fold the now equivalent code in the ide_dma_check() method into a mere call to ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set and call it from the ide_dma_check() method instead of ide_dma_on(). Also, defer writing the DMA timings to the chip registers until DMA is actually turned on (and do not enable IORDY for DMA). Remove unnecessary code from the init_hwif() method, improve its looks overall, and also rename the driver's ide_dma_check() and dma_start() methods. --- This version takes into account that the ide-use-fast-pio.patch had been merged to mainline... Argh! Where those extra pluses camen from in the second hunk?! Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> drivers/ide/pci/sl82c105.c | 112 ++++++++++++++++----------------------------- 1 files changed, 41 insertions(+), 71 deletions(-) Index: linux-2.6/drivers/ide/pci/sl82c105.c =================================================================== --- linux-2.6.orig/drivers/ide/pci/sl82c105.c +++ linux-2.6/drivers/ide/pci/sl82c105.c @@ -11,6 +11,8 @@ * Merge in Russell's HW workarounds, fix various problems * with the timing registers setup. * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org + * + * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> */ #include <linux/types.h> @@ -115,59 +117,28 @@ static void sl82c105_tune_drive(ide_driv } /* - * Configure the drive and the chipset for DMA + * Configure the drive for DMA. + * We'll program the chipset only when DMA is actually turned on. */ static int config_for_dma (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - unsigned int reg; - DBG(("config_for_dma(drive:%s)\n", drive->name)); - reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) - return 1; - - pci_write_config_word(dev, reg, 0x0240); + return 0; - return 0; + return ide_dma_enable(drive); } /* - * Check to see if the drive and - * chipset is capable of DMA mode + * Check to see if the drive and chipset are capable of DMA mode. */ - -static int sl82c105_check_drive (ide_drive_t *drive) +static int sl82c105_ide_dma_check (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - - DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); - - do { - struct hd_driveid *id = drive->id; - - if (!drive->autodma) - break; + DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); - if (!id || !(id->capability & 1)) - break; - - /* Consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) - break; - - if (id->field_valid & 2) { - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) - return 0; - } - - if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) - return 0; - } while (0); + if (ide_use_dma(drive) && config_for_dma(drive)) + return 0; return -1; } @@ -236,7 +207,7 @@ static int sl82c105_ide_dma_lost_irq(ide * The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_ide_dma_start(ide_drive_t *drive) +static void sl82c105_dma_start(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -258,12 +229,18 @@ static int sl82c105_ide_dma_timeout(ide_ static int sl82c105_ide_dma_on (ide_drive_t *drive) { + struct pci_dev *dev = HWIF(drive)->pci_dev; + int rc, reg = 0x44 + drive->dn * 4; + DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); - if (config_for_dma(drive)) - return 1; - printk(KERN_INFO "%s: DMA enabled\n", drive->name); - return __ide_dma_on(drive); + rc = __ide_dma_on(drive); + if (rc == 0) { + pci_write_config_word(dev, reg, 0x0200); + + printk(KERN_INFO "%s: DMA enabled\n", drive->name); + } + return rc; } static void sl82c105_dma_off_quietly(ide_drive_t *drive) @@ -376,7 +353,7 @@ static unsigned int __devinit init_chips } /* - * Initialise the chip + * Initialise IDE channel */ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { @@ -396,11 +373,6 @@ static void __devinit init_hwif_sl82c105 hwif->drives[0].drive_data = hwif->drives[1].drive_data = 0x0909; hwif->drives[0].autotune = hwif->drives[1].autotune = 1; - hwif->atapi_dma = 0; - hwif->mwdma_mask = 0; - hwif->swdma_mask = 0; - hwif->autodma = 0; - if (!hwif->dma_base) return; @@ -410,27 +382,27 @@ static void __devinit init_hwif_sl82c105 * 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 { - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; - - hwif->ide_dma_check = &sl82c105_check_drive; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - 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; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; - - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; + printk(" %s: Winbond W83C553 bridge revision %d, " + "BM-DMA disabled\n", hwif->name, rev); + return; } + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x04; + + hwif->ide_dma_check = &sl82c105_ide_dma_check; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->dma_off_quietly = &sl82c105_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; + hwif->dma_start = &sl82c105_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; + + if (hwif->mate) + hwif->serialized = hwif->mate->serialized = 1; } static ide_pci_device_t sl82c105_chipset __devinitdata = { ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3) 2007-02-23 16:13 ` [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3) Sergei Shtylyov @ 2007-02-23 23:42 ` Bartlomiej Zolnierkiewicz 2007-03-28 18:50 ` [PATCH pata-2.6] sl82c105: DMA support code cleanup (take 4) Sergei Shtylyov 2007-03-28 20:24 ` [PATCH pata-2.6] sl82c105: add speedproc() method and MWDMA0/1 support Sergei Shtylyov 2 siblings, 0 replies; 10+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2007-02-23 23:42 UTC (permalink / raw) To: Sergei Shtylyov; +Cc: linux-ide, linuxppc-dev On Friday 23 February 2007, Sergei Shtylyov wrote: > Fold the now equivalent code in the ide_dma_check() method into a mere call to > ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set > and call it from the ide_dma_check() method instead of ide_dma_on(). > Also, defer writing the DMA timings to the chip registers until DMA is actually > turned on (and do not enable IORDY for DMA). Remove unnecessary code from the > init_hwif() method, improve its looks overall, and also rename the driver's > ide_dma_check() and dma_start() methods. > > --- > This version takes into account that the ide-use-fast-pio.patch had been merged > to mainline... applied ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH pata-2.6] sl82c105: DMA support code cleanup (take 4) 2007-02-23 16:13 ` [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3) Sergei Shtylyov 2007-02-23 23:42 ` Bartlomiej Zolnierkiewicz @ 2007-03-28 18:50 ` Sergei Shtylyov 2007-04-04 19:38 ` Bartlomiej Zolnierkiewicz 2007-03-28 20:24 ` [PATCH pata-2.6] sl82c105: add speedproc() method and MWDMA0/1 support Sergei Shtylyov 2 siblings, 1 reply; 10+ messages in thread From: Sergei Shtylyov @ 2007-03-28 18:50 UTC (permalink / raw) To: bzolnier; +Cc: linux-ide, linuxppc-dev Fold the now equivalent code in the ide_dma_check() method into a mere call to ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set and call it from the ide_dma_check() method instead of ide_dma_on(). Defer writing the DMA timings to the chip registers until DMA is really turned on (and do not enable IORDY for DMA). Remove unneeded code from the init_hwif() method, improve its overall looks. Rename the dma_start(), ide_dma_check(), and ide_dma_lostirq() methods, and also use more proper hwif->dma_command, fix printk() and comment in the latter one as well. While at it, cleanup style in several places. --- This patch has also been actually tested at last. :-) Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> drivers/ide/pci/sl82c105.c | 148 +++++++++++++++++---------------------------- 1 files changed, 59 insertions(+), 89 deletions(-) Index: linux-2.6/drivers/ide/pci/sl82c105.c =================================================================== --- linux-2.6.orig/drivers/ide/pci/sl82c105.c +++ linux-2.6/drivers/ide/pci/sl82c105.c @@ -100,59 +100,28 @@ static u8 sl82c105_tune_pio(ide_drive_t } /* - * Configure the drive and the chipset for DMA + * Configure the drive for DMA. + * We'll program the chipset only when DMA is actually turned on. */ -static int config_for_dma (ide_drive_t *drive) +static int config_for_dma(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - unsigned int reg; - DBG(("config_for_dma(drive:%s)\n", drive->name)); - reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) - return 1; - - pci_write_config_word(dev, reg, 0x0240); + return 0; - return 0; + return ide_dma_enable(drive); } /* - * Check to see if the drive and - * chipset is capable of DMA mode + * Check to see if the drive and chipset are capable of DMA mode. */ - -static int sl82c105_check_drive (ide_drive_t *drive) +static int sl82c105_ide_dma_check(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - - DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); + DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); - do { - struct hd_driveid *id = drive->id; - - if (!drive->autodma) - break; - - if (!id || !(id->capability & 1)) - break; - - /* Consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) - break; - - if (id->field_valid & 2) { - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) - return 0; - } - - if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) - return 0; - } while (0); + if (ide_use_dma(drive) && config_for_dma(drive)) + return 0; return -1; } @@ -181,14 +150,14 @@ static inline void sl82c105_reset_host(s * This function is called when the IDE timer expires, the drive * indicates that it is READY, and we were waiting for DMA to complete. */ -static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) +static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; - unsigned long dma_base = hwif->dma_base; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; + u8 dma_cmd; - printk("sl82c105: lost IRQ: resetting host\n"); + printk("sl82c105: lost IRQ, resetting host\n"); /* * Check the raw interrupt from the drive. @@ -201,15 +170,15 @@ static int sl82c105_ide_dma_lost_irq(ide * Was DMA enabled? If so, disable it - we're resetting the * host. The IDE layer will be handling the drive for us. */ - val = inb(dma_base); - if (val & 1) { - outb(val & ~1, dma_base); + dma_cmd = inb(hwif->dma_command); + if (dma_cmd & 1) { + outb(dma_cmd & ~1, hwif->dma_command); printk("sl82c105: DMA was enabled\n"); } sl82c105_reset_host(dev); - /* ide_dmaproc would return 1, so we do as well */ + /* __ide_dma_lostirq would return 1, so we do as well */ return 1; } @@ -221,10 +190,10 @@ static int sl82c105_ide_dma_lost_irq(ide * The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_ide_dma_start(ide_drive_t *drive) +static void sl82c105_dma_start(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; sl82c105_reset_host(dev); ide_dma_start(drive); @@ -232,8 +201,8 @@ static void sl82c105_ide_dma_start(ide_d static int sl82c105_ide_dma_timeout(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); @@ -241,14 +210,20 @@ static int sl82c105_ide_dma_timeout(ide_ return __ide_dma_timeout(drive); } -static int sl82c105_ide_dma_on (ide_drive_t *drive) +static int sl82c105_ide_dma_on(ide_drive_t *drive) { + struct pci_dev *dev = HWIF(drive)->pci_dev; + int rc, reg = 0x44 + drive->dn * 4; + DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); - if (config_for_dma(drive)) - return 1; - printk(KERN_INFO "%s: DMA enabled\n", drive->name); - return __ide_dma_on(drive); + rc = __ide_dma_on(drive); + if (rc == 0) { + pci_write_config_word(dev, reg, 0x0200); + + printk(KERN_INFO "%s: DMA enabled\n", drive->name); + } + return rc; } static void sl82c105_dma_off_quietly(ide_drive_t *drive) @@ -272,8 +247,8 @@ static void sl82c105_dma_off_quietly(ide */ static void sl82c105_selectproc(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; u32 val, old, mask; //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); @@ -373,7 +348,7 @@ static unsigned int __devinit init_chips } /* - * Initialise the chip + * Initialise IDE channel */ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { @@ -398,11 +373,6 @@ static void __devinit init_hwif_sl82c105 */ hwif->drives[0].autotune = hwif->drives[1].autotune = 1; - hwif->atapi_dma = 0; - hwif->mwdma_mask = 0; - hwif->swdma_mask = 0; - hwif->autodma = 0; - if (!hwif->dma_base) return; @@ -412,27 +382,27 @@ static void __devinit init_hwif_sl82c105 * 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 { - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; - - hwif->ide_dma_check = &sl82c105_check_drive; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - 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; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; - - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; + printk(" %s: Winbond W83C553 bridge revision %d, " + "BM-DMA disabled\n", hwif->name, rev); + return; } + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x04; + + hwif->ide_dma_check = &sl82c105_ide_dma_check; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->dma_off_quietly = &sl82c105_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lostirq; + hwif->dma_start = &sl82c105_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; + + if (hwif->mate) + hwif->serialized = hwif->mate->serialized = 1; } static ide_pci_device_t sl82c105_chipset __devinitdata = { ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH pata-2.6] sl82c105: DMA support code cleanup (take 4) 2007-03-28 18:50 ` [PATCH pata-2.6] sl82c105: DMA support code cleanup (take 4) Sergei Shtylyov @ 2007-04-04 19:38 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 10+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2007-04-04 19:38 UTC (permalink / raw) To: Sergei Shtylyov; +Cc: linux-ide, linuxppc-dev On Wednesday 28 March 2007, Sergei Shtylyov wrote: > Fold the now equivalent code in the ide_dma_check() method into a mere call to > ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set > and call it from the ide_dma_check() method instead of ide_dma_on(). > Defer writing the DMA timings to the chip registers until DMA is really turned > on (and do not enable IORDY for DMA). > Remove unneeded code from the init_hwif() method, improve its overall looks. > Rename the dma_start(), ide_dma_check(), and ide_dma_lostirq() methods, and > also use more proper hwif->dma_command, fix printk() and comment in the latter > one as well. While at it, cleanup style in several places. > > --- > This patch has also been actually tested at last. :-) > > Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> > Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> I moved Signed-off-by-s before "---" to prevent them from being eaten by git. applied ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH pata-2.6] sl82c105: add speedproc() method and MWDMA0/1 support 2007-02-23 16:13 ` [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3) Sergei Shtylyov 2007-02-23 23:42 ` Bartlomiej Zolnierkiewicz 2007-03-28 18:50 ` [PATCH pata-2.6] sl82c105: DMA support code cleanup (take 4) Sergei Shtylyov @ 2007-03-28 20:24 ` Sergei Shtylyov 2007-04-04 19:38 ` Bartlomiej Zolnierkiewicz 2 siblings, 1 reply; 10+ messages in thread From: Sergei Shtylyov @ 2007-03-28 20:24 UTC (permalink / raw) To: bzolnier; +Cc: linux-ide, linuxppc-dev Add the speedproc() method for setting transfer modes, modify config_for_dma() to call it and use ide_max_dma_mode() to select the best DMA mode. Add support for the multiword DMA modes 0 and 1, using the upper half of the 'drive_data' field to store the DMA timings to program into the drive control register when DMA is turned on for real. Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> --- This patch replaces sl82c105-add-speedproc.patch from pata-2.6 patchset. drivers/ide/pci/sl82c105.c | 71 +++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 66 insertions(+), 5 deletions(-) Index: linux-2.6/drivers/ide/pci/sl82c105.c =================================================================== --- linux-2.6.orig/drivers/ide/pci/sl82c105.c +++ linux-2.6/drivers/ide/pci/sl82c105.c @@ -82,7 +82,14 @@ static u8 sl82c105_tune_pio(ide_drive_t pio = ide_get_best_pio_mode(drive, pio, 5, &p); - drive->drive_data = drv_ctrl = get_pio_timings(&p); + drv_ctrl = get_pio_timings(&p); + + /* + * Store the PIO timings so that we can restore them + * in case DMA will be turned off... + */ + drive->drive_data &= 0xffff0000; + drive->drive_data |= drv_ctrl; if (!drive->using_dma) { /* @@ -100,14 +107,67 @@ static u8 sl82c105_tune_pio(ide_drive_t } /* + * Configure the drive and chipset for a new transfer speed. + */ +static int sl82c105_tune_chipset(ide_drive_t *drive, u8 speed) +{ + static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200}; + u16 drv_ctrl; + + DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n", + drive->name, ide_xfer_verbose(speed))); + + speed = ide_rate_filter(drive, speed); + + switch (speed) { + case XFER_MW_DMA_2: + case XFER_MW_DMA_1: + case XFER_MW_DMA_0: + drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0]; + + /* + * Store the DMA timings so that we can actually program + * them when DMA will be turned on... + */ + drive->drive_data &= 0x0000ffff; + drive->drive_data |= (unsigned long)drv_ctrl << 16; + + /* + * If we are already using DMA, we just reprogram + * the drive control register. + */ + if (drive->using_dma) { + struct pci_dev *dev = HWIF(drive)->pci_dev; + int reg = 0x44 + drive->dn * 4; + + pci_write_config_word(dev, reg, drv_ctrl); + } + break; + case XFER_PIO_5: + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + (void) sl82c105_tune_pio(drive, speed - XFER_PIO_0); + break; + default: + return -1; + } + + return ide_config_drive_speed(drive, speed); +} + +/* * Configure the drive for DMA. - * We'll program the chipset only when DMA is actually turned on. */ static int config_for_dma(ide_drive_t *drive) { + u8 speed = ide_max_dma_mode(drive); + DBG(("config_for_dma(drive:%s)\n", drive->name)); - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) + if (!speed || sl82c105_tune_chipset(drive, speed)) return 0; return ide_dma_enable(drive); @@ -219,7 +279,7 @@ static int sl82c105_ide_dma_on(ide_drive rc = __ide_dma_on(drive); if (rc == 0) { - pci_write_config_word(dev, reg, 0x0200); + pci_write_config_word(dev, reg, drive->drive_data >> 16); printk(KERN_INFO "%s: DMA enabled\n", drive->name); } @@ -357,6 +417,7 @@ static void __devinit init_hwif_sl82c105 DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); hwif->tuneproc = &sl82c105_tune_drive; + hwif->speedproc = &sl82c105_tune_chipset; hwif->selectproc = &sl82c105_selectproc; hwif->resetproc = &sl82c105_resetproc; @@ -388,7 +449,7 @@ static void __devinit init_hwif_sl82c105 } hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; + hwif->mwdma_mask = 0x07; hwif->ide_dma_check = &sl82c105_ide_dma_check; hwif->ide_dma_on = &sl82c105_ide_dma_on; ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH pata-2.6] sl82c105: add speedproc() method and MWDMA0/1 support 2007-03-28 20:24 ` [PATCH pata-2.6] sl82c105: add speedproc() method and MWDMA0/1 support Sergei Shtylyov @ 2007-04-04 19:38 ` Bartlomiej Zolnierkiewicz 2007-04-04 19:53 ` Sergei Shtylyov 0 siblings, 1 reply; 10+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2007-04-04 19:38 UTC (permalink / raw) To: Sergei Shtylyov; +Cc: linux-ide, linuxppc-dev On Wednesday 28 March 2007, Sergei Shtylyov wrote: > Add the speedproc() method for setting transfer modes, modify config_for_dma() > to call it and use ide_max_dma_mode() to select the best DMA mode. > Add support for the multiword DMA modes 0 and 1, using the upper half of the > 'drive_data' field to store the DMA timings to program into the drive control > register when DMA is turned on for real. > > Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> applied ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH pata-2.6] sl82c105: add speedproc() method and MWDMA0/1 support 2007-04-04 19:38 ` Bartlomiej Zolnierkiewicz @ 2007-04-04 19:53 ` Sergei Shtylyov 0 siblings, 0 replies; 10+ messages in thread From: Sergei Shtylyov @ 2007-04-04 19:53 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linuxppc-dev Hello. Bartlomiej Zolnierkiewicz wrote: >>Add the speedproc() method for setting transfer modes, modify config_for_dma() >>to call it and use ide_max_dma_mode() to select the best DMA mode. >>Add support for the multiword DMA modes 0 and 1, using the upper half of the >>'drive_data' field to store the DMA timings to program into the drive control >>register when DMA is turned on for real. >>Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> > applied I now also have almost complete patch to merge PIO/DMA timings and so get rid of selectproc() there... :-) MBR, Sergei ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-04-04 19:52 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-02-13 21:43 [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup Sergei Shtylyov 2007-02-14 19:48 ` Bartlomiej Zolnierkiewicz 2007-02-23 16:10 ` [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 2) Sergei Shtylyov 2007-02-23 16:13 ` [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3) Sergei Shtylyov 2007-02-23 23:42 ` Bartlomiej Zolnierkiewicz 2007-03-28 18:50 ` [PATCH pata-2.6] sl82c105: DMA support code cleanup (take 4) Sergei Shtylyov 2007-04-04 19:38 ` Bartlomiej Zolnierkiewicz 2007-03-28 20:24 ` [PATCH pata-2.6] sl82c105: add speedproc() method and MWDMA0/1 support Sergei Shtylyov 2007-04-04 19:38 ` Bartlomiej Zolnierkiewicz 2007-04-04 19:53 ` Sergei Shtylyov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).