From 6c987183fcc3c6cb9eb77fd0b3e8ca1ac98a4813 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sun, 15 Jun 2008 21:00:22 +0200 Subject: opti621: program devices timings separately in ->set_pio_mode * Set drive->drive_data to 'pio + XFER_PIO_0' instead of 'pio', then simplify selecting maximum adress setup timing. * Remove no longer needed compute_pios() and opti621_port_init_devs(). * Program devices timings separately in ->set_pio_mode. Based on a bugreport from Juergen Kosel & inspired by pata_opti.c code. Tested-by: Juergen Kosel Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/opti621.c | 80 +++++++++-------------------------------------- 1 file changed, 15 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index 7547fa2d83a..c746e6f0607 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c @@ -115,34 +115,6 @@ static int reg_base; static DEFINE_SPINLOCK(opti621_lock); -/* there are stored pio numbers from other calls of opti621_set_pio_mode */ -static void compute_pios(ide_drive_t *drive, const u8 pio) -/* Store values into drive->drive_data - * second_contr - 0 for primary controller, 1 for secondary - * slave_drive - 0 -> pio is for master, 1 -> pio is for slave - * pio - PIO mode for selected drive (for other we don't know) - */ -{ - int d; - ide_hwif_t *hwif = HWIF(drive); - - drive->drive_data = pio; - - for (d = 0; d < 2; ++d) { - drive = &hwif->drives[d]; - if (drive->present) { - if (drive->drive_data == PIO_DONT_KNOW) - drive->drive_data = ide_get_best_pio_mode(drive, 255, 3); -#ifdef OPTI621_DEBUG - printk("%s: Selected PIO mode %d\n", - drive->name, drive->drive_data); -#endif - } else { - drive->drive_data = PIO_NOT_EXIST; - } - } -} - static int cmpt_clk(int time, int bus_speed) /* Returns (rounded up) time in clocks for time in ns, * with bus_speed in MHz. @@ -226,20 +198,19 @@ static void compute_clocks(int pio, pio_clocks_t *clks, int bus_speed) static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) { - /* primary and secondary drives share some registers, - * so we have to program both drives - */ + ide_hwif_t *hwif = drive->hwif; + ide_drive_t *pair = ide_get_paired_drive(drive); unsigned long flags; - u8 pio1 = 0, pio2 = 0; pio_clocks_t first, second; int ax, drdy; - u8 cycle1, cycle2, misc, clk; - ide_hwif_t *hwif = HWIF(drive); + u8 cycle1, misc, clk, addr_pio = pio; - /* sets drive->drive_data for both drives */ - compute_pios(drive, pio); - pio1 = hwif->drives[0].drive_data; - pio2 = hwif->drives[1].drive_data; + drive->drive_data = XFER_PIO_0 + pio; + + if (pair->present) { + if (pair->drive_data && pair->drive_data < drive->drive_data) + addr_pio = pair->drive_data - XFER_PIO_0; + } spin_lock_irqsave(&opti621_lock, flags); @@ -259,8 +230,8 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) printk(KERN_INFO "%s: CLK = %d MHz\n", hwif->name, clk ? 25 : 33); - compute_clocks(pio1, &first, clk ? 25 : 33); - compute_clocks(pio2, &second, clk ? 25 : 33); + compute_clocks(pio, &first, clk ? 25 : 33); + compute_clocks(addr_pio, &second, clk ? 25 : 33); /* ax = max(a1,a2) */ ax = (first.address_time < second.address_time) ? second.address_time : first.address_time; @@ -268,37 +239,23 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) drdy = 2; /* DRDY is default 2 (by OPTi Databook) */ cycle1 = ((first.data_time-1)<<4) | (first.recovery_time-2); - cycle2 = ((second.data_time-1)<<4) | (second.recovery_time-2); misc = ((ax - 1) << 4) | ((drdy - 2) << 1); #ifdef OPTI621_DEBUG - printk("%s: master: address: %d, data: %d, " + printk("%s: address: %d, data: %d, " "recovery: %d, drdy: %d [clk]\n", - hwif->name, ax, first.data_time, + drive->name, ax, first.data_time, first.recovery_time, drdy); - printk("%s: slave: address: %d, data: %d, " - "recovery: %d, drdy: %d [clk]\n", - hwif->name, ax, second.data_time, - second.recovery_time, drdy); #endif - /* program primary drive */ - /* select Index-0 for Register-A */ - write_reg(0, MISC_REG); + /* select Index-0/1 for Register-A/B */ + write_reg(drive->select.b.unit, MISC_REG); /* set read cycle timings */ write_reg(cycle1, READ_REG); /* set write cycle timings */ write_reg(cycle1, WRITE_REG); - /* program secondary drive */ - /* select Index-1 for Register-B */ - write_reg(1, MISC_REG); - /* set read cycle timings */ - write_reg(cycle2, READ_REG); - /* set write cycle timings */ - write_reg(cycle2, WRITE_REG); - /* use Register-A for drive 0 */ /* use Register-B for drive 1 */ write_reg(0x85, CNTRL_REG); @@ -310,14 +267,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) spin_unlock_irqrestore(&opti621_lock, flags); } -static void __devinit opti621_port_init_devs(ide_hwif_t *hwif) -{ - hwif->drives[0].drive_data = PIO_DONT_KNOW; - hwif->drives[1].drive_data = PIO_DONT_KNOW; -} - static const struct ide_port_ops opti621_port_ops = { - .port_init_devs = opti621_port_init_devs, .set_pio_mode = opti621_set_pio_mode, }; -- cgit v1.2.3