static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, u8 pio_mode, unsigned int cycle_time) { struct ide_timing *t; int setup_time, active_time, recovery_time, clock_time; u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; int bus_speed; if (cmd640_vlb) bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; else bus_speed = ide_pci_clk ? ide_pci_clk : 33; if (pio_mode > 5) pio_mode = 5; t = ide_timing_find_mode(XFER_PIO_0 + pio_mode); setup_time = t->setup; active_time = t->active; recovery_time = cycle_time - (setup_time + active_time); clock_time = 1000 / bus_speed; cycle_count = DIV_ROUND_UP(cycle_time, clock_time); setup_count = DIV_ROUND_UP(setup_time, clock_time); active_count = DIV_ROUND_UP(active_time, clock_time); if (active_count < 2) active_count = 2; recovery_count = DIV_ROUND_UP(recovery_time, clock_time); recovery_count2 = cycle_count - (setup_count + active_count); if (recovery_count2 > recovery_count) recovery_count = recovery_count2; if (recovery_count < 2) recovery_count = 2; if (recovery_count > 17) { active_count += recovery_count - 17; recovery_count = 17; } if (active_count > 16) active_count = 16; if (cmd640_chip_version > 1) recovery_count -= 1; if (recovery_count > 16) recovery_count = 16; setup_counts[index] = setup_count; active_counts[index] = active_count; recovery_counts[index] = recovery_count; program_drive_counts(drive, index); }
static void __init cmd640_init_dev(ide_drive_t *drive) { unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1); #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED setup_counts[i] = 4; active_counts[i] = 16; recovery_counts[i] = 16; program_drive_counts(drive, i); set_prefetch_mode(drive, i, 0); printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch cleared\n", i); #else check_prefetch(drive, i); printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n", i, (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) ? "off" : "on"); #endif }
static void cmd640_init_dev(ide_drive_t *drive) { unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1); #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED /* * Reset timing to the slowest speed and turn off prefetch. * This way, the drive identify code has a better chance. */ setup_counts[i] = 4; /* max possible */ active_counts[i] = 16; /* max possible */ recovery_counts[i] = 16; /* max possible */ program_drive_counts(drive, i); set_prefetch_mode(drive, i, 0); printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch cleared\n", i); #else /* * Set the drive unmask flags to match the prefetch setting. */ check_prefetch(drive, i); printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n", i, (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT) ? "off" : "on"); #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ }
/* * Set a specific pio_mode for a drive */ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, u8 pio_mode, unsigned int cycle_time) { struct ide_timing *t; int setup_time, active_time, recovery_time, clock_time; u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; int bus_speed; if (cmd640_vlb) bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; else bus_speed = ide_pci_clk ? ide_pci_clk : 33; if (pio_mode > 5) pio_mode = 5; t = ide_timing_find_mode(XFER_PIO_0 + pio_mode); setup_time = t->setup; active_time = t->active; recovery_time = cycle_time - (setup_time + active_time); clock_time = 1000 / bus_speed; cycle_count = DIV_ROUND_UP(cycle_time, clock_time); setup_count = DIV_ROUND_UP(setup_time, clock_time); active_count = DIV_ROUND_UP(active_time, clock_time); if (active_count < 2) active_count = 2; /* minimum allowed by cmd640 */ recovery_count = DIV_ROUND_UP(recovery_time, clock_time); recovery_count2 = cycle_count - (setup_count + active_count); if (recovery_count2 > recovery_count) recovery_count = recovery_count2; if (recovery_count < 2) recovery_count = 2; /* minimum allowed by cmd640 */ if (recovery_count > 17) { active_count += recovery_count - 17; recovery_count = 17; } if (active_count > 16) active_count = 16; /* maximum allowed by cmd640 */ if (cmd640_chip_version > 1) recovery_count -= 1; /* cmd640b uses (count + 1)*/ if (recovery_count > 16) recovery_count = 16; /* maximum allowed by cmd640 */ setup_counts[index] = setup_count; active_counts[index] = active_count; recovery_counts[index] = recovery_count; /* * In a perfect world, we might set the drive pio mode here * (using WIN_SETFEATURE) before continuing. * * But we do not, because: * 1) this is the wrong place to do it (proper is do_special() in ide.c) * 2) in practice this is rarely, if ever, necessary */ program_drive_counts(drive, index); }
static void cmd64x_tuneproc (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(); /*byte b;*/ ide_pio_data_t d; switch (mode_wanted) { case 8: /* set prefetch off */ case 9: /* set prefetch on */ mode_wanted &= 1; /*set_prefetch_mode(index, mode_wanted);*/ cmdprintk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis"); return; } mode_wanted = ide_get_best_pio_mode (drive, mode_wanted, 5, &d); pio_mode = d.pio_mode; cycle_time = d.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. */ if (pio_mode > 5) pio_mode = 5; 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; 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; if (recovery_count > 16) { active_count += recovery_count - 16; recovery_count = 16; } if (active_count > 16) active_count = 16; /* maximum allowed by cmd646 */ /* * In a perfect world, we might set the drive pio mode here * (using WIN_SETFEATURE) before continuing. * * But we do not, because: * 1) this is the wrong place to do it * (proper is do_special() in ide.c) * 2) in practice this is rarely, if ever, necessary */ program_drive_counts (drive, setup_count, active_count, recovery_count); cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns)%s, " "clocks=%d/%d/%d\n", drive->name, pio_mode, mode_wanted, cycle_time, d.overridden ? " (overriding vendor mode)" : "", setup_count, active_count, recovery_count); }