Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26bcb879 authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz
Browse files

ide: add ide_set{_max}_pio() (take 4)



* Add IDE_HFLAG_ABUSE_{PREFETCH,FAST_DEVSEL,DMA_MODES} flags
  and set them in ht6560, cmd640, cmd64x and sc1200 host drivers.

* Add set_pio_mode_abuse() for checking if host driver has a non-standard
  ->tuneproc() implementation and use it in do_special().

* Add ide_set_pio() for setting PIO mode (it uses hwif->pio_mask to find
  the maximum PIO mode supported by the host), also add ide_set_max_pio()
  wrapper for ide_set_pio() to use for auto-tuning.  Convert users of
  ->tuneproc to use ide_set{_max}_pio() where possible.  This leaves only
  do_special(), set_using_pio(), ide_hwif_restore() and ide_set_pio() as
  a direct users of ->tuneproc.

* Remove no longer needed ide_get_best_pio_mode() calls and printk-s
  reporting PIO mode selected from ->tuneproc implementations.

* Rename ->tuneproc hook to ->set_pio_mode and make 'pio' argument const.

* Remove stale comment from ide_config_drive_speed().

v2:
* Fix "ata_" prefix (Noticed by Jeff).

v3:
* Minor cleanups/fixups per Sergei's suggestions.

v4:
* Fix compile problem in drivers/ide/pci/cmd640.c
  (Noticed by Andrew Morton).

* Improve some ->set_pio_mode comments.

Reviewed-by: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 842c19ad
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -680,12 +680,10 @@ static void cris_dma_off(ide_drive_t *drive)
{
}

static void tune_cris_ide(ide_drive_t *drive, u8 pio)
static void cris_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
	int setup, strobe, hold;

	pio = ide_get_best_pio_mode(drive, pio, 4);

	switch(pio)
	{
		case 0:
@@ -727,7 +725,7 @@ static int speed_cris_ide(ide_drive_t *drive, const u8 speed)
	int cyc = 0, dvs = 0, strobe = 0, hold = 0;

	if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
		tune_cris_ide(drive, speed - XFER_PIO_0);
		cris_set_pio_mode(drive, speed - XFER_PIO_0);
		return ide_config_drive_speed(drive, speed);
	}

@@ -797,7 +795,7 @@ init_e100_ide (void)
		ide_register_hw(&hw, 1, &hwif);
		hwif->mmio = 1;
		hwif->chipset = ide_etrax100;
		hwif->tuneproc = &tune_cris_ide;
		hwif->set_pio_mode = &cris_set_pio_mode;
		hwif->speedproc = &speed_cris_ide;
		hwif->ata_input_data = &cris_ide_input_data;
		hwif->ata_output_data = &cris_ide_output_data;
+35 −4
Original line number Diff line number Diff line
@@ -201,8 +201,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
		return do_rw_taskfile(drive, args);

	case idedisk_pm_restore_pio:	/* Resume step 1 (restore PIO) */
		if (drive->hwif->tuneproc != NULL)
			drive->hwif->tuneproc(drive, 255);
		ide_set_max_pio(drive);
		/*
		 * skip idedisk_pm_idle for ATAPI devices
		 */
@@ -788,6 +787,30 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
	return ide_started;
}

/*
 * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
 */
static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
{
	switch (req_pio) {
	case 202:
	case 201:
	case 200:
	case 102:
	case 101:
	case 100:
		return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
	case 9:
	case 8:
		return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
	case 7:
	case 6:
		return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
	default:
		return 0;
	}
}

/**
 *	do_special		-	issue some special commands
 *	@drive: drive the command is for
@@ -805,9 +828,17 @@ static ide_startstop_t do_special (ide_drive_t *drive)
	printk("%s: do_special: 0x%02x\n", drive->name, s->all);
#endif
	if (s->b.set_tune) {
		ide_hwif_t *hwif = drive->hwif;
		u8 req_pio = drive->tune_req;

		s->b.set_tune = 0;
		if (HWIF(drive)->tuneproc != NULL)
			HWIF(drive)->tuneproc(drive, drive->tune_req);

		if (set_pio_mode_abuse(drive->hwif, req_pio)) {
			if (hwif->set_pio_mode)
				hwif->set_pio_mode(drive, req_pio);
		} else
			ide_set_pio(drive, req_pio);

		return ide_stopped;
	} else {
		if (drive->media == ide_disk)
+0 −6
Original line number Diff line number Diff line
@@ -780,12 +780,6 @@ int ide_driveid_update (ide_drive_t *drive)

/*
 * Similar to ide_wait_stat(), except it never calls ide_error internally.
 * This is a kludge to handle the new ide_config_drive_speed() function,
 * and should not otherwise be used anywhere.  Eventually, the tuneproc's
 * should be updated to return ide_startstop_t, in which case we can get
 * rid of this abomination again.  :)   -ml
 *
 * It is gone..........
 *
 * const char *msg == consider adding for verbose errors.
 */
+29 −0
Original line number Diff line number Diff line
@@ -325,6 +325,35 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode)

EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);

/* req_pio == "255" for auto-tune */
void ide_set_pio(ide_drive_t *drive, u8 req_pio)
{
	ide_hwif_t *hwif = drive->hwif;
	u8 host_pio, pio;

	if (hwif->set_pio_mode == NULL)
		return;

	BUG_ON(hwif->pio_mask == 0x00);

	host_pio = fls(hwif->pio_mask) - 1;

	pio = ide_get_best_pio_mode(drive, req_pio, host_pio);

	/*
	 * TODO:
	 * - report device max PIO mode
	 * - check req_pio != 255 against device max PIO mode
	 */
	printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
			  drive->name, host_pio, req_pio,
			  req_pio == 255 ? "(auto-tune)" : "", pio);

	hwif->set_pio_mode(drive, pio);
}

EXPORT_SYMBOL_GPL(ide_set_pio);

/**
 *	ide_toggle_bounce	-	handle bounce buffering
 *	@drive: drive to update
+2 −4
Original line number Diff line number Diff line
@@ -827,10 +827,8 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
		ide_drive_t *drive = &hwif->drives[unit];

		if (drive->present) {
			if (hwif->tuneproc != NULL && 
				drive->autotune == IDE_TUNE_AUTO)
				/* auto-tune PIO mode */
				hwif->tuneproc(drive, 255);
			if (drive->autotune == IDE_TUNE_AUTO)
				ide_set_max_pio(drive);

			if (drive->autotune != IDE_TUNE_DEFAULT &&
			    drive->autotune != IDE_TUNE_AUTO)
Loading