static u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode) { u16 *id = drive->id; int pio_mode = -1, overridden = 0; if (mode_wanted != 255) return min_t(u8, mode_wanted, max_mode); if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0) pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]); if (pio_mode != -1) { printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name); } else { pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8; if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */ pio_mode = 2; overridden = 1; } if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */ if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7)) pio_mode = 4 + min_t(int, 2, id[ATA_ID_CFA_MODES] & 7); else if (ata_id_has_iordy(id)) { if (id[ATA_ID_PIO_MODES] & 7) { overridden = 0; if (id[ATA_ID_PIO_MODES] & 4) pio_mode = 5; else if (id[ATA_ID_PIO_MODES] & 2) pio_mode = 4; else pio_mode = 3; } } } if (overridden) printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n", drive->name); }
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"); }