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);
}
Beispiel #2
0
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");
}