/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16
  *
- * linux/drivers/ide/pci/cmd64x.c              Version 1.41    Feb 3, 2007
+ * linux/drivers/ide/pci/cmd64x.c              Version 1.42    Feb 8, 2007
  *
  * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
  *           Note, this driver is not used at all on other systems because
 
 #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */
 
+static u8 quantize_timing(int timing, int quant)
+{
+       return (timing + quant - 1) / quant;
+}
+
 /*
  * This routine writes the prepared setup/active/recovery counts
  * for a drive into the cmd646 chipset registers to active them.
  */
 static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted)
 {
-       int setup_time, active_time, recovery_time;
-       int clock_time, pio_mode, cycle_time;
-       u8 recovery_count2, cycle_count;
-       int setup_count, active_count, recovery_count;
-       int bus_speed = system_bus_clock();
-       ide_pio_data_t  d;
+       int setup_time, active_time, cycle_time;
+       u8  cycle_count, setup_count, active_count, recovery_count;
+       u8  pio_mode;
+       int clock_time = 1000 / system_bus_clock();
+       ide_pio_data_t pio;
 
-       pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &d);
-       cycle_time = d.cycle_time;
+       pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio);
+       cycle_time = pio.cycle_time;
 
-       /*
-        * I copied all this complicated stuff from cmd640.c and made a few
-        * minor changes.  For now I am just going to pray that it is correct.
-        */
        setup_time  = ide_pio_timings[pio_mode].setup_time;
        active_time = ide_pio_timings[pio_mode].active_time;
-       recovery_time = cycle_time - (setup_time + active_time);
-       clock_time = 1000 / bus_speed;
-       cycle_count = (cycle_time + clock_time - 1) / clock_time;
-
-       setup_count = (setup_time + clock_time - 1) / clock_time;
 
-       active_count = (active_time + clock_time - 1) / clock_time;
+       setup_count  = quantize_timing( setup_time, clock_time);
+       cycle_count  = quantize_timing( cycle_time, clock_time);
+       active_count = quantize_timing(active_time, clock_time);
 
-       recovery_count = (recovery_time + clock_time - 1) / clock_time;
-       recovery_count2 = cycle_count - (setup_count + active_count);
-       if (recovery_count2 > recovery_count)
-               recovery_count = recovery_count2;
+       recovery_count = cycle_count - active_count;
+       /* program_drive_counts() takes care of zero recovery cycles */
        if (recovery_count > 16) {
                active_count += recovery_count - 16;
                recovery_count = 16;
        }
        if (active_count > 16)
-               active_count = 16; /* maximum allowed by cmd646 */
+               active_count = 16; /* maximum allowed by cmd64x */
 
        program_drive_counts (drive, setup_count, active_count, recovery_count);
 
        cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, "
                "clocks=%d/%d/%d\n",
                drive->name, mode_wanted, pio_mode, cycle_time,
-               d.overridden ? " (overriding vendor mode)" : "",
+               pio.overridden ? " (overriding vendor mode)" : "",
                setup_count, active_count, recovery_count);
 
        return pio_mode;