From ceec1827e29b9b3d5cac225fee554bd31e565b58 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:47 +0200 Subject: ide_platform: set hwif->chipset We need to set hwif->chipset or IDE PCI host drivers may try to claim our ide_hwifs[] slot. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/legacy/ide_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index ccfb9893a467..b992b2b91fe2 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c @@ -65,7 +65,7 @@ found: hwif->hw.irq = hwif->irq = irq; hwif->hw.dma = NO_DMA; - hwif->hw.chipset = ide_generic; + hwif->chipset = hwif->hw.chipset = ide_generic; if (mmio) { hwif->mmio = 1; -- cgit v1.2.3-55-g7522 From 39e5f590b6dea070f17d44e1e6af1188777085d3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 13 Oct 2007 17:47:48 +0200 Subject: ide: unexport ide_acpi_set_state This patch removes the unused EXPORT_SYMBOL_GPL(ide_acpi_set_state) Signed-off-by: Adrian Bunk Cc: Shaohua Li Cc: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-acpi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 6bff81a58bf3..1d5f6823101c 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -649,7 +649,6 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) if (!on) acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3); } -EXPORT_SYMBOL_GPL(ide_acpi_set_state); /** * ide_acpi_init - initialize the ACPI link for an IDE interface -- cgit v1.2.3-55-g7522 From 90a87ea480ce50e7a1553568395c024294db1808 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:48 +0200 Subject: ide-pmac: don't check kauai_lookup_timing() return value kauai_lookup_timing() should always return non-zero return value: * BUG() in kauai_lookup_timing() if the timing info cannot be found. * Remove code checking for zero return value from all callers. Acked-by: Benjamin Herrenschmidt Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index f759a5397865..b43457e34311 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -392,6 +392,7 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time) for (i=0; table[i].cycle_time; i++) if (cycle_time > table[i+1].cycle_time) return table[i].timing_reg; + BUG(); return 0; } @@ -637,8 +638,6 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) case controller_sh_ata6: { /* 133Mhz cell */ u32 tr = kauai_lookup_timing(shasta_pio_timings, cycle_time); - if (tr == 0) - return; *timings = ((*timings) & ~TR_133_PIOREG_PIO_MASK) | tr; break; } @@ -646,8 +645,6 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) case controller_k2_ata6: { /* 100Mhz cell */ u32 tr = kauai_lookup_timing(kauai_pio_timings, cycle_time); - if (tr == 0) - return; *timings = ((*timings) & ~TR_100_PIOREG_PIO_MASK) | tr; break; } @@ -746,8 +743,6 @@ set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed) if (speed > XFER_UDMA_5 || t == NULL) return 1; tr = kauai_lookup_timing(kauai_udma_timings, (int)t->udma); - if (tr == 0) - return 1; *ultra_timings = ((*ultra_timings) & ~TR_100_UDMAREG_UDMA_MASK) | tr; *ultra_timings = (*ultra_timings) | TR_100_UDMAREG_UDMA_EN; @@ -766,8 +761,6 @@ set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed) if (speed > XFER_UDMA_6 || t == NULL) return 1; tr = kauai_lookup_timing(shasta_udma133_timings, (int)t->udma); - if (tr == 0) - return 1; *ultra_timings = ((*ultra_timings) & ~TR_133_UDMAREG_UDMA_MASK) | tr; *ultra_timings = (*ultra_timings) | TR_133_UDMAREG_UDMA_EN; @@ -839,8 +832,6 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, case controller_sh_ata6: { /* 133Mhz cell */ u32 tr = kauai_lookup_timing(shasta_mdma_timings, cycleTime); - if (tr == 0) - return 1; *timings = ((*timings) & ~TR_133_PIOREG_MDMA_MASK) | tr; *timings2 = (*timings2) & ~TR_133_UDMAREG_UDMA_EN; } @@ -848,8 +839,6 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, case controller_k2_ata6: { /* 100Mhz cell */ u32 tr = kauai_lookup_timing(kauai_mdma_timings, cycleTime); - if (tr == 0) - return 1; *timings = ((*timings) & ~TR_100_PIOREG_MDMA_MASK) | tr; *timings2 = (*timings2) & ~TR_100_UDMAREG_UDMA_EN; } -- cgit v1.2.3-55-g7522 From 085798b12ffebd69c13c8ce05fabc8ed5ac43e63 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:48 +0200 Subject: ide-pmac: pmac_ide_tune_chipset() fixes * Don't check check for pmif == NULL (it should never be NULL if we got here). * Make a local copy of the timings and set the pmif->timings[] only after setting the transfer mode on the device (otherwise SELECT_DRIVE() call in pmac_ide_do_setfeature() will program new timings before the transfer mode is set on the device - this was pointed out by Sergei). This change makes pmac_ide_tune_chipset() behavior match this of pmac_ide_{m,u}dma_enable(). Acked-by: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index b43457e34311..cfbe5690ca88 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -916,14 +916,15 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed) int unit = (drive->select.b.unit & 0x01); int ret = 0; pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; - u32 *timings, *timings2; + u32 *timings, *timings2, tl[2]; - if (pmif == NULL) - return 1; - timings = &pmif->timings[unit]; timings2 = &pmif->timings[unit+2]; - + + /* Copy timings to local image */ + tl[0] = *timings; + tl[1] = *timings2; + switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC case XFER_UDMA_6: @@ -934,19 +935,19 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed) case XFER_UDMA_1: case XFER_UDMA_0: if (pmif->kind == controller_kl_ata4) - ret = set_timings_udma_ata4(timings, speed); + ret = set_timings_udma_ata4(&tl[0], speed); else if (pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6) - ret = set_timings_udma_ata6(timings, timings2, speed); + ret = set_timings_udma_ata6(&tl[0], &tl[1], speed); else if (pmif->kind == controller_sh_ata6) - ret = set_timings_udma_shasta(timings, timings2, speed); + ret = set_timings_udma_shasta(&tl[0], &tl[1], speed); else - ret = 1; + ret = 1; break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: - ret = set_timings_mdma(drive, pmif->kind, timings, timings2, speed, 0); + ret = set_timings_mdma(drive, pmif->kind, &tl[0], &tl[1], speed, 0); break; case XFER_SW_DMA_2: case XFER_SW_DMA_1: @@ -962,7 +963,11 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed) ret = pmac_ide_do_setfeature(drive, speed); if (ret) return ret; - + + /* Apply timings to controller */ + *timings = tl[0]; + *timings2 = tl[1]; + pmac_ide_do_update_timings(drive); return 0; -- cgit v1.2.3-55-g7522 From 90f72eca36e92d5756cf312535d94d7f21f34d2e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:48 +0200 Subject: ide-pmac: fix set_timings_mdma() * Move adjusting of cycle time for devices providing explicit DMA cycle time from pmac_ide_mdma_enable() to set_timings_mdma(). * Remove no longer needed drive_cycle_time argument. * BUG() if unsupported speed argument value is passed (shouldn't happen). * Matching access/recovery timings always exist so remove redundant check. * Make set_timings_mdma() void. * Update pmac_ide_tune_chipset()'s comment. Acked-by: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index cfbe5690ca88..b24e905ddcdd 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -770,12 +770,13 @@ set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed) /* * Calculate MDMA timings for all cells */ -static int +static void set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, - u8 speed, int drive_cycle_time) + u8 speed) { int cycleTime, accessTime = 0, recTime = 0; unsigned accessTicks, recTicks; + struct hd_driveid *id = drive->id; struct mdma_timings_t* tm = NULL; int i; @@ -785,11 +786,14 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, case 1: cycleTime = 150; break; case 2: cycleTime = 120; break; default: - return 1; + BUG(); + break; } - /* Adjust for drive */ - if (drive_cycle_time && drive_cycle_time > cycleTime) - cycleTime = drive_cycle_time; + + /* Check if drive provides explicit DMA cycle time */ + if ((id->field_valid & 2) && id->eide_dma_time) + cycleTime = max_t(int, id->eide_dma_time, cycleTime); + /* OHare limits according to some old Apple sources */ if ((intf_type == controller_ohare) && (cycleTime < 150)) cycleTime = 150; @@ -817,8 +821,6 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, break; i++; } - if (i < 0) - return 1; cycleTime = tm[i].cycleTime; accessTime = tm[i].accessTime; recTime = tm[i].recoveryTime; @@ -900,16 +902,12 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, printk(KERN_ERR "%s: Set MDMA timing for mode %d, reg: 0x%08x\n", drive->name, speed & 0xf, *timings); #endif - return 0; } #endif /* #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC */ /* * Speedproc. This function is called by the core to set any of the standard * DMA timing (MDMA or UDMA) to both the drive and the controller. - * You may notice we don't use this function on normal "dma check" operation, - * our dedicated function is more precise as it uses the drive provided - * cycle time value. We should probably fix this one to deal with that too... */ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed) { @@ -947,7 +945,7 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed) case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: - ret = set_timings_mdma(drive, pmif->kind, &tl[0], &tl[1], speed, 0); + set_timings_mdma(drive, pmif->kind, &tl[0], &tl[1], speed); break; case XFER_SW_DMA_2: case XFER_SW_DMA_1: @@ -1680,8 +1678,6 @@ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) { ide_hwif_t *hwif = HWIF(drive); pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; - int drive_cycle_time; - struct hd_driveid *id = drive->id; u32 *timings, *timings2; u32 timing_local[2]; int ret; @@ -1690,24 +1686,12 @@ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) timings = &pmif->timings[drive->select.b.unit & 0x01]; timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2]; - /* Check if drive provide explicit cycle time */ - if ((id->field_valid & 2) && (id->eide_dma_time)) - drive_cycle_time = id->eide_dma_time; - else - drive_cycle_time = 0; - /* Copy timings to local image */ timing_local[0] = *timings; timing_local[1] = *timings2; /* Calculate controller timings */ - ret = set_timings_mdma( drive, pmif->kind, - &timing_local[0], - &timing_local[1], - mode, - drive_cycle_time); - if (ret) - return 0; + set_timings_mdma(drive, pmif->kind, &timing_local[0], &timing_local[1], mode); /* Set feature on drive */ printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, mode & 0xf); -- cgit v1.2.3-55-g7522 From 78103940e4f8084de2bf8ca81c4bd09b48e9ac16 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:49 +0200 Subject: ide-pmac: remove control register messing from pmac_ide_dma_check() pmac_ide_do_setfeature() contains matching nIEN setting/clearing so this Device Control register messing in pmac_ide_dma_check() is totally unnecessary. Cc: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index b24e905ddcdd..d6a1a9be58a7 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1784,7 +1784,7 @@ pmac_ide_dma_check(ide_drive_t *drive) drive->using_dma = pmac_ide_udma_enable(drive, mode); else if (mode >= XFER_MW_DMA_0) drive->using_dma = pmac_ide_mdma_enable(drive, mode); - hwif->OUTB(0, IDE_CONTROL_REG); + /* Apply settings to controller */ pmac_ide_do_update_timings(drive); } -- cgit v1.2.3-55-g7522 From fd553ce86893e0a54ec0d07d1f1d241f2fb2aef3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:49 +0200 Subject: ide-pmac: remove pmac_ide_{m,u}dma_enable() (take 2) * Fix pmac_ide_dma_check() to use pmac_ide_tune_chipset() and remove no longer necessary pmac_ide_{m,u}dma_enable(). * While at it remove some dead code from pmac_ide_dma_check() (leftovers from conversion to use ide_max_dma_mode()). There should be no functionality changes caused by this patch. v2: * Fix compile by replacing "id" with "drive->id" in pmac_ide_dma_check() (Noticed by Ben). Cc: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 102 ++----------------------------------------------- 1 file changed, 4 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index d6a1a9be58a7..ad58c7ecf858 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1670,94 +1670,6 @@ pmac_ide_destroy_dmatable (ide_drive_t *drive) } } -/* - * Pick up best MDMA timing for the drive and apply it - */ -static int -pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) -{ - ide_hwif_t *hwif = HWIF(drive); - pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; - u32 *timings, *timings2; - u32 timing_local[2]; - int ret; - - /* which drive is it ? */ - timings = &pmif->timings[drive->select.b.unit & 0x01]; - timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2]; - - /* Copy timings to local image */ - timing_local[0] = *timings; - timing_local[1] = *timings2; - - /* Calculate controller timings */ - set_timings_mdma(drive, pmif->kind, &timing_local[0], &timing_local[1], mode); - - /* Set feature on drive */ - printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, mode & 0xf); - ret = pmac_ide_do_setfeature(drive, mode); - if (ret) { - printk(KERN_WARNING "%s: Failed !\n", drive->name); - return 0; - } - - /* Apply timings to controller */ - *timings = timing_local[0]; - *timings2 = timing_local[1]; - - return 1; -} - -/* - * Pick up best UDMA timing for the drive and apply it - */ -static int -pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) -{ - ide_hwif_t *hwif = HWIF(drive); - pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data; - u32 *timings, *timings2; - u32 timing_local[2]; - int ret; - - /* which drive is it ? */ - timings = &pmif->timings[drive->select.b.unit & 0x01]; - timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2]; - - /* Copy timings to local image */ - timing_local[0] = *timings; - timing_local[1] = *timings2; - - /* Calculate timings for interface */ - if (pmif->kind == controller_un_ata6 - || pmif->kind == controller_k2_ata6) - ret = set_timings_udma_ata6( &timing_local[0], - &timing_local[1], - mode); - else if (pmif->kind == controller_sh_ata6) - ret = set_timings_udma_shasta( &timing_local[0], - &timing_local[1], - mode); - else - ret = set_timings_udma_ata4(&timing_local[0], mode); - if (ret) - return 0; - - /* Set feature on drive */ - printk(KERN_INFO "%s: Enabling Ultra DMA %d\n", drive->name, mode & 0x0f); - ret = pmac_ide_do_setfeature(drive, mode); - if (ret) { - printk(KERN_WARNING "%s: Failed !\n", drive->name); - return 0; - } - - /* Apply timings to controller */ - *timings = timing_local[0]; - *timings2 = timing_local[1]; - - return 1; -} - /* * Check what is the best DMA timing setting for the drive and * call appropriate functions to apply it. @@ -1765,14 +1677,13 @@ pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) static int pmac_ide_dma_check(ide_drive_t *drive) { - struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); int enable = 1; + drive->using_dma = 0; if (drive->media == ide_floppy) enable = 0; - if (((id->capability & 1) == 0) && !__ide_dma_good_drive(drive)) + if ((drive->id->capability & 1) == 0 && !__ide_dma_good_drive(drive)) enable = 0; if (__ide_dma_bad_drive(drive)) enable = 0; @@ -1780,13 +1691,8 @@ pmac_ide_dma_check(ide_drive_t *drive) if (enable) { u8 mode = ide_max_dma_mode(drive); - if (mode >= XFER_UDMA_0) - drive->using_dma = pmac_ide_udma_enable(drive, mode); - else if (mode >= XFER_MW_DMA_0) - drive->using_dma = pmac_ide_mdma_enable(drive, mode); - - /* Apply settings to controller */ - pmac_ide_do_update_timings(drive); + if (mode && pmac_ide_tune_chipset(drive, mode) == 0) + drive->using_dma = 1; } return 0; } -- cgit v1.2.3-55-g7522 From 74af21cf4d0ab67df53608753a443dc7904ec12e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:49 +0200 Subject: ide: add __ide_wait_stat() helper * Split off checking of the status register from ide_wait_stat() to __ide_wait_stat() helper. * Use the new helper in ide_config_drive_speed(). The only change in the functionality is that the function now fails if after 20 sec (WAIT_CMD) device is still busy (BUSY_STAT bit is set) while previously instead of failing the function continued with checking for the correct device status (which would give the device additional 10 usec to clear BUSY_STAT bit). * Remove stale comment for ide_config_drive_speed(). * Remove duplicate comment for ide_wait_stat() from . Cc: Benjamin Herrenschmidt Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-iops.c | 96 +++++++++++++++++++++++--------------------------- include/linux/ide.h | 11 +----- 2 files changed, 45 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index cf0678b61161..fb524cf175d5 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -505,25 +505,19 @@ int wait_for_ready (ide_drive_t *drive, int timeout) * This routine busy-waits for the drive status to be not "busy". * It then checks the status for all of the "good" bits and none * of the "bad" bits, and if all is okay it returns 0. All other - * cases return 1 after invoking ide_error() -- caller should just return. + * cases return error -- caller may then invoke ide_error(). * * This routine should get fixed to not hog the cpu during extra long waits.. * That could be done by busy-waiting for the first jiffy or two, and then * setting a timer to wake up at half second intervals thereafter, * until timeout is achieved, before timing out. */ -int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout) +static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) { - ide_hwif_t *hwif = HWIF(drive); - u8 stat; - int i; + ide_hwif_t *hwif = drive->hwif; unsigned long flags; - - /* bail early if we've exceeded max_failures */ - if (drive->max_failures && (drive->failures > drive->max_failures)) { - *startstop = ide_stopped; - return 1; - } + int i; + u8 stat; udelay(1); /* spec allows drive 400ns to assert "BUSY" */ if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { @@ -541,8 +535,8 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b break; local_irq_restore(flags); - *startstop = ide_error(drive, "status timeout", stat); - return 1; + *rstat = stat; + return -EBUSY; } } local_irq_restore(flags); @@ -556,11 +550,39 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b */ for (i = 0; i < 10; i++) { udelay(1); - if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) + if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) { + *rstat = stat; return 0; + } } - *startstop = ide_error(drive, "status error", stat); - return 1; + *rstat = stat; + return -EFAULT; +} + +/* + * In case of error returns error value after doing "*startstop = ide_error()". + * The caller should return the updated value of "startstop" in this case, + * "startstop" is unchanged when the function returns 0. + */ +int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout) +{ + int err; + u8 stat; + + /* bail early if we've exceeded max_failures */ + if (drive->max_failures && (drive->failures > drive->max_failures)) { + *startstop = ide_stopped; + return 1; + } + + err = __ide_wait_stat(drive, good, bad, timeout, &stat); + + if (err) { + char *s = (err == -EBUSY) ? "status timeout" : "status error"; + *startstop = ide_error(drive, s, stat); + } + + return err; } EXPORT_SYMBOL(ide_wait_stat); @@ -778,15 +800,10 @@ int ide_driveid_update (ide_drive_t *drive) #endif } -/* - * Similar to ide_wait_stat(), except it never calls ide_error internally. - * - * const char *msg == consider adding for verbose errors. - */ -int ide_config_drive_speed (ide_drive_t *drive, u8 speed) +int ide_config_drive_speed(ide_drive_t *drive, u8 speed) { - ide_hwif_t *hwif = HWIF(drive); - int i, error = 1; + ide_hwif_t *hwif = drive->hwif; + int error; u8 stat; // while (HWGROUP(drive)->busy) @@ -826,35 +843,10 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) hwif->OUTB(drive->ctl, IDE_CONTROL_REG); - udelay(1); - /* - * Wait for drive to become non-BUSY - */ - if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { - unsigned long flags, timeout; - local_irq_set(flags); - timeout = jiffies + WAIT_CMD; - while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { - if (time_after(jiffies, timeout)) - break; - } - local_irq_restore(flags); - } - /* - * Allow status to settle, then read it again. - * A few rare drives vastly violate the 400ns spec here, - * so we'll wait up to 10usec for a "good" status - * rather than expensively fail things immediately. - * This fix courtesy of Matthew Faupel & Niccolo Rigacci. - */ - for (i = 0; i < 10; i++) { - udelay(1); - if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT)) { - error = 0; - break; - } - } + error = __ide_wait_stat(drive, drive->ready_stat, + BUSY_STAT|DRQ_STAT|ERR_STAT, + WAIT_CMD, &stat); SELECT_MASK(drive, 0); diff --git a/include/linux/ide.h b/include/linux/ide.h index 85d448b4abec..3a8cb81bb61d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1079,16 +1079,7 @@ extern void ide_fix_driveid(struct hd_driveid *); */ extern void ide_fixstring(u8 *, const int, const int); -/* - * This routine busy-waits for the drive status to be not "busy". - * It then checks the status for all of the "good" bits and none - * of the "bad" bits, and if all is okay it returns 0. All other - * cases return 1 after doing "*startstop = ide_error()", and the - * caller should return the updated value of "startstop" in this case. - * "startstop" is unchanged when the function returns 0; - * (startstop, drive, good, bad, timeout) - */ -extern int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); +int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); /* * Start a reset operation for an IDE interface. -- cgit v1.2.3-55-g7522 From 218ee5f364ed006403f1bbe3c1da5af51b1bdb2a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:49 +0200 Subject: ide-pmac: remove extra good status wait from pmac_ide_do_setfeature() Don't check for good device status before executing the command in pmac_ide_do_setfeature() (ide_config_drive_speed() doesn't do this). It is a job of upper layers to guarantee that the device is ready to accept new command before we get here. Cc: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index ad58c7ecf858..512452b379bd 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -548,16 +548,6 @@ pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) SELECT_DRIVE(drive); SELECT_MASK(drive, 0); udelay(1); - /* Get rid of pending error state */ - (void) hwif->INB(IDE_STATUS_REG); - /* Timeout bumped for some powerbooks */ - if (wait_for_ready(drive, 2000)) { - /* Timeout bumped for some powerbooks */ - printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready " - "before SET_FEATURE!\n", drive->name); - goto out; - } - udelay(10); hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); hwif->OUTB(command, IDE_NSECTOR_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); @@ -569,7 +559,7 @@ pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) if (result) printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready " "after SET_FEATURE !\n", drive->name); -out: + SELECT_MASK(drive, 0); if (result == 0) { drive->id->dma_ultra &= ~0xFF00; -- cgit v1.2.3-55-g7522 From ddf151026a293725507fedc39b18ae6edb86d775 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:49 +0200 Subject: ide-pmac: use __ide_wait_stat() * Use __ide_wait_stat() instead of wait_for_ready() in pmac_ide_do_setfeature(). While at it do following changes to match __ide_wait_stat() call in ide_config_drive_speed(): * Wait WAIT_CMD time (20 sec) instead of 2 sec for device to clear BUSY_STAT. * Check DRQ_STAT bit (shouldn't be set for good device status). Also remove no longer needed wait_for_ready() from ide-iops.c. Acked-by: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-iops.c | 31 +------------------------------ drivers/ide/ppc/pmac.c | 9 +++++---- include/linux/ide.h | 2 +- 3 files changed, 7 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index fb524cf175d5..f7e976c0c2f3 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -472,35 +472,6 @@ int drive_is_ready (ide_drive_t *drive) EXPORT_SYMBOL(drive_is_ready); -/* - * Global for All, and taken from ide-pmac.c. Can be called - * with spinlock held & IRQs disabled, so don't schedule ! - */ -int wait_for_ready (ide_drive_t *drive, int timeout) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 stat = 0; - - while(--timeout) { - stat = hwif->INB(IDE_STATUS_REG); - if (!(stat & BUSY_STAT)) { - if (drive->ready_stat == 0) - break; - else if ((stat & drive->ready_stat)||(stat & ERR_STAT)) - break; - } - mdelay(1); - } - if ((stat & ERR_STAT) || timeout <= 0) { - if (stat & ERR_STAT) { - printk(KERN_ERR "%s: wait_for_ready, " - "error status: %x\n", drive->name, stat); - } - return 1; - } - return 0; -} - /* * This routine busy-waits for the drive status to be not "busy". * It then checks the status for all of the "good" bits and none @@ -512,7 +483,7 @@ int wait_for_ready (ide_drive_t *drive, int timeout) * setting a timer to wake up at half second intervals thereafter, * until timeout is achieved, before timing out. */ -static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) +int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) { ide_hwif_t *hwif = drive->hwif; unsigned long flags; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 512452b379bd..13e26642dad7 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -541,7 +541,8 @@ static int pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) { ide_hwif_t *hwif = HWIF(drive); - int result = 1; + int result; + u8 stat; disable_irq_nosync(hwif->irq); udelay(1); @@ -552,9 +553,9 @@ pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) hwif->OUTB(command, IDE_NSECTOR_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); - udelay(1); - /* Timeout bumped for some powerbooks */ - result = wait_for_ready(drive, 2000); + result = __ide_wait_stat(drive, drive->ready_stat, + BUSY_STAT|DRQ_STAT|ERR_STAT, + WAIT_CMD, &stat); hwif->OUTB(drive->ctl, IDE_CONTROL_REG); if (result) printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready " diff --git a/include/linux/ide.h b/include/linux/ide.h index 3a8cb81bb61d..d86115e9aa2c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1153,7 +1153,7 @@ extern void SELECT_MASK(ide_drive_t *, int); extern void QUIRK_LIST(ide_drive_t *); extern int drive_is_ready(ide_drive_t *); -extern int wait_for_ready(ide_drive_t *, int /* timeout */); +int __ide_wait_stat(ide_drive_t *, u8, u8, unsigned long); /* * taskfile io for disks for now...and builds request from ide_ioctl -- cgit v1.2.3-55-g7522 From 3b2d0093b8eb2b0b4adc86138edee9f6d376cafb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:49 +0200 Subject: ide-pmac: remove nIEN clearing from pmac_ide_do_setfeature() Upper layers are responsible for controlling nIEN so don't clear nIEN after command execution in pmac_ide_do_setfeature(). Cc: Benjamin Herrenschmidt Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 13e26642dad7..c68e2472345a 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -556,7 +556,6 @@ pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) result = __ide_wait_stat(drive, drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD, &stat); - hwif->OUTB(drive->ctl, IDE_CONTROL_REG); if (result) printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready " "after SET_FEATURE !\n", drive->name); -- cgit v1.2.3-55-g7522 From aedea5910ce44fea79e2c517bb22e0006372156f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:50 +0200 Subject: ide-pmac: remove pmac_ide_do_setfeature() (take 2) Use ide_config_drive_speed() instead of pmac_ide_do_setfeature() and remove the latter, also ide-iops.c::__ide_wait_stat() could be static again. Since for IDE PMAC host driver IDE_CONTROL_REG is always true, device's ->quirk_list is always zero and ->ide_dma_host_{on,off} are nops than the only changes in behavior are: * if PIO mode is set then ->dma_off_queitly is called to disable DMA * if setting transfer mode fails ide_dump_status() is called to dump status v2: * IDE PMAC controllers allow separate PIO and DMA timings and PPC userland depends on this fact, and calls "hdparm -p" without calling "hdparm -d". Therefore to compensate for DMA being disabled by ide_config_drive_speed() for PIO modes: - add IDE_HFLAG_SET_PIO_MODE_KEEP_DMA flag and set it in PMAC host driver - add handling of the new flag to ide-io.c::do_special() Cc: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 10 ++++++- drivers/ide/ide-iops.c | 2 +- drivers/ide/ppc/pmac.c | 80 ++------------------------------------------------ include/linux/ide.h | 6 +++- 4 files changed, 18 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 9560a8f4a86c..4cece930114c 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -836,9 +836,17 @@ static ide_startstop_t do_special (ide_drive_t *drive) if (set_pio_mode_abuse(drive->hwif, req_pio)) { if (hwif->set_pio_mode) hwif->set_pio_mode(drive, req_pio); - } else + } else { + int keep_dma = drive->using_dma; + ide_set_pio(drive, req_pio); + if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) { + if (keep_dma) + hwif->ide_dma_on(drive); + } + } + return ide_stopped; } else { if (drive->media == ide_disk) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index f7e976c0c2f3..e5fc2e505959 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -483,7 +483,7 @@ EXPORT_SYMBOL(drive_is_ready); * setting a timer to wake up at half second intervals thereafter, * until timeout is achieved, before timing out. */ -int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) +static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) { ide_hwif_t *hwif = drive->hwif; unsigned long flags; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index c68e2472345a..24f73291c4d5 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -529,81 +529,6 @@ pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port) tmp = readl(PMAC_IDE_REG(IDE_TIMING_CONFIG)); } -/* - * Send the SET_FEATURE IDE command to the drive and update drive->id with - * the new state. We currently don't use the generic routine as it used to - * cause various trouble, especially with older mediabays. - * This code is sometimes triggering a spurrious interrupt though, I need - * to sort that out sooner or later and see if I can finally get the - * common version to work properly in all cases - */ -static int -pmac_ide_do_setfeature(ide_drive_t *drive, u8 command) -{ - ide_hwif_t *hwif = HWIF(drive); - int result; - u8 stat; - - disable_irq_nosync(hwif->irq); - udelay(1); - SELECT_DRIVE(drive); - SELECT_MASK(drive, 0); - udelay(1); - hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); - hwif->OUTB(command, IDE_NSECTOR_REG); - hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); - hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); - result = __ide_wait_stat(drive, drive->ready_stat, - BUSY_STAT|DRQ_STAT|ERR_STAT, - WAIT_CMD, &stat); - if (result) - printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready " - "after SET_FEATURE !\n", drive->name); - - SELECT_MASK(drive, 0); - if (result == 0) { - drive->id->dma_ultra &= ~0xFF00; - drive->id->dma_mword &= ~0x0F00; - drive->id->dma_1word &= ~0x0F00; - switch(command) { - case XFER_UDMA_7: - drive->id->dma_ultra |= 0x8080; break; - case XFER_UDMA_6: - drive->id->dma_ultra |= 0x4040; break; - case XFER_UDMA_5: - drive->id->dma_ultra |= 0x2020; break; - case XFER_UDMA_4: - drive->id->dma_ultra |= 0x1010; break; - case XFER_UDMA_3: - drive->id->dma_ultra |= 0x0808; break; - case XFER_UDMA_2: - drive->id->dma_ultra |= 0x0404; break; - case XFER_UDMA_1: - drive->id->dma_ultra |= 0x0202; break; - case XFER_UDMA_0: - drive->id->dma_ultra |= 0x0101; break; - case XFER_MW_DMA_2: - drive->id->dma_mword |= 0x0404; break; - case XFER_MW_DMA_1: - drive->id->dma_mword |= 0x0202; break; - case XFER_MW_DMA_0: - drive->id->dma_mword |= 0x0101; break; - case XFER_SW_DMA_2: - drive->id->dma_1word |= 0x0404; break; - case XFER_SW_DMA_1: - drive->id->dma_1word |= 0x0202; break; - case XFER_SW_DMA_0: - drive->id->dma_1word |= 0x0101; break; - default: break; - } - if (!drive->init_speed) - drive->init_speed = command; - drive->current_speed = command; - } - enable_irq(hwif->irq); - return result; -} - /* * Old tuning functions (called on hdparm -p), sets up drive PIO timings */ @@ -685,7 +610,7 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) drive->name, pio, *timings); #endif - if (pmac_ide_do_setfeature(drive, XFER_PIO_0 + pio)) + if (ide_config_drive_speed(drive, XFER_PIO_0 + pio)) return; pmac_ide_do_update_timings(drive); @@ -948,7 +873,7 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed) if (ret) return ret; - ret = pmac_ide_do_setfeature(drive, speed); + ret = ide_config_drive_speed(drive, speed); if (ret) return ret; @@ -1218,6 +1143,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; hwif->drives[0].unmask = 1; hwif->drives[1].unmask = 1; + hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA; hwif->pio_mask = ATA_PIO4; hwif->set_pio_mode = pmac_ide_set_pio_mode; if (pmif->kind == controller_un_ata6 diff --git a/include/linux/ide.h b/include/linux/ide.h index d86115e9aa2c..6bb621203f30 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1153,7 +1153,6 @@ extern void SELECT_MASK(ide_drive_t *, int); extern void QUIRK_LIST(ide_drive_t *); extern int drive_is_ready(ide_drive_t *); -int __ide_wait_stat(ide_drive_t *, u8, u8, unsigned long); /* * taskfile io for disks for now...and builds request from ide_ioctl @@ -1253,6 +1252,11 @@ enum { IDE_HFLAG_ABUSE_FAST_DEVSEL = (1 << 5), /* use 100-102 and 200-202 PIO values to set DMA modes */ IDE_HFLAG_ABUSE_DMA_MODES = (1 << 6), + /* + * keep DMA setting when programming PIO mode, may be used only + * for hosts which have separate PIO and DMA timings (ie. PMAC) + */ + IDE_HFLAG_SET_PIO_MODE_KEEP_DMA = (1 << 7), }; typedef struct ide_pci_device_s { -- cgit v1.2.3-55-g7522 From 254bb5503611da57240ed6df1cfe6d7f0f185027 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:50 +0200 Subject: ide-pmac: use ide_tune_dma() (take 2) * Add missing initialization of hwif->autodma and drive->autodma to pmac_ide_setup_dma(). * Use ide_tune_dma() in pmac_ide_dma_check(). While at it: * Fix pmac_ide_dma_check() return value if DMA mode is not programmed (should be "-1" otherwise ide_set_dma() will try to enable DMA). * Remove unnecessary drive->using_dma fiddling (->dma_off_quietly is always called before ide_set_dma() call and ide_set_dma() calls ->ide_dma_on if ->ide_dma_check returns "0"). v2: * No reason to blacklist all ide_floppy devices and the old code was always enabling DMA anyway (without even programming controller/device if the device was ide_floppy). Cc: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 24f73291c4d5..a1d24cd1293e 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1593,24 +1593,10 @@ pmac_ide_destroy_dmatable (ide_drive_t *drive) static int pmac_ide_dma_check(ide_drive_t *drive) { - int enable = 1; + if (ide_tune_dma(drive)) + return 0; - drive->using_dma = 0; - - if (drive->media == ide_floppy) - enable = 0; - if ((drive->id->capability & 1) == 0 && !__ide_dma_good_drive(drive)) - enable = 0; - if (__ide_dma_bad_drive(drive)) - enable = 0; - - if (enable) { - u8 mode = ide_max_dma_mode(drive); - - if (mode && pmac_ide_tune_chipset(drive, mode) == 0) - drive->using_dma = 1; - } - return 0; + return -1; } /* @@ -1844,7 +1830,10 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x00; break; - } + } + + hwif->autodma = 1; + hwif->drives[1].autodma = hwif->drives[0].autodma = hwif->autodma; } #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ -- cgit v1.2.3-55-g7522 From 0b46ff2ea2d817dc7883b80cd4e05ce41cce9158 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 13 Oct 2007 17:47:50 +0200 Subject: ide-pmac: fix PIO setup and enable autotune Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index a1d24cd1293e..313194a0f36e 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -535,7 +535,7 @@ pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port) static void pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) { - u32 *timings; + u32 *timings, t; unsigned accessTicks, recTicks; unsigned accessTime, recTime; pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data; @@ -546,6 +546,7 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) /* which drive is it ? */ timings = &pmif->timings[drive->select.b.unit & 0x01]; + t = *timings; cycle_time = ide_pio_cycle_time(drive, pio); @@ -553,14 +554,14 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) case controller_sh_ata6: { /* 133Mhz cell */ u32 tr = kauai_lookup_timing(shasta_pio_timings, cycle_time); - *timings = ((*timings) & ~TR_133_PIOREG_PIO_MASK) | tr; + t = (t & ~TR_133_PIOREG_PIO_MASK) | tr; break; } case controller_un_ata6: case controller_k2_ata6: { /* 100Mhz cell */ u32 tr = kauai_lookup_timing(kauai_pio_timings, cycle_time); - *timings = ((*timings) & ~TR_100_PIOREG_PIO_MASK) | tr; + t = (t & ~TR_100_PIOREG_PIO_MASK) | tr; break; } case controller_kl_ata4: @@ -574,9 +575,9 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) accessTicks = min(accessTicks, 0x1fU); recTicks = SYSCLK_TICKS_66(recTime); recTicks = min(recTicks, 0x1fU); - *timings = ((*timings) & ~TR_66_PIO_MASK) | - (accessTicks << TR_66_PIO_ACCESS_SHIFT) | - (recTicks << TR_66_PIO_RECOVERY_SHIFT); + t = (t & ~TR_66_PIO_MASK) | + (accessTicks << TR_66_PIO_ACCESS_SHIFT) | + (recTicks << TR_66_PIO_RECOVERY_SHIFT); break; default: { /* 33Mhz cell */ @@ -596,11 +597,11 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) recTicks--; /* guess, but it's only for PIO0, so... */ ebit = 1; } - *timings = ((*timings) & ~TR_33_PIO_MASK) | + t = (t & ~TR_33_PIO_MASK) | (accessTicks << TR_33_PIO_ACCESS_SHIFT) | (recTicks << TR_33_PIO_RECOVERY_SHIFT); if (ebit) - *timings |= TR_33_PIO_E; + t |= TR_33_PIO_E; break; } } @@ -613,6 +614,7 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) if (ide_config_drive_speed(drive, XFER_PIO_0 + pio)) return; + *timings = t; pmac_ide_do_update_timings(drive); } @@ -1143,6 +1145,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40; hwif->drives[0].unmask = 1; hwif->drives[1].unmask = 1; + hwif->drives[0].autotune = IDE_TUNE_AUTO; + hwif->drives[1].autotune = IDE_TUNE_AUTO; hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA; hwif->pio_mask = ATA_PIO4; hwif->set_pio_mode = pmac_ide_set_pio_mode; -- cgit v1.2.3-55-g7522 From 75d7d963e3dcf8a1410000ab246921709e276cd9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:50 +0200 Subject: icside: use ide_tune_dma() * Add "good DMA drives" hack for icside to ide-dma.c::ide_find_dma_mode() (in the long-term it should be either removed or generalized for all hosts). * Use ide_tune_dma() in icside.c::icside_dma_check(). This results in the following changes in behavior: - pre-EIDE SWDMA modes are now also respected - drive->autodma is checked instead of hwif->autodma (doesn't really matter as icside sets both to "1") * Make ide-dma.c::__ide_dma_good_drive() static and drop "__" prefix. Cc: Russell King Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/arm/icside.c | 37 +++---------------------------------- drivers/ide/ide-dma.c | 23 ++++++++++++++--------- include/linux/ide.h | 1 - 3 files changed, 17 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 7912a471f10d..110e52377c71 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -313,41 +313,10 @@ static int icside_dma_on(ide_drive_t *drive) static int icside_dma_check(ide_drive_t *drive) { - struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); - int xfer_mode = 0; - - if (!(id->capability & 1) || !hwif->autodma) - goto out; - - /* - * Consult the list of known "bad" drives - */ - if (__ide_dma_bad_drive(drive)) - goto out; - - /* - * Enable DMA on any drive that has multiword DMA - */ - if (id->field_valid & 2) { - xfer_mode = ide_max_dma_mode(drive); - goto out; - } - - /* - * Consult the list of known "good" drives - */ - if (__ide_dma_good_drive(drive)) { - if (id->eide_dma_time > 150) - goto out; - xfer_mode = XFER_MW_DMA_1; - } - -out: - if (xfer_mode == 0) - return -1; + if (ide_tune_dma(drive)) + return 0; - return icside_set_speed(drive, xfer_mode) ? -1 : 0; + return -1; } static int icside_dma_end(ide_drive_t *drive) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 6000c08f51ba..05781faaddd8 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -169,6 +169,11 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive) EXPORT_SYMBOL_GPL(ide_dma_intr); +static int ide_dma_good_drive(ide_drive_t *drive) +{ + return ide_in_drive_list(drive->id, drive_whitelist); +} + #ifdef CONFIG_BLK_DEV_IDEDMA_PCI /** * ide_build_sglist - map IDE scatter gather for DMA I/O @@ -357,7 +362,7 @@ static int config_drive_for_dma (ide_drive_t *drive) return 0; /* Consult the list of known "good" drives */ - if (__ide_dma_good_drive(drive)) + if (ide_dma_good_drive(drive)) return 0; } @@ -639,14 +644,6 @@ int __ide_dma_bad_drive (ide_drive_t *drive) EXPORT_SYMBOL(__ide_dma_bad_drive); -int __ide_dma_good_drive (ide_drive_t *drive) -{ - struct hd_driveid *id = drive->id; - return ide_in_drive_list(id, drive_whitelist); -} - -EXPORT_SYMBOL(__ide_dma_good_drive); - static const u8 xfer_mode_bases[] = { XFER_UDMA_0, XFER_MW_DMA_0, @@ -746,6 +743,14 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode) } } + if (hwif->chipset == ide_acorn && mode == 0) { + /* + * is this correct? + */ + if (ide_dma_good_drive(drive) && drive->id->eide_dma_time < 150) + mode = XFER_MW_DMA_1; + } + printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode); return min(mode, req_mode); diff --git a/include/linux/ide.h b/include/linux/ide.h index 6bb621203f30..a7d8b4bc7681 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1296,7 +1296,6 @@ int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); #ifdef CONFIG_BLK_DEV_IDEDMA int __ide_dma_bad_drive(ide_drive_t *); -int __ide_dma_good_drive(ide_drive_t *); u8 ide_find_dma_mode(ide_drive_t *, u8); -- cgit v1.2.3-55-g7522 From 0f458943e0247906b7a3f534f9e9e7ff3d901296 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:51 +0200 Subject: au1xxx: fix au1xxx_set_pio_mode() Set transfer mode on the device before programming the host controller for the new timings (matches what auide_tune_chipset() is doing wrt DMA modes). Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/mips/au1xxx-ide.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index 85819ae20602..c319f6163127 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -103,7 +103,9 @@ static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio) { int mem_sttime; int mem_stcfg; - u8 speed; + + if (ide_config_drive_speed(drive, pio + XFER_PIO_0)) + return; mem_sttime = 0; mem_stcfg = au_readl(MEM_STCFG2); @@ -164,9 +166,6 @@ static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio) au_writel(mem_sttime,MEM_STTIME2); au_writel(mem_stcfg,MEM_STCFG2); - - speed = pio + XFER_PIO_0; - ide_config_drive_speed(drive, speed); } static int auide_tune_chipset(ide_drive_t *drive, const u8 speed) -- cgit v1.2.3-55-g7522 From 3b4024d4297279ef85631f3c19a6fa4312b4c401 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:51 +0200 Subject: amd74xx/via82cxxx: check ide_config_drive_speed() return value * Check ide_config_drive_speed() return value. * While at also call ide_config_drive_speed() if the transfer mode is XFER_PIO_SLOW (this case happens iff the transfer mode has already been set on the device by ide-proc.c::set_xfer_rate()) and remove redundant setting of ->{init,current}_speed. * Bump driver version. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/amd74xx.c | 10 +++------- drivers/ide/pci/via82cxxx.c | 10 +++------- 2 files changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 513205e52ad2..71d2c670e97e 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -1,5 +1,5 @@ /* - * Version 2.22 + * Version 2.23 * * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04 * IDE driver for Linux. @@ -240,8 +240,8 @@ static int amd_set_drive(ide_drive_t *drive, const u8 speed) struct ide_timing t, p; int T, UT; - if (speed != XFER_PIO_SLOW) - ide_config_drive_speed(drive, speed); + if (ide_config_drive_speed(drive, speed)) + return 1; T = 1000000000 / amd_clock; UT = (amd_config->udma_mask == ATA_UDMA2) ? T : (T / 2); @@ -258,10 +258,6 @@ static int amd_set_drive(ide_drive_t *drive, const u8 speed) amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); - if (!drive->init_speed) - drive->init_speed = speed; - drive->current_speed = speed; - return 0; } diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 378feb491ec4..ac094e51d2bf 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -1,6 +1,6 @@ /* * - * Version 3.48 + * Version 3.49 * * VIA IDE driver for Linux. Supported southbridges: * @@ -165,8 +165,8 @@ static int via_set_drive(ide_drive_t *drive, const u8 speed) struct ide_timing t, p; unsigned int T, UT; - if (speed != XFER_PIO_SLOW) - ide_config_drive_speed(drive, speed); + if (ide_config_drive_speed(drive, speed)) + return 1; T = 1000000000 / via_clock; @@ -187,10 +187,6 @@ static int via_set_drive(ide_drive_t *drive, const u8 speed) via_set_speed(HWIF(drive), drive->dn, &t); - if (!drive->init_speed) - drive->init_speed = speed; - drive->current_speed = speed; - return 0; } -- cgit v1.2.3-55-g7522 From 249aa4ff1778b318346d8ba4a7fa62c169a29410 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:51 +0200 Subject: cs5535: check ide_config_drive_speed() return value Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5535.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 383b7eccbcbb..5d1be657adca 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -141,7 +141,9 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed) */ static int cs5535_set_drive(ide_drive_t *drive, u8 speed) { - ide_config_drive_speed(drive, speed); + if (ide_config_drive_speed(drive, speed)) + return 1; + cs5535_set_speed(drive, speed); return 0; @@ -157,7 +159,9 @@ static int cs5535_set_drive(ide_drive_t *drive, u8 speed) static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio) { - ide_config_drive_speed(drive, XFER_PIO_0 + pio); + if (ide_config_drive_speed(drive, XFER_PIO_0 + pio)) + return; + cs5535_set_speed(drive, XFER_PIO_0 + pio); } -- cgit v1.2.3-55-g7522 From 6e249395eace037ef139a1c8996b31e3797e412a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:51 +0200 Subject: pdc202xx_new: check ide_config_drive_speed() return value Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/pdc202xx_new.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 5fb1eedc8194..95600681bd3a 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -150,13 +150,13 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); u8 adj = (drive->dn & 1) ? 0x08 : 0x00; - int err; /* * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will * automatically set the timing registers based on 100 MHz PLL output. */ - err = ide_config_drive_speed(drive, speed); + if (ide_config_drive_speed(drive, speed)) + return 1; /* * As we set up the PLL to output 133 MHz for UltraDMA/133 capable @@ -212,7 +212,7 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed) set_indexed_reg(hwif, 0x10 + adj, tmp & 0x7f); } - return err; + return 0; } static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio) -- cgit v1.2.3-55-g7522 From 88b2b32babd46cd54d2de4d17eb869aea3383e11 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:51 +0200 Subject: ide: move ide_config_drive_speed() calls to upper layers (take 2) * Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16. * Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program the host for the transfer mode after programming the device. Set it in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac and via82cxxx host drivers. * Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely skip programming of host/device for the transfer mode ("smart" hosts). Set it in it821x host driver and check it in ide_tune_dma(). * Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all direct ->set_pio_mode/->speedproc users to use these helpers. * Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc methods to callers. * Rename ->speedproc method to ->set_dma_mode, make it void and update all implementations accordingly. * Update ide_set_xfer_rate() comments. * Unexport ide_config_drive_speed(). v2: * Fix issues noticed by Sergei: - export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt to setting DMA modes from sc1200_set_pio_mode() to do_special() - check IDE_HFLAG_NO_SET_MODE in ide_tune_dma() - check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode() - check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode() - return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL - don't set ->set_{pio,dma}_mode on it821x in "smart" mode - fix build problem in pmac.c - minor fixes in au1xxx-ide.c/cs5530.c/siimage.c - improve patch description Changes in behavior caused by this patch: - HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change PIO mode if it821x controller is in "smart" mode - removal of two debugging printk-s (from cs5530.c and sc1200.c) - transfer modes 0x00-0x07 passed from user space may be programmed twice on the device (not really an issue since 0x00 is not supported correctly by any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid) Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/arm/icside.c | 8 ++-- drivers/ide/cris/ide-cris.c | 8 +--- drivers/ide/ide-dma.c | 5 ++- drivers/ide/ide-iops.c | 3 -- drivers/ide/ide-lib.c | 78 ++++++++++++++++++++++++++++-------- drivers/ide/ide.c | 2 +- drivers/ide/mips/au1xxx-ide.c | 27 +++---------- drivers/ide/pci/aec62xx.c | 12 +++--- drivers/ide/pci/alim15x3.c | 33 ++++------------ drivers/ide/pci/amd74xx.c | 20 ++++------ drivers/ide/pci/atiixp.c | 33 ++++++---------- drivers/ide/pci/cmd64x.c | 9 ++--- drivers/ide/pci/cs5520.c | 13 +----- drivers/ide/pci/cs5530.c | 50 +++++------------------ drivers/ide/pci/cs5535.c | 28 +++++-------- drivers/ide/pci/hpt34x.c | 9 ++--- drivers/ide/pci/hpt366.c | 18 ++++----- drivers/ide/pci/it8213.c | 34 ++++++---------- drivers/ide/pci/it821x.c | 90 ++++++++++++++---------------------------- drivers/ide/pci/jmicron.c | 15 +++---- drivers/ide/pci/pdc202xx_new.c | 24 +++++------ drivers/ide/pci/pdc202xx_old.c | 9 ++--- drivers/ide/pci/piix.c | 46 +++++++-------------- drivers/ide/pci/sc1200.c | 32 +++------------ drivers/ide/pci/scc_pata.c | 28 +++++-------- drivers/ide/pci/serverworks.c | 14 ++----- drivers/ide/pci/sgiioc4.c | 8 +--- drivers/ide/pci/siimage.c | 29 ++++++-------- drivers/ide/pci/sis5513.c | 16 ++------ drivers/ide/pci/sl82c105.c | 23 +++-------- drivers/ide/pci/slc90e66.c | 18 +++------ drivers/ide/pci/tc86c001.c | 9 ++--- drivers/ide/pci/triflex.c | 10 ++--- drivers/ide/pci/via82cxxx.c | 23 +++++------ drivers/ide/ppc/pmac.c | 24 +++-------- include/linux/ide.h | 17 +++++--- 36 files changed, 304 insertions(+), 521 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 110e52377c71..bd1f5b670378 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -248,7 +248,7 @@ static void icside_build_sglist(ide_drive_t *drive, struct request *rq) * MW1 80 50 50 150 C * MW2 70 25 25 120 C */ -static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode) +static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) { int cycle_time, use_dma_info = 0; @@ -273,7 +273,7 @@ static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode) cycle_time = 480; break; default: - return 1; + return; } /* @@ -287,8 +287,6 @@ static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode) printk("%s: %s selected (peak %dMB/s)\n", drive->name, ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); - - return ide_config_drive_speed(drive, xfer_mode); } static void icside_dma_host_off(ide_drive_t *drive) @@ -433,7 +431,7 @@ static void icside_dma_init(ide_hwif_t *hwif) hwif->dmatable_cpu = NULL; hwif->dmatable_dma = 0; - hwif->speedproc = icside_set_speed; + hwif->set_dma_mode = icside_set_dma_mode; hwif->autodma = 1; hwif->ide_dma_check = icside_dma_check; diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index 4bb42b30bfc0..2b4d2a0ae5c2 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -716,11 +716,9 @@ static void cris_set_pio_mode(ide_drive_t *drive, const u8 pio) } cris_ide_set_speed(TYPE_PIO, setup, strobe, hold); - - (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } -static int speed_cris_ide(ide_drive_t *drive, const u8 speed) +static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed) { int cyc = 0, dvs = 0, strobe = 0, hold = 0; @@ -759,8 +757,6 @@ static int speed_cris_ide(ide_drive_t *drive, const u8 speed) cris_ide_set_speed(TYPE_UDMA, cyc, dvs, 0); else cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); - - return ide_config_drive_speed(drive, speed); } void __init @@ -791,7 +787,7 @@ init_e100_ide (void) hwif->mmio = 1; hwif->chipset = ide_etrax100; hwif->set_pio_mode = &cris_set_pio_mode; - hwif->speedproc = &speed_cris_ide; + hwif->set_dma_mode = &cris_set_dma_mode; hwif->ata_input_data = &cris_ide_input_data; hwif->ata_output_data = &cris_ide_output_data; hwif->atapi_input_bytes = &cris_atapi_input_bytes; diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 05781faaddd8..b453211ee0fc 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -774,7 +774,10 @@ int ide_tune_dma(ide_drive_t *drive) if (!speed) return 0; - if (drive->hwif->speedproc(drive, speed)) + if (drive->hwif->host_flags & IDE_HFLAG_NO_SET_MODE) + return 0; + + if (ide_set_dma_mode(drive, speed)) return 0; return 1; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index e5fc2e505959..f5e73e2950d4 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -862,9 +862,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) return error; } -EXPORT_SYMBOL(ide_config_drive_speed); - - /* * This should get invoked any time we exit the driver to * wait for an interrupt response from a drive. handler() points diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index d97390c0543b..0e2562f0f74e 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -349,7 +349,7 @@ void ide_set_pio(ide_drive_t *drive, u8 req_pio) drive->name, host_pio, req_pio, req_pio == 255 ? "(auto-tune)" : "", pio); - hwif->set_pio_mode(drive, pio); + (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio); } EXPORT_SYMBOL_GPL(ide_set_pio); @@ -378,39 +378,83 @@ void ide_toggle_bounce(ide_drive_t *drive, int on) blk_queue_bounce_limit(drive->queue, addr); } +int ide_set_pio_mode(ide_drive_t *drive, const u8 mode) +{ + ide_hwif_t *hwif = drive->hwif; + + if (hwif->set_pio_mode == NULL) + return -1; + + /* + * TODO: temporary hack for some legacy host drivers that didn't + * set transfer mode on the device in ->set_pio_mode method... + */ + if (hwif->set_dma_mode == NULL) { + hwif->set_pio_mode(drive, mode - XFER_PIO_0); + return 0; + } + + if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { + if (ide_config_drive_speed(drive, mode)) + return -1; + hwif->set_pio_mode(drive, mode - XFER_PIO_0); + return 0; + } else { + hwif->set_pio_mode(drive, mode - XFER_PIO_0); + return ide_config_drive_speed(drive, mode); + } +} + +int ide_set_dma_mode(ide_drive_t *drive, const u8 mode) +{ + ide_hwif_t *hwif = drive->hwif; + + if (hwif->set_dma_mode == NULL) + return -1; + + if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { + if (ide_config_drive_speed(drive, mode)) + return -1; + hwif->set_dma_mode(drive, mode); + return 0; + } else { + hwif->set_dma_mode(drive, mode); + return ide_config_drive_speed(drive, mode); + } +} + +EXPORT_SYMBOL_GPL(ide_set_dma_mode); + /** * ide_set_xfer_rate - set transfer rate * @drive: drive to set - * @speed: speed to attempt to set + * @rate: speed to attempt to set * * General helper for setting the speed of an IDE device. This * function knows about user enforced limits from the configuration - * which speedproc() does not. High level drivers should never - * invoke speedproc() directly. + * which ->set_pio_mode/->set_dma_mode does not. */ - + int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) { ide_hwif_t *hwif = drive->hwif; - if (hwif->speedproc == NULL) + if (hwif->set_dma_mode == NULL) return -1; rate = ide_rate_filter(drive, rate); - if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) { - if (hwif->set_pio_mode) - hwif->set_pio_mode(drive, rate - XFER_PIO_0); + if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) + return ide_set_pio_mode(drive, rate); - /* - * FIXME: this is incorrect to return zero here but - * since all users of ide_set_xfer_rate() ignore - * the return value it is not a problem currently - */ - return 0; - } + /* + * TODO: transfer modes 0x00-0x07 passed from the user-space are + * currently handled here which needs fixing (please note that such + * case could happen iff the transfer mode has already been set on + * the device by ide-proc.c::set_xfer_rate()). + */ - return hwif->speedproc(drive, rate); + return ide_set_dma_mode(drive, rate); } static void ide_dump_opcode(ide_drive_t *drive) diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index a96a8b1b3539..5c0e4078b5cb 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -397,7 +397,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) #endif hwif->set_pio_mode = tmp_hwif->set_pio_mode; - hwif->speedproc = tmp_hwif->speedproc; + hwif->set_dma_mode = tmp_hwif->set_dma_mode; hwif->mdma_filter = tmp_hwif->mdma_filter; hwif->udma_filter = tmp_hwif->udma_filter; hwif->selectproc = tmp_hwif->selectproc; diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index c319f6163127..aebde49365d1 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -101,14 +101,7 @@ void auide_outsw(unsigned long port, void *addr, u32 count) static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio) { - int mem_sttime; - int mem_stcfg; - - if (ide_config_drive_speed(drive, pio + XFER_PIO_0)) - return; - - mem_sttime = 0; - mem_stcfg = au_readl(MEM_STCFG2); + int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2); /* set pio mode! */ switch(pio) { @@ -168,13 +161,9 @@ static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio) au_writel(mem_stcfg,MEM_STCFG2); } -static int auide_tune_chipset(ide_drive_t *drive, const u8 speed) +static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed) { - int mem_sttime; - int mem_stcfg; - - mem_sttime = 0; - mem_stcfg = au_readl(MEM_STCFG2); + int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2); switch(speed) { #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA @@ -210,16 +199,11 @@ static int auide_tune_chipset(ide_drive_t *drive, const u8 speed) break; #endif default: - return 1; + return; } - if (ide_config_drive_speed(drive, speed)) - return 1; - au_writel(mem_sttime,MEM_STTIME2); au_writel(mem_stcfg,MEM_STCFG2); - - return 0; } /* @@ -681,6 +665,7 @@ static int au_ide_probe(struct device *dev) #endif hwif->pio_mask = ATA_PIO4; + hwif->host_flags = IDE_HFLAG_POST_SET_MODE; hwif->noprobe = 0; hwif->drives[0].unmask = 1; @@ -701,7 +686,7 @@ static int au_ide_probe(struct device *dev) #endif hwif->set_pio_mode = &au1xxx_set_pio_mode; - hwif->speedproc = &auide_tune_chipset; + hwif->set_dma_mode = &auide_set_dma_mode; #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA hwif->dma_off_quietly = &auide_dma_off_quietly; diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index 0d5f62c5dfae..d6cb2d5143c8 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -87,7 +87,7 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr return chipset_table->ultra_settings; } -static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed) +static void aec6210_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -111,10 +111,9 @@ static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed) tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn)))); pci_write_config_byte(dev, 0x54, tmp2); local_irq_restore(flags); - return(ide_config_drive_speed(drive, speed)); } -static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed) +static void aec6260_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -135,12 +134,11 @@ static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed) tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit)))); pci_write_config_byte(dev, (0x44|hwif->channel), tmp2); local_irq_restore(flags); - return(ide_config_drive_speed(drive, speed)); } static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio) { - (void) HWIF(drive)->speedproc(drive, pio + XFER_PIO_0); + drive->hwif->set_dma_mode(drive, pio + XFER_PIO_0); } static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) @@ -205,9 +203,9 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { if(hwif->mate) hwif->mate->serialized = hwif->serialized = 1; - hwif->speedproc = &aec6210_tune_chipset; + hwif->set_dma_mode = &aec6210_set_mode; } else - hwif->speedproc = &aec6260_tune_chipset; + hwif->set_dma_mode = &aec6260_set_mode; if (!hwif->dma_base) { hwif->drives[0].autotune = hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index d04b966b4347..88f084eae193 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -283,14 +283,14 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count) #endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */ /** - * ali_tune_pio - set host controller for PIO mode + * ali_set_pio_mode - set host controller for PIO mode * @drive: drive * @pio: PIO mode number * * Program the controller for the given PIO mode. */ -static void ali_tune_pio(ide_drive_t *drive, const u8 pio) +static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -357,21 +357,6 @@ static void ali_tune_pio(ide_drive_t *drive, const u8 pio) */ } -/** - * ali_set_pio_mode - set up drive for PIO mode - * @drive: drive to tune - * @pio: desired mode - * - * Program the controller with the desired PIO timing for the given drive. - * Then set up the drive itself. - */ - -static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - ali_tune_pio(drive, pio); - (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} - /** * ali_udma_filter - compute UDMA mask * @drive: IDE device @@ -401,15 +386,14 @@ static u8 ali_udma_filter(ide_drive_t *drive) } /** - * ali15x3_tune_chipset - set up chipset/drive for new speed - * @drive: drive to configure for - * @speed: desired speed + * ali_set_dma_mode - set host controller for DMA mode + * @drive: drive + * @speed: DMA mode * * Configure the hardware for the desired IDE transfer mode. - * We also do the needed drive configuration through helpers */ -static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed) +static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -419,7 +403,7 @@ static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed) int m5229_udma = (hwif->channel) ? 0x57 : 0x56; if (speed < XFER_PIO_0) - return 1; + return; if (speed == XFER_UDMA_6) speed1 = 0x47; @@ -450,7 +434,6 @@ static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed) pci_write_config_byte(dev, 0x4b, tmpbyte); } } - return (ide_config_drive_speed(drive, speed)); } /** @@ -699,7 +682,7 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) { hwif->autodma = 0; hwif->set_pio_mode = &ali_set_pio_mode; - hwif->speedproc = &ali15x3_tune_chipset; + hwif->set_dma_mode = &ali_set_dma_mode; hwif->udma_filter = &ali_udma_filter; /* don't use LBA48 DMA on ALi devices before rev 0xC5 */ diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 71d2c670e97e..6ff4089a2379 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -229,20 +229,16 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi } /* - * amd_set_drive() computes timing values configures the drive and - * the chipset to a desired transfer mode. It also can be called - * by upper layers. + * amd_set_drive() computes timing values and configures the chipset + * to a desired transfer mode. It also can be called by upper layers. */ -static int amd_set_drive(ide_drive_t *drive, const u8 speed) +static void amd_set_drive(ide_drive_t *drive, const u8 speed) { ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); struct ide_timing t, p; int T, UT; - if (ide_config_drive_speed(drive, speed)) - return 1; - T = 1000000000 / amd_clock; UT = (amd_config->udma_mask == ATA_UDMA2) ? T : (T / 2); @@ -257,8 +253,6 @@ static int amd_set_drive(ide_drive_t *drive, const u8 speed) if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15; amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); - - return 0; } /* @@ -395,7 +389,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) hwif->autodma = 0; hwif->set_pio_mode = &amd_set_pio_mode; - hwif->speedproc = &amd_set_drive; + hwif->set_dma_mode = &amd_set_drive; for (i = 0; i < 2; i++) { hwif->drives[i].io_32bit = 1; @@ -437,7 +431,8 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ .bootable = ON_BOARD, \ .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \ - | IDE_HFLAG_PIO_NO_DOWNGRADE, \ + | IDE_HFLAG_PIO_NO_DOWNGRADE \ + | IDE_HFLAG_POST_SET_MODE, \ .pio_mask = ATA_PIO5, \ } @@ -450,7 +445,8 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \ .bootable = ON_BOARD, \ .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \ - | IDE_HFLAG_PIO_NO_DOWNGRADE, \ + | IDE_HFLAG_PIO_NO_DOWNGRADE \ + | IDE_HFLAG_POST_SET_MODE, \ .pio_mask = ATA_PIO5, \ } diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 178876a3afca..0eb97f021d39 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -122,14 +122,14 @@ static void atiixp_dma_host_off(ide_drive_t *drive) } /** - * atiixp_tune_pio - tune a drive attached to a ATIIXP - * @drive: drive to tune - * @pio: desired PIO mode + * atiixp_set_pio_mode - set host controller for PIO mode + * @drive: drive + * @pio: PIO mode number * * Set the interface PIO mode. */ -static void atiixp_tune_pio(ide_drive_t *drive, u8 pio) +static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio) { struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; @@ -153,23 +153,16 @@ static void atiixp_tune_pio(ide_drive_t *drive, u8 pio) spin_unlock_irqrestore(&atiixp_lock, flags); } -static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - atiixp_tune_pio(drive, pio); - (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} - /** - * atiixp_tune_chipset - tune a ATIIXP interface - * @drive: IDE drive to tune - * @speed: speed to configure + * atiixp_set_dma_mode - set host controller for DMA mode + * @drive: drive + * @speed: DMA mode * - * Set a ATIIXP interface channel to the desired speeds. This involves - * requires the right timing data into the ATIIXP configuration space - * then setting the drive parameters appropriately + * Set a ATIIXP host controller to the desired DMA mode. This involves + * programming the right timing data into the PCI configuration space. */ -static int atiixp_speedproc(ide_drive_t *drive, const u8 speed) +static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed) { struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; @@ -204,9 +197,7 @@ static int atiixp_speedproc(ide_drive_t *drive, const u8 speed) else pio = speed - XFER_PIO_0; - atiixp_tune_pio(drive, pio); - - return ide_config_drive_speed(drive, speed); + atiixp_set_pio_mode(drive, pio); } /** @@ -249,7 +240,7 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) hwif->autodma = 0; hwif->set_pio_mode = &atiixp_set_pio_mode; - hwif->speedproc = &atiixp_speedproc; + hwif->set_dma_mode = &atiixp_set_dma_mode; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 0b568c60f926..d50f15e34b80 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -280,10 +280,9 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio) return; cmd64x_tune_pio(drive, pio); - (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); } -static int cmd64x_tune_chipset(ide_drive_t *drive, const u8 speed) +static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -324,13 +323,11 @@ static int cmd64x_tune_chipset(ide_drive_t *drive, const u8 speed) program_cycle_times(drive, 480, 215); break; default: - return 1; + return; } if (speed >= XFER_SW_DMA_0) (void) pci_write_config_byte(dev, pciU, regU); - - return ide_config_drive_speed(drive, speed); } static int cmd64x_config_drive_for_dma (ide_drive_t *drive) @@ -524,7 +521,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) pci_read_config_byte(dev, PCI_REVISION_ID, &rev); hwif->set_pio_mode = &cmd64x_set_pio_mode; - hwif->speedproc = &cmd64x_tune_chipset; + hwif->set_dma_mode = &cmd64x_set_dma_mode; hwif->drives[0].autotune = hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 1217d2a747fb..cb2a10203dc4 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -96,22 +96,13 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) reg = inb(hwif->dma_base + 0x02 + 8*controller); reg |= 1<<((drive->dn&1)+5); outb(reg, hwif->dma_base + 0x02 + 8*controller); - - (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } -static int cs5520_tune_chipset(ide_drive_t *drive, const u8 speed) +static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) { printk(KERN_ERR "cs55x0: bad ide timing.\n"); cs5520_set_pio_mode(drive, 0); - - /* - * FIXME: this is incorrect to return zero here but - * since all users of ide_set_xfer_rate() ignore - * the return value it is not a problem currently - */ - return 0; } static int cs5520_config_drive_xfer_rate(ide_drive_t *drive) @@ -150,7 +141,7 @@ static int cs5520_dma_on(ide_drive_t *drive) static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) { hwif->set_pio_mode = &cs5520_set_pio_mode; - hwif->speedproc = &cs5520_tune_chipset; + hwif->set_dma_mode = &cs5520_set_dma_mode; hwif->ide_dma_check = &cs5520_config_drive_xfer_rate; hwif->ide_dma_on = &cs5520_dma_on; diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 741507b4cd93..e4121577cef0 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -30,22 +30,6 @@ #include #include -/** - * cs5530_xfer_set_mode - set a new transfer mode at the drive - * @drive: drive to tune - * @mode: new mode - * - * Logging wrapper to the IDE driver speed configuration. This can - * probably go away now. - */ - -static int cs5530_set_xfer_mode (ide_drive_t *drive, u8 mode) -{ - printk(KERN_DEBUG "%s: cs5530_set_xfer_mode(%s)\n", - drive->name, ide_xfer_verbose(mode)); - return (ide_config_drive_speed(drive, mode)); -} - /* * Here are the standard PIO mode 0-4 timings for each "format". * Format-0 uses fast data reg timings, with slower command reg timings. @@ -62,20 +46,12 @@ static unsigned int cs5530_pio_timings[2][5] = { #define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132) #define CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20)) -static void cs5530_tunepio(ide_drive_t *drive, u8 pio) -{ - unsigned long basereg = CS5530_BASEREG(drive->hwif); - unsigned int format = (inl(basereg + 4) >> 31) & 1; - - outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3)); -} - /** - * cs5530_set_pio_mode - set PIO mode + * cs5530_set_pio_mode - set host controller for PIO mode * @drive: drive * @pio: PIO mode number * - * Handles setting of PIO mode for both the chipset and drive. + * Handles setting of PIO mode for the chipset. * * The init_hwif_cs5530() routine guarantees that all drives * will have valid default PIO timings set up before we get here. @@ -83,8 +59,10 @@ static void cs5530_tunepio(ide_drive_t *drive, u8 pio) static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio) { - if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) - cs5530_tunepio(drive, pio); + unsigned long basereg = CS5530_BASEREG(drive->hwif); + unsigned int format = (inl(basereg + 4) >> 31) & 1; + + outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3)); } /** @@ -142,20 +120,11 @@ static int cs5530_config_dma(ide_drive_t *drive) return 1; } -static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode) +static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode) { unsigned long basereg; unsigned int reg, timings = 0; - /* - * Tell the drive to switch to the new mode; abort on failure. - */ - if (cs5530_set_xfer_mode(drive, mode)) - return 1; /* failure */ - - /* - * Now tune the chipset to match the drive: - */ switch (mode) { case XFER_UDMA_0: timings = 0x00921250; break; case XFER_UDMA_1: timings = 0x00911140; break; @@ -180,8 +149,6 @@ static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode) outl(reg, basereg + 4); /* write drive0 config register */ outl(timings, basereg + 12); /* write drive1 config register */ } - - return 0; /* success */ } /** @@ -299,7 +266,7 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) hwif->serialized = hwif->mate->serialized = 1; hwif->set_pio_mode = &cs5530_set_pio_mode; - hwif->speedproc = &cs5530_tune_chipset; + hwif->set_dma_mode = &cs5530_set_dma_mode; basereg = CS5530_BASEREG(hwif); d0_timings = inl(basereg + 0); @@ -340,6 +307,7 @@ static ide_pci_device_t cs5530_chipset __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, .pio_mask = ATA_PIO4, + .host_flags = IDE_HFLAG_POST_SET_MODE, }; static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index 5d1be657adca..da606ba6d28c 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -131,26 +131,21 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed) } } -/**** - * cs5535_set_drive - Configure the drive to the new speed - * @drive: Drive to set up - * @speed: desired speed +/** + * cs5535_set_dma_mode - set host controller for DMA mode + * @drive: drive + * @speed: DMA mode * - * cs5535_set_drive() configures the drive and the chipset to a - * new speed. It also can be called by upper layers. + * Programs the chipset for DMA mode. */ -static int cs5535_set_drive(ide_drive_t *drive, u8 speed) -{ - if (ide_config_drive_speed(drive, speed)) - return 1; +static void cs5535_set_dma_mode(ide_drive_t *drive, const u8 speed) +{ cs5535_set_speed(drive, speed); - - return 0; } /** - * cs5535_set_pio_mode - PIO setup + * cs5535_set_pio_mode - set host controller for PIO mode * @drive: drive * @pio: PIO mode number * @@ -159,9 +154,6 @@ static int cs5535_set_drive(ide_drive_t *drive, u8 speed) static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio) { - if (ide_config_drive_speed(drive, XFER_PIO_0 + pio)) - return; - cs5535_set_speed(drive, XFER_PIO_0 + pio); } @@ -203,7 +195,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif) hwif->autodma = 0; hwif->set_pio_mode = &cs5535_set_pio_mode; - hwif->speedproc = &cs5535_set_drive; + hwif->set_dma_mode = &cs5535_set_dma_mode; hwif->ide_dma_check = &cs5535_dma_check; hwif->atapi_dma = 1; @@ -227,7 +219,7 @@ static ide_pci_device_t cs5535_chipset __devinitdata = { .init_hwif = init_hwif_cs5535, .autodma = AUTODMA, .bootable = ON_BOARD, - .host_flags = IDE_HFLAG_SINGLE, + .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE, .pio_mask = ATA_PIO4, }; diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index a1bb10188fe5..218852aaf22a 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -43,7 +43,7 @@ #define HPT343_DEBUG_DRIVE_INFO 0 -static int hpt34x_tune_chipset(ide_drive_t *drive, const u8 speed) +static void hpt34x_set_mode(ide_drive_t *drive, const u8 speed) { struct pci_dev *dev = HWIF(drive)->pci_dev; u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0; @@ -73,13 +73,11 @@ static int hpt34x_tune_chipset(ide_drive_t *drive, const u8 speed) drive->dn, reg1, tmp1, reg2, tmp2, hi_speed, lo_speed); #endif /* HPT343_DEBUG_DRIVE_INFO */ - - return(ide_config_drive_speed(drive, speed)); } static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio) { - (void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio)); + hpt34x_set_mode(drive, XFER_PIO_0 + pio); } static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) @@ -145,7 +143,8 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) hwif->autodma = 0; hwif->set_pio_mode = &hpt34x_set_pio_mode; - hwif->speedproc = &hpt34x_tune_chipset; + hwif->set_dma_mode = &hpt34x_set_mode; + hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 0e7d3b60d43c..8812a9bb032f 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -600,7 +600,7 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info) return (*info->settings)[i]; } -static int hpt36x_tune_chipset(ide_drive_t *drive, const u8 speed) +static void hpt36x_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -623,11 +623,9 @@ static int hpt36x_tune_chipset(ide_drive_t *drive, const u8 speed) new_itr &= ~0xc0000000; pci_write_config_dword(dev, itr_addr, new_itr); - - return ide_config_drive_speed(drive, speed); } -static int hpt37x_tune_chipset(ide_drive_t *drive, const u8 speed) +static void hpt37x_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -647,24 +645,22 @@ static int hpt37x_tune_chipset(ide_drive_t *drive, const u8 speed) if (speed < XFER_MW_DMA_0) new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ pci_write_config_dword(dev, itr_addr, new_itr); - - return ide_config_drive_speed(drive, speed); } -static int hpt3xx_tune_chipset(ide_drive_t *drive, u8 speed) +static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct hpt_info *info = pci_get_drvdata(hwif->pci_dev); if (info->chip_type >= HPT370) - return hpt37x_tune_chipset(drive, speed); + hpt37x_set_mode(drive, speed); else /* hpt368: hpt_minimum_revision(dev, 2) */ - return hpt36x_tune_chipset(drive, speed); + hpt36x_set_mode(drive, speed); } static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio) { - (void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio); + hpt3xx_set_mode(drive, XFER_PIO_0 + pio); } static int hpt3xx_quirkproc(ide_drive_t *drive) @@ -1257,7 +1253,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) hwif->select_data = hwif->channel ? 0x54 : 0x50; hwif->set_pio_mode = &hpt3xx_set_pio_mode; - hwif->speedproc = &hpt3xx_tune_chipset; + hwif->set_dma_mode = &hpt3xx_set_mode; hwif->quirkproc = &hpt3xx_quirkproc; hwif->intrproc = &hpt3xx_intrproc; hwif->maskproc = &hpt3xx_maskproc; diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c index 76e91ff9420b..ecf4ce078dce 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/pci/it8213.c @@ -48,15 +48,15 @@ static u8 it8213_dma_2_pio (u8 xfer_rate) { } } -/* - * it8213_tune_pio - tune a drive - * @drive: drive to tune - * @pio: desired PIO mode +/** + * it8213_set_pio_mode - set host controller for PIO mode + * @drive: drive + * @pio: PIO mode number * * Set the interface PIO mode. */ -static void it8213_tune_pio(ide_drive_t *drive, const u8 pio) +static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -105,21 +105,15 @@ static void it8213_tune_pio(ide_drive_t *drive, const u8 pio) spin_unlock_irqrestore(&tune_lock, flags); } -static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - it8213_tune_pio(drive, pio); - ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} - /** - * it8213_tune_chipset - set controller timings - * @drive: Drive to set up - * @speed: speed we want to achieve + * it8213_set_dma_mode - set host controller for DMA mode + * @drive: drive + * @speed: DMA mode * - * Tune the ITE chipset for the desired mode. + * Tune the ITE chipset for the DMA mode. */ -static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed) +static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -152,7 +146,7 @@ static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed) case XFER_SW_DMA_2: break; default: - return -1; + return; } if (speed >= XFER_UDMA_0) { @@ -182,9 +176,7 @@ static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed) pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); } - it8213_tune_pio(drive, it8213_dma_2_pio(speed)); - - return ide_config_drive_speed(drive, speed); + it8213_set_pio_mode(drive, it8213_dma_2_pio(speed)); } /** @@ -220,7 +212,7 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif) { u8 reg42h = 0; - hwif->speedproc = &it8213_tune_chipset; + hwif->set_dma_mode = &it8213_set_dma_mode; hwif->set_pio_mode = &it8213_set_pio_mode; hwif->autodma = 0; diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 758a98230cc5..1b69d82478c6 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -229,24 +229,24 @@ static void it821x_clock_strategy(ide_drive_t *drive) } /** - * it821x_tunepio - tune a drive - * @drive: drive to tune - * @pio: the desired PIO mode + * it821x_set_pio_mode - set host controller for PIO mode + * @drive: drive + * @pio: PIO mode number * - * Try to tune the drive/host to the desired PIO mode taking into - * the consideration the maximum PIO mode supported by the other - * device on the cable. + * Tune the host to the desired PIO mode taking into the consideration + * the maximum PIO mode supported by the other device on the cable. */ -static int it821x_tunepio(ide_drive_t *drive, u8 set_pio) +static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); int unit = drive->select.b.unit; ide_drive_t *pair = &hwif->drives[1 - unit]; + u8 set_pio = pio; /* Spec says 89 ref driver uses 88 */ - static u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; + static u16 pio_timings[]= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; /* @@ -261,22 +261,12 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio) set_pio = pair_pio; } - if (itdev->smart) - return 0; - /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */ itdev->want[unit][1] = pio_want[set_pio]; itdev->want[unit][0] = 1; /* PIO is lowest priority */ - itdev->pio[unit] = pio[set_pio]; + itdev->pio[unit] = pio_timings[set_pio]; it821x_clock_strategy(drive); it821x_program(drive, itdev->pio[unit]); - - return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio); -} - -static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - (void)it821x_tunepio(drive, pio); } /** @@ -405,47 +395,24 @@ static int it821x_dma_end(ide_drive_t *drive) } /** - * it821x_tune_chipset - set controller timings - * @drive: Drive to set up - * @speed: speed we want to achieve + * it821x_set_dma_mode - set host controller for DMA mode + * @drive: drive + * @speed: DMA mode * - * Tune the ITE chipset for the desired mode. + * Tune the ITE chipset for the desired DMA mode. */ -static int it821x_tune_chipset(ide_drive_t *drive, const u8 speed) +static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed) { - - ide_hwif_t *hwif = drive->hwif; - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - - if (itdev->smart == 0) { - switch (speed) { - /* MWDMA tuning is really hard because our MWDMA and PIO - timings are kept in the same place. We can switch in the - host dma on/off callbacks */ - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - it821x_tune_mwdma(drive, (speed - XFER_MW_DMA_0)); - break; - case XFER_UDMA_6: - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - it821x_tune_udma(drive, (speed - XFER_UDMA_0)); - break; - default: - return 1; - } - - return ide_config_drive_speed(drive, speed); - } - - /* don't touch anything in the smart mode */ - return 0; + /* + * MWDMA tuning is really hard because our MWDMA and PIO + * timings are kept in the same place. We can switch in the + * host dma on/off callbacks. + */ + if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_6) + it821x_tune_udma(drive, speed - XFER_UDMA_0); + else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) + it821x_tune_mwdma(drive, speed - XFER_MW_DMA_0); } /** @@ -629,14 +596,15 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n"); } - hwif->speedproc = &it821x_tune_chipset; - hwif->set_pio_mode = &it821x_set_pio_mode; + if (idev->smart == 0) { + hwif->set_pio_mode = &it821x_set_pio_mode; + hwif->set_dma_mode = &it821x_set_dma_mode; - /* MWDMA/PIO clock switching for pass through mode */ - if(!idev->smart) { + /* MWDMA/PIO clock switching for pass through mode */ hwif->dma_start = &it821x_dma_start; hwif->ide_dma_end = &it821x_dma_end; - } + } else + hwif->host_flags |= IDE_HFLAG_NO_SET_MODE; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index d379fbaf6743..582b4cae2b53 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -85,21 +85,18 @@ static u8 __devinit ata66_jmicron(ide_hwif_t *hwif) static void jmicron_set_pio_mode(ide_drive_t *drive, const u8 pio) { - ide_config_drive_speed(drive, XFER_PIO_0 + pio); } /** - * jmicron_tune_chipset - set controller timings - * @drive: Drive to set up - * @speed: speed we want to achieve + * jmicron_set_dma_mode - set host controller for DMA mode + * @drive: drive + * @mode: DMA mode * - * As the JMicron snoops for timings all we actually need to do is - * set the transfer mode on the device. + * As the JMicron snoops for timings we don't need to do anything here. */ -static int jmicron_tune_chipset(ide_drive_t *drive, const u8 speed) +static void jmicron_set_dma_mode(ide_drive_t *drive, const u8 mode) { - return ide_config_drive_speed(drive, speed); } /** @@ -129,8 +126,8 @@ static int jmicron_config_drive_for_dma (ide_drive_t *drive) static void __devinit init_hwif_jmicron(ide_hwif_t *hwif) { - hwif->speedproc = &jmicron_tune_chipset; hwif->set_pio_mode = &jmicron_set_pio_mode; + hwif->set_dma_mode = &jmicron_set_dma_mode; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 95600681bd3a..ad0bdcb0c02b 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -146,19 +146,16 @@ static struct udma_timing { { 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */ }; -static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed) +static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); u8 adj = (drive->dn & 1) ? 0x08 : 0x00; /* - * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will + * IDE core issues SETFEATURES_XFER to the drive first (thanks to + * IDE_HFLAG_POST_SET_MODE in ->host_flags). PDC202xx hardware will * automatically set the timing registers based on 100 MHz PLL output. - */ - if (ide_config_drive_speed(drive, speed)) - return 1; - - /* + * * As we set up the PLL to output 133 MHz for UltraDMA/133 capable * chips, we must override the default register settings... */ @@ -211,13 +208,11 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed) set_indexed_reg(hwif, 0x10 + adj, tmp & 0x7f); } - - return 0; } static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio) { - (void)pdcnew_tune_chipset(drive, XFER_PIO_0 + pio); + pdcnew_set_mode(drive, XFER_PIO_0 + pio); } static u8 pdcnew_cable_detect(ide_hwif_t *hwif) @@ -490,9 +485,9 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->autodma = 0; hwif->set_pio_mode = &pdcnew_set_pio_mode; + hwif->set_dma_mode = &pdcnew_set_mode; hwif->quirkproc = &pdcnew_quirkproc; - hwif->speedproc = &pdcnew_tune_chipset; hwif->resetproc = &pdcnew_reset; hwif->err_stops_fifo = 1; @@ -583,6 +578,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, .udma_mask = 0x3f, /* udma0-5 */ + .host_flags = IDE_HFLAG_POST_SET_MODE, },{ /* 1 */ .name = "PDC20269", .init_setup = init_setup_pdcnew, @@ -592,6 +588,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, },{ /* 2 */ .name = "PDC20270", .init_setup = init_setup_pdc20270, @@ -601,6 +598,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, .udma_mask = 0x3f, /* udma0-5 */ + .host_flags = IDE_HFLAG_POST_SET_MODE, },{ /* 3 */ .name = "PDC20271", .init_setup = init_setup_pdcnew, @@ -610,6 +608,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, },{ /* 4 */ .name = "PDC20275", .init_setup = init_setup_pdcnew, @@ -619,6 +618,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, },{ /* 5 */ .name = "PDC20276", .init_setup = init_setup_pdc20276, @@ -628,6 +628,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, },{ /* 6 */ .name = "PDC20277", .init_setup = init_setup_pdcnew, @@ -637,6 +638,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, } }; diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index b578307fad51..8c3e8cf36ec9 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -63,7 +63,7 @@ static const char *pdc_quirk_drives[] = { static void pdc_old_disable_66MHz_clock(ide_hwif_t *); -static int pdc202xx_tune_chipset(ide_drive_t *drive, const u8 speed) +static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -138,13 +138,11 @@ static int pdc202xx_tune_chipset(ide_drive_t *drive, const u8 speed) pci_read_config_dword(dev, drive_pci, &drive_conf); printk("0x%08x\n", drive_conf); #endif - - return ide_config_drive_speed(drive, speed); } static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio) { - pdc202xx_tune_chipset(drive, XFER_PIO_0 + pio); + pdc202xx_set_mode(drive, XFER_PIO_0 + pio); } static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) @@ -330,14 +328,13 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->autodma = 0; hwif->set_pio_mode = &pdc202xx_set_pio_mode; + hwif->set_dma_mode = &pdc202xx_set_mode; hwif->quirkproc = &pdc202xx_quirkproc; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) hwif->resetproc = &pdc202xx_reset; - hwif->speedproc = &pdc202xx_tune_chipset; - hwif->err_stops_fifo = 1; hwif->drives[0].autotune = hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index fd8214a7ab98..38c91ba6497b 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -137,13 +137,14 @@ static u8 piix_dma_2_pio (u8 xfer_rate) { } /** - * piix_tune_pio - tune PIIX for PIO mode - * @drive: drive to tune - * @pio: desired PIO mode + * piix_set_pio_mode - set host controller for PIO mode + * @drive: drive + * @pio: PIO mode number * * Set the interface PIO mode based upon the settings done by AMI BIOS. */ -static void piix_tune_pio (ide_drive_t *drive, u8 pio) + +static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -204,31 +205,15 @@ static void piix_tune_pio (ide_drive_t *drive, u8 pio) } /** - * piix_set_pio_mode - set PIO mode - * @drive: drive to tune - * @pio: desired PIO mode - * - * Set the drive's PIO mode (might be useful if drive is not registered - * in CMOS for any reason). - */ - -static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - piix_tune_pio(drive, pio); - (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} - -/** - * piix_tune_chipset - tune a PIIX interface - * @drive: IDE drive to tune - * @speed: speed to configure + * piix_set_dma_mode - set host controller for DMA mode + * @drive: drive + * @speed: DMA mode * - * Set a PIIX interface channel to the desired speeds. This involves - * requires the right timing data into the PIIX configuration space - * then setting the drive parameters appropriately + * Set a PIIX host controller to the desired DMA mode. This involves + * programming the right timing data into the PCI configuration space. */ -static int piix_tune_chipset(ide_drive_t *drive, const u8 speed) +static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -259,7 +244,7 @@ static int piix_tune_chipset(ide_drive_t *drive, const u8 speed) case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; - default: return -1; + default: return; } if (speed >= XFER_UDMA_0) { @@ -288,9 +273,7 @@ static int piix_tune_chipset(ide_drive_t *drive, const u8 speed) pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); } - piix_tune_pio(drive, piix_dma_2_pio(speed)); - - return ide_config_drive_speed(drive, speed); + piix_set_pio_mode(drive, piix_dma_2_pio(speed)); } /** @@ -448,7 +431,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) hwif->autodma = 0; hwif->set_pio_mode = &piix_set_pio_mode; - hwif->speedproc = &piix_tune_chipset; + hwif->set_dma_mode = &piix_set_dma_mode; + hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 79ecab689489..76f0868054a1 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -68,17 +68,6 @@ static unsigned short sc1200_get_pci_clock (void) return pci_clock; } -extern char *ide_xfer_verbose (byte xfer_rate); - -/* - * Set a new transfer mode at the drive - */ -static int sc1200_set_xfer_mode (ide_drive_t *drive, byte mode) -{ - printk("%s: sc1200_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode)); - return ide_config_drive_speed(drive, mode); -} - /* * Here are the standard PIO mode 0-4 timings for each "format". * Format-0 uses fast data reg timings, with slower command reg timings. @@ -138,7 +127,7 @@ out: return mask; } -static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode) +static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) { ide_hwif_t *hwif = HWIF(drive); int unit = drive->select.b.unit; @@ -146,17 +135,9 @@ static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode) unsigned short pci_clock; unsigned int basereg = hwif->channel ? 0x50 : 0x40; - /* - * Tell the drive to switch to the new mode; abort on failure. - */ - if (sc1200_set_xfer_mode(drive, mode)) - return 1; /* failure */ - pci_clock = sc1200_get_pci_clock(); /* - * Now tune the chipset to match the drive: - * * Note that each DMA mode has several timings associated with it. * The correct timing depends on the fast PCI clock freq. */ @@ -216,8 +197,6 @@ static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode) } else { pci_write_config_dword(hwif->pci_dev, basereg+12, timings); } - - return 0; /* success */ } /* @@ -286,13 +265,12 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) if (mode != -1) { printk("SC1200: %s: changing (U)DMA mode\n", drive->name); hwif->dma_off_quietly(drive); - if (sc1200_tune_chipset(drive, mode) == 0) + if (ide_set_dma_mode(drive, mode) == 0) hwif->dma_host_on(drive); return; } - if (sc1200_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) - sc1200_tunepio(drive, pio); + sc1200_tunepio(drive, pio); } #ifdef CONFIG_PM @@ -408,7 +386,7 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) hwif->autodma = 1; hwif->set_pio_mode = &sc1200_set_pio_mode; - hwif->speedproc = &sc1200_tune_chipset; + hwif->set_dma_mode = &sc1200_set_dma_mode; } hwif->atapi_dma = 1; hwif->ultra_mask = 0x07; @@ -423,7 +401,7 @@ static ide_pci_device_t sc1200_chipset __devinitdata = { .init_hwif = init_hwif_sc1200, .autodma = AUTODMA, .bootable = ON_BOARD, - .host_flags = IDE_HFLAG_ABUSE_DMA_MODES, + .host_flags = IDE_HFLAG_ABUSE_DMA_MODES | IDE_HFLAG_POST_SET_MODE, .pio_mask = ATA_PIO4, }; diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 66a526e0ece4..67f06dd11b34 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -190,15 +190,15 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count) } /** - * scc_tune_pio - tune a drive PIO mode - * @drive: drive to tune - * @mode_wanted: the target operating mode + * scc_set_pio_mode - set host controller for PIO mode + * @drive: drive + * @pio: PIO mode number * * Load the timing settings for this device mode into the * controller. */ -static void scc_tune_pio(ide_drive_t *drive, const u8 pio) +static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct scc_ports *ports = ide_get_hwifdata(hwif); @@ -221,22 +221,16 @@ static void scc_tune_pio(ide_drive_t *drive, const u8 pio) out_be32((void __iomem *)pioct_port, reg); } -static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - scc_tune_pio(drive, pio); - ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} - /** - * scc_tune_chipset - tune a drive DMA mode - * @drive: Drive to set up - * @speed: speed we want to achieve + * scc_set_dma_mode - set host controller for DMA mode + * @drive: drive + * @speed: DMA mode * * Load the timing settings for this device mode into the * controller. */ -static int scc_tune_chipset(ide_drive_t *drive, const u8 speed) +static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct scc_ports *ports = ide_get_hwifdata(hwif); @@ -271,7 +265,7 @@ static int scc_tune_chipset(ide_drive_t *drive, const u8 speed) idx = speed - XFER_UDMA_0; break; default: - return 1; + return; } jcactsel = JCACTSELtbl[offset][idx]; @@ -287,8 +281,6 @@ static int scc_tune_chipset(ide_drive_t *drive, const u8 speed) } reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]; out_be32((void __iomem *)udenvt_port, reg); - - return ide_config_drive_speed(drive, speed); } /** @@ -708,8 +700,8 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) hwif->dma_setup = scc_dma_setup; hwif->ide_dma_end = scc_ide_dma_end; - hwif->speedproc = scc_tune_chipset; hwif->set_pio_mode = scc_set_pio_mode; + hwif->set_dma_mode = scc_set_dma_mode; hwif->ide_dma_check = scc_config_drive_for_dma; hwif->ide_dma_test_irq = scc_dma_test_irq; hwif->udma_filter = scc_udma_filter; diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 0351cf210427..49ec0ac64a4b 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -124,7 +124,7 @@ static u8 svwks_csb_check (struct pci_dev *dev) return 0; } -static void svwks_tune_pio(ide_drive_t *drive, const u8 pio) +static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio) { static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; @@ -145,7 +145,7 @@ static void svwks_tune_pio(ide_drive_t *drive, const u8 pio) } } -static int svwks_tune_chipset(ide_drive_t *drive, const u8 speed) +static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed) { static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; @@ -193,14 +193,6 @@ static int svwks_tune_chipset(ide_drive_t *drive, const u8 speed) pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing); pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing); pci_write_config_byte(dev, 0x54, ultra_enable); - - return (ide_config_drive_speed(drive, speed)); -} - -static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - svwks_tune_pio(drive, pio); - (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } static int svwks_config_drive_xfer_rate (ide_drive_t *drive) @@ -384,7 +376,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) hwif->irq = hwif->channel ? 15 : 14; hwif->set_pio_mode = &svwks_set_pio_mode; - hwif->speedproc = &svwks_tune_chipset; + hwif->set_dma_mode = &svwks_set_dma_mode; hwif->udma_filter = &svwks_udma_filter; hwif->atapi_dma = 1; diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index c292e1de1d56..26352626c0e8 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -291,12 +291,8 @@ static void sgiioc4_dma_off_quietly(ide_drive_t *drive) drive->hwif->dma_host_off(drive); } -static int sgiioc4_speedproc(ide_drive_t *drive, const u8 speed) +static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed) { - if (speed != XFER_MW_DMA_2) - return 1; - - return ide_config_drive_speed(drive, speed); } static int sgiioc4_ide_dma_check(ide_drive_t *drive) @@ -595,7 +591,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif) hwif->mwdma_mask = 0x04; hwif->pio_mask = 0x00; hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */ - hwif->speedproc = &sgiioc4_speedproc; + hwif->set_dma_mode = &sgiioc4_set_dma_mode; hwif->selectproc = NULL;/* Use the default routine to select drive */ hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */ hwif->pre_reset = NULL; /* No HBA specific pre_set needed */ diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 5d1e5e52a044..ce7784996d12 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -165,16 +165,16 @@ out: } /** - * sil_tune_pio - tune a drive - * @drive: drive to tune - * @pio: the desired PIO mode + * sil_set_pio_mode - set host controller for PIO mode + * @drive: drive + * @pio: PIO mode number * * Load the timing settings for this device mode into the * controller. If we are in PIO mode 3 or 4 turn on IORDY * monitoring (bit 9). The TF timing is bits 31:16 */ -static void sil_tune_pio(ide_drive_t *drive, u8 pio) +static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) { const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 }; const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; @@ -234,21 +234,15 @@ static void sil_tune_pio(ide_drive_t *drive, u8 pio) } } -static void sil_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - sil_tune_pio(drive, pio); - (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} - /** - * siimage_tune_chipset - set controller timings - * @drive: Drive to set up - * @speed: speed we want to achieve + * sil_set_dma_mode - set host controller for DMA mode + * @drive: drive + * @speed: DMA mode * - * Tune the SII chipset for the desired mode. + * Tune the SiI chipset for the desired DMA mode. */ -static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed) +static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) { u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; @@ -303,7 +297,7 @@ static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed) mode |= ((unit) ? 0x30 : 0x03); break; default: - return 1; + return; } if (hwif->mmio) { @@ -315,7 +309,6 @@ static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed) pci_write_config_word(hwif->pci_dev, ma, multi); pci_write_config_word(hwif->pci_dev, ua, ultra); } - return (ide_config_drive_speed(drive, speed)); } /** @@ -904,8 +897,8 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) hwif->autodma = 0; hwif->resetproc = &siimage_reset; - hwif->speedproc = &siimage_tune_chipset; hwif->set_pio_mode = &sil_set_pio_mode; + hwif->set_dma_mode = &sil_set_dma_mode; hwif->reset_poll = &siimage_reset_poll; hwif->pre_reset = &siimage_pre_reset; hwif->udma_filter = &sil_udma_filter; diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 3e18899de631..b375ee53d66d 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -451,7 +451,7 @@ static void config_drive_art_rwp (ide_drive_t *drive) } /* Set per-drive active and recovery time */ -static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) +static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -519,20 +519,14 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) } } -static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - config_art_rwp_pio(drive, pio); - (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} - -static int sis5513_tune_chipset(ide_drive_t *drive, const u8 speed) +static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u32 regdw; u8 drive_pci, reg; - /* See config_art_rwp_pio for drive pci config registers */ + /* See sis_set_pio_mode() for drive PCI config registers */ drive_pci = 0x40; if (chipset_family >= ATA_133) { u32 reg54h; @@ -600,8 +594,6 @@ static int sis5513_tune_chipset(ide_drive_t *drive, const u8 speed) BUG(); break; } - - return ide_config_drive_speed(drive, speed); } static int sis5513_config_xfer_rate(ide_drive_t *drive) @@ -841,7 +833,7 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) hwif->irq = hwif->channel ? 15 : 14; hwif->set_pio_mode = &sis_set_pio_mode; - hwif->speedproc = &sis5513_tune_chipset; + hwif->set_dma_mode = &sis_set_dma_mode; if (chipset_family >= ATA_133) hwif->udma_filter = sis5513_ata133_udma_filter; diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index f492318ba797..2ef26e3f7be4 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -75,7 +75,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio) /* * Configure the chipset for PIO mode. */ -static void sl82c105_tune_pio(ide_drive_t *drive, const u8 pio) +static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) { struct pci_dev *dev = HWIF(drive)->pci_dev; int reg = 0x44 + drive->dn * 4; @@ -105,9 +105,9 @@ static void sl82c105_tune_pio(ide_drive_t *drive, const u8 pio) } /* - * Configure the drive and chipset for a new transfer speed. + * Configure the chipset for DMA mode. */ -static int sl82c105_tune_chipset(ide_drive_t *drive, const u8 speed) +static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed) { static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200}; u16 drv_ctrl; @@ -140,10 +140,8 @@ static int sl82c105_tune_chipset(ide_drive_t *drive, const u8 speed) } break; default: - return -1; + return; } - - return ide_config_drive_speed(drive, speed); } /* @@ -306,17 +304,6 @@ static void sl82c105_resetproc(ide_drive_t *drive) pci_read_config_dword(dev, 0x40, &val); pci_set_drvdata(dev, (void *)val); } - -/* - * We only deal with PIO mode here - DMA mode 'using_dma' is not - * initialised at the point that this function is called. - */ -static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - sl82c105_tune_pio(drive, pio); - - (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} /* * Return the revision of the Winbond bridge @@ -383,7 +370,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); hwif->set_pio_mode = &sl82c105_set_pio_mode; - hwif->speedproc = &sl82c105_tune_chipset; + hwif->set_dma_mode = &sl82c105_set_dma_mode; hwif->selectproc = &sl82c105_selectproc; hwif->resetproc = &sl82c105_resetproc; diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index ae8e91324577..ebac87f7200a 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -42,7 +42,7 @@ static u8 slc90e66_dma_2_pio (u8 xfer_rate) { } } -static void slc90e66_tune_pio (ide_drive_t *drive, u8 pio) +static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -95,13 +95,7 @@ static void slc90e66_tune_pio (ide_drive_t *drive, u8 pio) spin_unlock_irqrestore(&ide_lock, flags); } -static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) -{ - slc90e66_tune_pio(drive, pio); - (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); -} - -static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed) +static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -125,7 +119,7 @@ static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed) case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; - default: return -1; + default: return; } if (speed >= XFER_UDMA_0) { @@ -144,9 +138,7 @@ static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed) pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); } - slc90e66_tune_pio(drive, slc90e66_dma_2_pio(speed)); - - return ide_config_drive_speed(drive, speed); + slc90e66_set_pio_mode(drive, slc90e66_dma_2_pio(speed)); } static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) @@ -172,8 +164,8 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) if (!hwif->irq) hwif->irq = hwif->channel ? 15 : 14; - hwif->speedproc = &slc90e66_tune_chipset; hwif->set_pio_mode = &slc90e66_set_pio_mode; + hwif->set_dma_mode = &slc90e66_set_dma_mode; pci_read_config_byte(hwif->pci_dev, 0x47, ®47); diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c index e23b9cfb6eb4..840415d68d38 100644 --- a/drivers/ide/pci/tc86c001.c +++ b/drivers/ide/pci/tc86c001.c @@ -13,7 +13,7 @@ #include #include -static int tc86c001_tune_chipset(ide_drive_t *drive, const u8 speed) +static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00); @@ -39,13 +39,11 @@ static int tc86c001_tune_chipset(ide_drive_t *drive, const u8 speed) scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f; scr |= mode; outw(scr, scr_port); - - return ide_config_drive_speed(drive, speed); } static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio) { - (void) tc86c001_tune_chipset(drive, XFER_PIO_0 + pio); + tc86c001_set_mode(drive, XFER_PIO_0 + pio); } /* @@ -193,7 +191,8 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) hwif->config_data = sc_base; hwif->set_pio_mode = &tc86c001_set_pio_mode; - hwif->speedproc = &tc86c001_tune_chipset; + hwif->set_dma_mode = &tc86c001_set_mode; + hwif->busproc = &tc86c001_busproc; hwif->drives[0].autotune = hwif->drives[1].autotune = 1; diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index c3ff066eea5a..54e411d4e56c 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -40,7 +40,7 @@ #include #include -static int triflex_tune_chipset(ide_drive_t *drive, const u8 speed) +static void triflex_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -82,20 +82,18 @@ static int triflex_tune_chipset(ide_drive_t *drive, const u8 speed) timing = 0x0808; break; default: - return -1; + return; } triflex_timings &= ~(0xFFFF << (16 * unit)); triflex_timings |= (timing << (16 * unit)); pci_write_config_dword(dev, channel_offset, triflex_timings); - - return (ide_config_drive_speed(drive, speed)); } static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio) { - (void)triflex_tune_chipset(drive, XFER_PIO_0 + pio); + triflex_set_mode(drive, XFER_PIO_0 + pio); } static int triflex_config_drive_xfer_rate(ide_drive_t *drive) @@ -111,7 +109,7 @@ static int triflex_config_drive_xfer_rate(ide_drive_t *drive) static void __devinit init_hwif_triflex(ide_hwif_t *hwif) { hwif->set_pio_mode = &triflex_set_pio_mode; - hwif->speedproc = &triflex_tune_chipset; + hwif->set_dma_mode = &triflex_set_mode; if (hwif->dma_base == 0) return; diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index ac094e51d2bf..479e49661032 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -153,21 +153,17 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) * @drive: Drive to set up * @speed: desired speed * - * via_set_drive() computes timing values configures the drive and - * the chipset to a desired transfer mode. It also can be called - * by upper layers. + * via_set_drive() computes timing values configures the chipset to + * a desired transfer mode. It also can be called by upper layers. */ -static int via_set_drive(ide_drive_t *drive, const u8 speed) +static void via_set_drive(ide_drive_t *drive, const u8 speed) { ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); struct via82cxxx_dev *vdev = pci_get_drvdata(drive->hwif->pci_dev); struct ide_timing t, p; unsigned int T, UT; - if (ide_config_drive_speed(drive, speed)) - return 1; - T = 1000000000 / via_clock; switch (vdev->via_config->udma_mask) { @@ -186,12 +182,10 @@ static int via_set_drive(ide_drive_t *drive, const u8 speed) } via_set_speed(HWIF(drive), drive->dn, &t); - - return 0; } /** - * via_set_pio_mode - PIO setup + * via_set_pio_mode - set host controller for PIO mode * @drive: drive * @pio: PIO mode number * @@ -452,8 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) hwif->autodma = 0; hwif->set_pio_mode = &via_set_pio_mode; - hwif->speedproc = &via_set_drive; - + hwif->set_dma_mode = &via_set_drive; #ifdef CONFIG_PPC_CHRP if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) { @@ -496,7 +489,8 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, .bootable = ON_BOARD, .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST - | IDE_HFLAG_PIO_NO_DOWNGRADE, + | IDE_HFLAG_PIO_NO_DOWNGRADE + | IDE_HFLAG_POST_SET_MODE, .pio_mask = ATA_PIO5, },{ /* 1 */ .name = "VP_IDE", @@ -506,7 +500,8 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, .bootable = ON_BOARD, .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST - | IDE_HFLAG_PIO_NO_DOWNGRADE, + | IDE_HFLAG_PIO_NO_DOWNGRADE + | IDE_HFLAG_POST_SET_MODE, .pio_mask = ATA_PIO5, } }; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 313194a0f36e..7d8873839e21 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -611,9 +611,6 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) drive->name, pio, *timings); #endif - if (ide_config_drive_speed(drive, XFER_PIO_0 + pio)) - return; - *timings = t; pmac_ide_do_update_timings(drive); } @@ -822,11 +819,7 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2, } #endif /* #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC */ -/* - * Speedproc. This function is called by the core to set any of the standard - * DMA timing (MDMA or UDMA) to both the drive and the controller. - */ -static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed) +static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed) { int unit = (drive->select.b.unit & 0x01); int ret = 0; @@ -867,25 +860,19 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed) case XFER_SW_DMA_2: case XFER_SW_DMA_1: case XFER_SW_DMA_0: - return 1; + return; #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ default: ret = 1; } if (ret) - return ret; - - ret = ide_config_drive_speed(drive, speed); - if (ret) - return ret; + return; /* Apply timings to controller */ *timings = tl[0]; *timings2 = tl[1]; pmac_ide_do_update_timings(drive); - - return 0; } /* @@ -1147,7 +1134,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->drives[1].unmask = 1; hwif->drives[0].autotune = IDE_TUNE_AUTO; hwif->drives[1].autotune = IDE_TUNE_AUTO; - hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA; + hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA | + IDE_HFLAG_POST_SET_MODE; hwif->pio_mask = ATA_PIO4; hwif->set_pio_mode = pmac_ide_set_pio_mode; if (pmif->kind == controller_un_ata6 @@ -1156,7 +1144,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->selectproc = pmac_ide_kauai_selectproc; else hwif->selectproc = pmac_ide_selectproc; - hwif->speedproc = pmac_ide_tune_chipset; + hwif->set_dma_mode = pmac_ide_set_dma_mode; printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, diff --git a/include/linux/ide.h b/include/linux/ide.h index a7d8b4bc7681..02a27e8cbad2 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -681,7 +681,7 @@ typedef struct hwif_s { u8 straight8; /* Alan's straight 8 check */ u8 bus_state; /* power state of the IDE bus */ - u8 host_flags; + u16 host_flags; u8 pio_mask; @@ -702,10 +702,10 @@ typedef struct hwif_s { #if 0 ide_hwif_ops_t *hwifops; #else - /* routine to set PIO mode for drives */ + /* routine to program host for PIO mode */ void (*set_pio_mode)(ide_drive_t *, const u8); - /* routine to retune DMA modes for drives */ - int (*speedproc)(ide_drive_t *, const u8); + /* routine to program host for DMA mode */ + void (*set_dma_mode)(ide_drive_t *, const u8); /* tweaks hardware to select drive */ void (*selectproc)(ide_drive_t *); /* chipset polling based on hba specifics */ @@ -1257,6 +1257,10 @@ enum { * for hosts which have separate PIO and DMA timings (ie. PMAC) */ IDE_HFLAG_SET_PIO_MODE_KEEP_DMA = (1 << 7), + /* program host for the transfer mode after programming device */ + IDE_HFLAG_POST_SET_MODE = (1 << 8), + /* don't program host/device for the transfer mode ("smart" hosts) */ + IDE_HFLAG_NO_SET_MODE = (1 << 9), }; typedef struct ide_pci_device_s { @@ -1273,7 +1277,7 @@ typedef struct ide_pci_device_s { u8 bootable; unsigned int extra; struct ide_pci_device_s *next; - u8 host_flags; + u16 host_flags; u8 pio_mask; u8 udma_mask; } ide_pci_device_t; @@ -1414,6 +1418,9 @@ unsigned int ide_pio_cycle_time(ide_drive_t *, u8); u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8); extern const ide_pio_timings_t ide_pio_timings[6]; +int ide_set_pio_mode(ide_drive_t *, u8); +int ide_set_dma_mode(ide_drive_t *, u8); + void ide_set_pio(ide_drive_t *, u8); static inline void ide_set_max_pio(ide_drive_t *drive) -- cgit v1.2.3-55-g7522 From b140b99c413ce410197cfcd4014e757cd745226a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:51 +0200 Subject: ide: change master/slave IDENTIFY order Need to probe slave device first to make it release PDIAG- (this is required for correct device side cable detection). Based on libata commit f31f0cc2f0b7527072d94d02da332d9bb8d7d94c. Thanks to Craig for testing this patch. Cc: Craig Block Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-iops.c | 1 - drivers/ide/ide-probe.c | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index f5e73e2950d4..bb691f2eb5bf 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -613,7 +613,6 @@ u8 eighty_ninty_three (ide_drive_t *drive) /* * FIXME: - * - change master/slave IDENTIFY order * - force bit13 (80c cable present) check also for !ivb devices * (unless the slave device is pre-ATA3) */ diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index b4c9f63a3854..d1011712601c 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -719,9 +719,9 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave); */ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)) { - unsigned int unit; unsigned long flags; unsigned int irqd; + int unit; if (hwif->noprobe) return; @@ -777,10 +777,9 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)) printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name); /* - * Second drive should only exist if first drive was found, - * but a lot of cdrom drives are configured as single slaves. + * Need to probe slave device first to make it release PDIAG-. */ - for (unit = 0; unit < MAX_DRIVES; ++unit) { + for (unit = MAX_DRIVES - 1; unit >= 0; unit--) { ide_drive_t *drive = &hwif->drives[unit]; drive->dn = (hwif->channel ? 2 : 0) + unit; (void) probe_for_drive(drive); -- cgit v1.2.3-55-g7522 From 76bb7782c6831bf450b964eb7596e21bcd23fc32 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:52 +0200 Subject: ide: remove CONFIG_IDEDMA_IVB config option Devices which don't set word 93 validation bit should be now handled by ide-iops.c::ivb_list[] and for debugging purposes cable detection can be completely overriden with "idex=ata66" parameter. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Kconfig | 16 ---------------- drivers/ide/ide-iops.c | 4 ---- 2 files changed, 20 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index aa0e0c9f74c5..8982c0932438 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -1074,22 +1074,6 @@ endif config BLK_DEV_IDEDMA def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA -config IDEDMA_IVB - bool "IGNORE word93 Validation BITS" - depends on BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS - ---help--- - There are unclear terms in ATA-4 and ATA-5 standards how certain - hardware (an 80c ribbon) should be detected. Different interpretations - of the standards have been released in hardware. This causes problems: - for example, a host with Ultra Mode 4 (or higher) will not run - in that mode with an 80c ribbon. - - If you are experiencing compatibility or performance problems, you - MAY try to answer Y here. However, it does not necessarily solve - any of your problems, it could even cause more of them. - - It is normally safe to answer Y; however, the default is N. - endif config BLK_DEV_HD_ONLY diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index bb691f2eb5bf..aa738833bed5 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -616,11 +616,7 @@ u8 eighty_ninty_three (ide_drive_t *drive) * - force bit13 (80c cable present) check also for !ivb devices * (unless the slave device is pre-ATA3) */ -#ifndef CONFIG_IDEDMA_IVB if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000))) -#else - if (id->hw_config & 0x6000) -#endif return 1; no_80w: -- cgit v1.2.3-55-g7522 From 7bda292d12795877ade9a7ccc044a7bb0ea8e8b4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:52 +0200 Subject: cs5535: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5535.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index da606ba6d28c..257865778f92 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c @@ -190,12 +190,16 @@ static u8 __devinit cs5535_cable_detect(struct pci_dev *dev) */ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif) { - int i; - hwif->autodma = 0; hwif->set_pio_mode = &cs5535_set_pio_mode; hwif->set_dma_mode = &cs5535_set_dma_mode; + + hwif->drives[1].autotune = hwif->drives[0].autotune = 1; + + if (hwif->dma_base == 0) + return; + hwif->ide_dma_check = &cs5535_dma_check; hwif->atapi_dma = 1; @@ -207,11 +211,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif) if (!noautodma) hwif->autodma = 1; - /* just setting autotune and not worrying about bios timings */ - for (i = 0; i < 2; i++) { - hwif->drives[i].autotune = 1; - hwif->drives[i].autodma = hwif->autodma; - } + hwif->drives[1].autodma = hwif->drives[0].autodma = hwif->autodma; } static ide_pci_device_t cs5535_chipset __devinitdata = { -- cgit v1.2.3-55-g7522 From b9d9e61abb85ecf4e4aa55328b21eac17840a3fb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:52 +0200 Subject: sgiioc4: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sgiioc4.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 26352626c0e8..85ffaaa39b1b 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -587,8 +587,6 @@ static void __devinit ide_init_sgiioc4(ide_hwif_t * hwif) { hwif->mmio = 1; - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; hwif->pio_mask = 0x00; hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */ hwif->set_dma_mode = &sgiioc4_set_dma_mode; @@ -602,6 +600,14 @@ ide_init_sgiioc4(ide_hwif_t * hwif) hwif->quirkproc = NULL; hwif->busproc = NULL; + hwif->INB = &sgiioc4_INB; + + if (hwif->dma_base == 0) + return; + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x04; + hwif->dma_setup = &sgiioc4_ide_dma_setup; hwif->dma_start = &sgiioc4_ide_dma_start; hwif->ide_dma_end = &sgiioc4_ide_dma_end; @@ -613,8 +619,6 @@ ide_init_sgiioc4(ide_hwif_t * hwif) hwif->dma_host_off = &sgiioc4_dma_host_off; hwif->dma_lost_irq = &sgiioc4_dma_lost_irq; hwif->dma_timeout = &ide_dma_timeout; - - hwif->INB = &sgiioc4_INB; } static int __devinit @@ -684,8 +688,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) /* Initializing chipset IRQ Registers */ writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); - ide_init_sgiioc4(hwif); - hwif->autodma = 0; if (dma_base && ide_dma_sgiioc4(hwif, dma_base) == 0) { @@ -695,6 +697,8 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n", hwif->name, DRV_NAME); + ide_init_sgiioc4(hwif); + if (probe_hwif_init(hwif)) return -EIO; -- cgit v1.2.3-55-g7522 From dfb2311226539e0496c0a7c65ceebaaff2120a0b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:52 +0200 Subject: cs5520: fix ->dma_base equal zero handling Set hwif->ide_dma_{check,on} and hwif->autodma to 1 after checking that ->dma_base exists. If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5520.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index cb2a10203dc4..fbce90048aec 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -142,25 +142,24 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) { hwif->set_pio_mode = &cs5520_set_pio_mode; hwif->set_dma_mode = &cs5520_set_dma_mode; - hwif->ide_dma_check = &cs5520_config_drive_xfer_rate; - hwif->ide_dma_on = &cs5520_dma_on; - if(!noautodma) - hwif->autodma = 1; - - if(!hwif->dma_base) - { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) { + hwif->drives[1].autotune = hwif->drives[0].autotune = 1; return; } + hwif->ide_dma_check = &cs5520_config_drive_xfer_rate; + hwif->ide_dma_on = &cs5520_dma_on; + /* ATAPI is harder so leave it for now */ hwif->atapi_dma = 0; hwif->ultra_mask = 0; hwif->swdma_mask = 0; hwif->mwdma_mask = 0; - + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; } -- cgit v1.2.3-55-g7522 From 88ae4d8c3829fe3d7be9b1e3ed79a37814752d61 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:53 +0200 Subject: sc1200: fix ->dma_base equal zero handling Set hwif->atapi_dma/{ultra,mwdma}_mask and drive->autodma after checking that ->dma_base exists. If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. OTOH hwif->set_{pio,dma}_mode hooks should be set even if hwif->dma_base == 0. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sc1200.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 76f0868054a1..ee0e3f554d9a 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -378,16 +378,20 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) if (hwif->mate) hwif->serialized = hwif->mate->serialized = 1; hwif->autodma = 0; - if (hwif->dma_base) { - hwif->udma_filter = sc1200_udma_filter; - hwif->ide_dma_check = &sc1200_config_dma; - hwif->ide_dma_end = &sc1200_ide_dma_end; - if (!noautodma) - hwif->autodma = 1; - - hwif->set_pio_mode = &sc1200_set_pio_mode; - hwif->set_dma_mode = &sc1200_set_dma_mode; - } + + hwif->set_pio_mode = &sc1200_set_pio_mode; + hwif->set_dma_mode = &sc1200_set_dma_mode; + + if (hwif->dma_base == 0) + return; + + hwif->udma_filter = sc1200_udma_filter; + hwif->ide_dma_check = &sc1200_config_dma; + hwif->ide_dma_end = &sc1200_ide_dma_end; + + if (!noautodma) + hwif->autodma = 1; + hwif->atapi_dma = 1; hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; -- cgit v1.2.3-55-g7522 From 99149a485958ada512eafc34fe36a80cb63fa56c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sat, 13 Oct 2007 17:47:53 +0200 Subject: alim15x3: remove redundant m5229_revision check init_dma_ali15x3() guarantees that hwif->dma_base will never be set for m5229_revision < 0x20 so remove redundant m5229_revision >= 0x20 check from init_hwif_common_ali15x3(). While at it remove incorrect comment. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/alim15x3.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 88f084eae193..0b83443bf250 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -694,6 +694,10 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) return; } + /* + * check in ->init_dma guarantees m5229_revision >= 0x20 here + */ + if (m5229_revision > 0x20) hwif->atapi_dma = 1; @@ -711,18 +715,15 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; - if (m5229_revision >= 0x20) { - /* - * M1543C or newer for DMAing - */ - hwif->ide_dma_check = &ali15x3_config_drive_for_dma; - hwif->dma_setup = &ali15x3_dma_setup; - if (!noautodma) - hwif->autodma = 1; - - if (hwif->cbl != ATA_CBL_PATA40_SHORT) - hwif->cbl = ata66_ali15x3(hwif); - } + hwif->ide_dma_check = &ali15x3_config_drive_for_dma; + hwif->dma_setup = &ali15x3_dma_setup; + + if (hwif->cbl != ATA_CBL_PATA40_SHORT) + hwif->cbl = ata66_ali15x3(hwif); + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; } -- cgit v1.2.3-55-g7522