static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) { unsigned int index = 0, cycle_time; u8 b; switch (pio) { case 6: /* set fast-devsel off */ case 7: /* set fast-devsel on */ b = get_cmd640_reg(CNTRL) & ~0x27; if (pio & 1) b |= 0x27; put_cmd640_reg(CNTRL, b); printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, (pio & 1) ? "en" : "dis"); return; case 8: /* set prefetch off */ case 9: /* set prefetch on */ set_prefetch_mode(drive, index, pio & 1); printk("%s: %sabled cmd640 prefetch\n", drive->name, (pio & 1) ? "en" : "dis"); return; } cycle_time = ide_pio_cycle_time(drive, pio); cmd640_set_mode(drive, index, pio, cycle_time); printk("%s: selected cmd640 PIO mode%d (%dns)", drive->name, pio, cycle_time); display_clocks(index); }
static void cmd640_tune_drive(ide_drive_t *drive, byte pio_mode) { int interface_number; int drive_number; int clock_time; /* ns */ int max_pio; int mc_time, av_time, ds_time; struct hd_driveid* id; int readahead; /* there is a global named read_ahead */ if (pio_mode != 255) { cmd640_set_mode(drive, pio_mode); return; } interface_number = HWIF(drive)->index; drive_number = drive->select.b.unit; clock_time = 1000/bus_speed; id = drive->id; if ((max_pio = ide_scan_pio_blacklist(id->model)) != -1) { ds_time = pio_timings[max_pio].ds_time; } else { max_pio = id->tPIO; ds_time = pio_timings[max_pio].ds_time; if (id->field_valid & 2) { if ((id->capability & 8) && (id->eide_pio_modes & 7)) { if (id->eide_pio_modes & 4) max_pio = 5; else if (id->eide_pio_modes & 2) max_pio = 4; else max_pio = 3; ds_time = id->eide_pio_iordy; } else { ds_time = id->eide_pio; } if (ds_time == 0) ds_time = pio_timings[max_pio].ds_time; } /* * Conservative "downgrade" */ if (max_pio < 4 && max_pio != 0) { max_pio -= 1; ds_time = pio_timings[max_pio].ds_time; } } mc_time = pio_timings[max_pio].mc_time; av_time = pio_timings[max_pio].av_time; cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time, interface_number*2 + drive_number); set_pio_mode(interface_number, drive_number, max_pio); cmd640_set_timing(interface_number, drive_number); /* * Disable (or set) readahead mode */ readahead = 0; if (cmd640_chip_version > 1) { /* Mmmm.. probably should be > 2 ?? */ readahead = known_drive_readahead(id->model); if (readahead == -1) readahead = 1; /* Mmmm.. probably be 0 ?? */ set_readahead_mode(readahead, interface_number, drive_number); } printk ("Mode and Timing set to PIO%d, Readahead is %s\n", max_pio, readahead ? "enabled" : "disabled"); }