All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Dalecki <dalecki@evision-ventures.com>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH] 2.5.21 IDE 90
Date: Fri, 14 Jun 2002 13:08:01 +0200	[thread overview]
Message-ID: <3D09CE91.9010109@evision-ventures.com> (raw)
In-Reply-To: <Pine.LNX.4.33.0206082235240.4635-100000@penguin.transmeta.com>

[-- Attachment #1: Type: text/plain, Size: 1118 bytes --]

Thu Jun 13 20:29:06 CEST 2002 ide-clean-90

- Implement the assertion that the lock is already held, if we run
   ata_status_poll.

- The usual host chip code load from Bartomiej onierkiewicz.  Fortunately
   I'm able to check the sis5513 fixes on a life system.

   More serious stuff... for IDE 88:

	- implement ata_best_pio_mode() in ata-timing.c
	  (play safer than driver's config_chipset_for_pio())

	- replace config_chipset_for_pio() by ata_best_pio_mode()
	  in host chips drivers
	  (trivial for hpt34x.c, hpt366.c and serverworks.c,
	   non-trivial for cmd64x.c and sis5513.c)

	- set PIO also for (U)DMA modes in cmd64x_tune_chipset()
	  (cmd64x.c)

	- fix bug in setting PIO0-2 for devices also supporting PIO3/4
	  (sis5513.c)

	- misc cleanups

- Rename XXX_do_request back do do_request. This was just tmporary tagging.

- Move ata_taskfile() call down to the ide-disk request handler.c, which is the
   only place needing it. Rename ata_taskfile to ata_do_taskfile().  This
   allowed us to implement the assertion that ata_do_taskfile() will be only
   called with the channel lock already held.




[-- Attachment #2: ide-clean-90.diff --]
[-- Type: text/plain, Size: 40132 bytes --]

diff -urN linux-2.5.21/drivers/ide/alim15x3.c linux/drivers/ide/alim15x3.c
--- linux-2.5.21/drivers/ide/alim15x3.c	2002-06-09 07:30:37.000000000 +0200
+++ linux/drivers/ide/alim15x3.c	2002-06-13 22:53:06.000000000 +0200
@@ -176,11 +176,6 @@
 	return ide_config_drive_speed(drive, speed);
 }
 
-static void config_chipset_for_pio(struct ata_device *drive)
-{
-	ali15x3_tune_drive(drive, 5);
-}
-
 #ifdef CONFIG_BLK_DEV_IDEDMA
 static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
 {
@@ -253,7 +248,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		config_chipset_for_pio(drive);
+		ali15x3_tune_drive(drive, 255);
 	}
 
 	udma_enable(drive, on, verbose);
diff -urN linux-2.5.21/drivers/ide/ata-timing.c linux/drivers/ide/ata-timing.c
--- linux-2.5.21/drivers/ide/ata-timing.c	2002-06-09 17:44:23.000000000 +0200
+++ linux/drivers/ide/ata-timing.c	2002-06-13 22:53:06.000000000 +0200
@@ -270,3 +270,25 @@
 
 	return 0;
 }
+
+u8 ata_best_pio_mode(struct ata_device *drive)
+{
+	static u16 eide_pio_timing[6] = { 600, 383, 240, 180, 120, 90 };
+	u16 pio_min;
+	u8 pio;
+
+	pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
+
+	/* downgrade mode if necessary */
+	pio_min = (pio > 2) ? drive->id->eide_pio_iordy : drive->id->eide_pio;
+
+	if (pio_min)
+		while (pio && pio_min > eide_pio_timing[pio])
+			pio--;
+
+	if (!pio && drive->id->tPIO)
+		return XFER_PIO_SLOW;
+
+	/* don't allow XFER_PIO_5 for now */
+	return XFER_PIO_0 + min_t(u8, pio, 4);
+}
diff -urN linux-2.5.21/drivers/ide/ata-timing.h linux/drivers/ide/ata-timing.h
--- linux-2.5.21/drivers/ide/ata-timing.h	2002-06-09 17:44:23.000000000 +0200
+++ linux/drivers/ide/ata-timing.h	2002-06-13 22:53:06.000000000 +0200
@@ -83,5 +83,6 @@
 extern struct ata_timing* ata_timing_data(short speed);
 extern int ata_timing_compute(struct ata_device *drive,
 		short speed, struct ata_timing *t, int T, int UT);
+extern u8 ata_best_pio_mode(struct ata_device *drive);
 
 #endif
diff -urN linux-2.5.21/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c
--- linux-2.5.21/drivers/ide/cmd64x.c	2002-06-13 20:15:09.000000000 +0200
+++ linux/drivers/ide/cmd64x.c	2002-06-13 22:53:06.000000000 +0200
@@ -152,16 +152,14 @@
 }
 
 /*
- * Attempts to set the interface PIO mode.
- * The preferred method of selecting PIO modes (e.g. mode 4) is
- * "echo 'piomode:4' > /proc/ide/hdx/settings".  Special cases are
+ * Attempts to set the interface PIO mode. Special cases are
  * 8: prefetch off, 9: prefetch on, 255: auto-select best mode.
  * Called with 255 at boot time.
  */
 static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted)
 {
 	int recovery_time, clock_time;
-	byte recovery_count2, cycle_count;
+	u8 recovery_count2, cycle_count, speed;
 	int setup_count, active_count, recovery_count;
 	struct ata_timing *t;
 
@@ -172,10 +170,14 @@
 			/*set_prefetch_mode(index, mode_wanted);*/
 			cmdprintk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis");
 			return;
-		case 255: mode_wanted = ata_timing_mode(drive, XFER_PIO | XFER_EPIO);
 	}
 
-	t = ata_timing_data(XFER_PIO_0 + min_t(byte, mode_wanted, 4));
+	if (mode_wanted == 255)
+		speed = ata_best_pio_mode(drive);
+	else
+		speed = XFER_PIO_0 + min_t(u8, mode_wanted, 4);
+
+	t = ata_timing_data(speed);
 
 	/*
 	 * I copied all this complicated stuff from cmd640.c and made a few minor changes.
@@ -213,6 +215,9 @@
 	cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns), clocks=%d/%d/%d\n",
 		drive->name, t.mode - XFER_PIO_0, mode_wanted, cycle_time,
 		setup_count, active_count, recovery_count);
+
+	drive->current_speed = speed;
+	ide_config_drive_speed(drive, speed);
 }
 
 static int cmd64x_ratemask(struct ata_device *drive)
@@ -283,13 +288,26 @@
 	}
 }
 
-static void cmd680_tuneproc(struct ata_device *drive, u8 mode_wanted)
+static void cmd680_tuneproc(struct ata_device *drive, u8 pio)
 {
-	struct ata_channel *hwif = drive->channel;
-	struct pci_dev *dev	= hwif->pci_dev;
-	u8 drive_pci;
+	struct ata_channel *ch = drive->channel;
+	struct pci_dev *dev = ch->pci_dev;
+	u8 unit	= (drive->select.b.unit & 0x01);
+	u8 addr_mask = (ch->unit) ? 0x84 : 0x80;
+	u8 drive_pci, mode_pci, speed;
+	u8 channel_timings = cmd680_taskfile_timing(ch);
 	u16 speedt;
 
+	pci_read_config_byte(dev, addr_mask, &mode_pci);
+	mode_pci &= ~(unit ? 0x30 : 0x03);
+
+	if (pio == 255)
+		pio = ata_best_pio_mode(drive) - XFER_PIO_0;
+
+	/* WARNING PIO timing mess is going to happen b/w devices, argh */
+	if ((channel_timings != pio) && (pio > channel_timings))
+		pio = channel_timings;
+
 	switch (drive->dn) {
 		case 0: drive_pci = 0xA4; break;
 		case 1: drive_pci = 0xA6; break;
@@ -302,7 +320,7 @@
 
 	/* cheat for now and use the docs */
 //	switch(cmd680_taskfile_timing(hwif)) {
-	switch(mode_wanted) {
+	switch(pio) {
 		case 4:		speedt = 0x10c1; break;
 		case 3:		speedt = 0x10C3; break;
 		case 2:		speedt = 0x1104; break;
@@ -311,50 +329,11 @@
 		default:	speedt = 0x328A; break;
 	}
 	pci_write_config_word(dev, drive_pci, speedt);
-}
-
-static void config_cmd64x_chipset_for_pio(struct ata_device *drive, u8 set_speed)
-{
-	u8 set_pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	cmd64x_tuneproc(drive, set_pio);
-	if (set_speed)
-		(void) ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
-}
-
-static void config_cmd680_chipset_for_pio(struct ata_device *drive, u8 set_speed)
-{
-	struct ata_channel *hwif = drive->channel;
-	struct pci_dev *dev	= hwif->pci_dev;
-	u8 unit			= (drive->select.b.unit & 0x01);
-	u8 addr_mask		= (hwif->unit) ? 0x84 : 0x80;
-	u8 speed;
-	u8 mode_pci;
-	u8 channel_timings	= cmd680_taskfile_timing(hwif);
-	u8 set_pio		= ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	pci_read_config_byte(dev, addr_mask, &mode_pci);
-	mode_pci &= ~((unit) ? 0x30 : 0x03);
 
-	/* WARNING PIO timing mess is going to happen b/w devices, argh */
-	if ((channel_timings != set_pio) && (set_pio > channel_timings))
-		set_pio = channel_timings;
+	speed = XFER_PIO_0 + min_t(u8, pio, 4);
 
-	cmd680_tuneproc(drive, set_pio);
-	speed = XFER_PIO_0 + set_pio;
-	if (set_speed) {
-		(void) ide_config_drive_speed(drive, speed);
-		drive->current_speed = speed;
-	}
-}
-
-static void config_chipset_for_pio(struct ata_device *drive, byte set_speed)
-{
-        if (drive->channel->pci_dev->device == PCI_DEVICE_ID_CMD_680) {
-		config_cmd680_chipset_for_pio(drive, set_speed);
-	} else {
-		config_cmd64x_chipset_for_pio(drive, set_speed);
-	}
+	drive->current_speed = speed;
+	ide_config_drive_speed(drive, speed);
 }
 
 static int cmd64x_tune_chipset(struct ata_device *drive, byte speed)
@@ -403,11 +382,13 @@
 		case XFER_PIO_1:
 		case XFER_PIO_0:
 			cmd64x_tuneproc(drive, speed - XFER_PIO_0);
-			break;
+			/* FIXME: error checking  --bkz */
+			return 0;
 		default:
 			return 1;
 	}
 
+	cmd64x_tuneproc(drive, 255);
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	(void) pci_write_config_byte(dev, pciU, regU);
 #endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -510,14 +491,13 @@
 		case XFER_PIO_1:
 		case XFER_PIO_0:
 			cmd680_tuneproc(drive, speed - XFER_PIO_0);
-			break;
+			/* FIXME: error checking  --bkz */
+			return 0;
 		default:
 			return 1;
 	}
 
-	if (speed >= XFER_MW_DMA_0) 
-		config_cmd680_chipset_for_pio(drive, 0);
-
+	cmd680_tuneproc(drive, 255);
 	if (speed >= XFER_UDMA_0)
 		mode_pci |= ((unit) ? 0x30 : 0x03);
 	else if (speed >= XFER_MW_DMA_0)
@@ -552,12 +532,6 @@
 
 	mode = ata_timing_mode(drive, map);
 
-	if (mode < XFER_SW_DMA_0) {
-		config_chipset_for_pio(drive, 1);
-		return 0;
-	}
-
-	config_chipset_for_pio(drive, 0);
 	return !drive->channel->speedproc(drive, mode);
 }
 
@@ -568,6 +542,8 @@
 	int on = 1;
 	int verbose = 1;
 
+	hwif->tuneproc(drive, 255);
+
 	if ((id != NULL) && ((id->capability & 1) != 0) &&
 	    hwif->autodma && (drive->type == ATA_DISK)) {
 		/* Consult the list of known "bad" drives */
@@ -610,7 +586,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		config_chipset_for_pio(drive, 1);
+		hwif->tuneproc(drive, 255);
 	}
 
 	udma_enable(drive, on, verbose);
diff -urN linux-2.5.21/drivers/ide/device.c linux/drivers/ide/device.c
--- linux-2.5.21/drivers/ide/device.c	2002-06-11 00:17:34.000000000 +0200
+++ linux/drivers/ide/device.c	2002-06-14 00:02:43.000000000 +0200
@@ -126,9 +126,8 @@
  * setting a timer to wake up at half second intervals thereafter, until
  * timeout is achieved, before timing out.
  *
- * FIXME: Channel lock should be held.
+ * Channel lock should be held.
  */
-
 int ata_status_poll(struct ata_device *drive, u8 good, u8 bad,
 		unsigned long timeout,
 		struct request *rq, ide_startstop_t *startstop)
@@ -159,6 +158,7 @@
 		if (ata_status(drive, good, bad))
 			return 0;
 	}
+
 	*startstop = ata_error(drive, rq, "status error");
 
 	return 1;
diff -urN linux-2.5.21/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- linux-2.5.21/drivers/ide/hpt34x.c	2002-06-13 20:15:09.000000000 +0200
+++ linux/drivers/ide/hpt34x.c	2002-06-13 22:53:06.000000000 +0200
@@ -67,43 +67,6 @@
 	return ide_config_drive_speed(drive, speed);
 }
 
-static void config_chipset_for_pio(struct ata_device *drive)
-{
-	unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-	unsigned short xfer_pio = drive->id->eide_pio_modes;
-
-	u8 timing, speed, pio;
-
-	pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	if (xfer_pio > 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0) {
-		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-			xfer_pio--);
-	} else {
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio;
-	}
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
-	switch(timing) {
-		case 4: speed = XFER_PIO_4;break;
-		case 3: speed = XFER_PIO_3;break;
-		case 2: speed = XFER_PIO_2;break;
-		case 1: speed = XFER_PIO_1;break;
-		default:
-			speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-			break;
-		}
-	(void) hpt34x_tune_chipset(drive, speed);
-}
-
 static void hpt34x_tune_drive(struct ata_device *drive, u8 pio)
 {
 	(void) hpt34x_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4));
@@ -177,7 +140,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		config_chipset_for_pio(drive);
+		hpt34x_tune_chipset(drive, ata_best_pio_mode(drive));
 	}
 
 #ifndef CONFIG_HPT34X_AUTODMA
diff -urN linux-2.5.21/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c
--- linux-2.5.21/drivers/ide/hpt366.c	2002-06-13 20:15:09.000000000 +0200
+++ linux/drivers/ide/hpt366.c	2002-06-13 22:53:06.000000000 +0200
@@ -682,44 +682,6 @@
 	return ide_config_drive_speed(drive, speed);
 }
 
-static void config_chipset_for_pio(struct ata_device *drive)
-{
-	static unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-	unsigned short xfer_pio = drive->id->eide_pio_modes;
-	u8 timing, speed, pio;
-
-	pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	if (xfer_pio > 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0) {
-		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-			xfer_pio--);
-	} else {
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 :
-			   (drive->id->tPIO & 2) ? 0x02 :
-			   (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
-	}
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
-	switch(timing) {
-		case 4: speed = XFER_PIO_4;break;
-		case 3: speed = XFER_PIO_3;break;
-		case 2: speed = XFER_PIO_2;break;
-		case 1: speed = XFER_PIO_1;break;
-		default:
-			speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-			break;
-	}
-	hpt3xx_tune_chipset(drive, speed);
-}
-
 static void hpt3xx_tune_drive(struct ata_device *drive, u8 pio)
 {
 	u8 speed;
@@ -866,8 +828,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-
-		config_chipset_for_pio(drive);
+		hpt3xx_tune_chipset(drive, ata_best_pio_mode(drive));
 	}
 	udma_enable(drive, on, verbose);
 
diff -urN linux-2.5.21/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.21/drivers/ide/ide.c	2002-06-13 20:29:39.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-06-13 23:34:16.000000000 +0200
@@ -671,28 +671,12 @@
 		block = 1;  /* redirect MBR access to EZ-Drive partn table */
 
 	ata_select(drive, 0);
-	spin_unlock_irq(ch->lock);
 	if (ata_status_poll(drive, drive->ready_stat, BUSY_STAT | DRQ_STAT,
 				WAIT_READY, rq, &ret)) {
 		printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
-		spin_lock_irq(ch->lock);
 
-		return ret;
+		goto kill_rq;
 	}
-	spin_lock_irq(ch->lock);
-
-	/* This issues a special drive command.
-	 *
-	 * FIXME: move this down to idedisk_do_request().
-	 */
-	if (rq->flags & REQ_SPECIAL)
-		if (drive->type == ATA_DISK) {
-			spin_unlock_irq(ch->lock);
-			ret = ata_taskfile(drive, rq->special, NULL);
-			spin_lock_irq(ch->lock);
-
-			return ret;
-		}
 
 	if (!ata_ops(drive)) {
 		printk(KERN_WARNING "%s: device type %d not supported\n",
@@ -704,8 +688,8 @@
 	 * handler down to the device type driver.
 	 */
 
-	if (ata_ops(drive)->XXX_do_request) {
-		ret = ata_ops(drive)->XXX_do_request(drive, rq, block);
+	if (ata_ops(drive)->do_request) {
+		ret = ata_ops(drive)->do_request(drive, rq, block);
 	} else {
 		__ata_end_request(drive, rq, 0, 0);
 		ret = ide_stopped;
diff -urN linux-2.5.21/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.21/drivers/ide/ide-cd.c	2002-06-13 20:29:39.000000000 +0200
+++ linux/drivers/ide/ide-cd.c	2002-06-13 23:39:32.000000000 +0200
@@ -732,46 +732,49 @@
 	struct ata_channel *ch = drive->channel;
 	ide_startstop_t startstop;
 	struct cdrom_info *info = drive->driver_data;
+	int ret;
 
+	spin_lock_irqsave(ch->lock, flags);
 	/* Wait for the controller to be idle. */
 	if (ata_status_poll(drive, 0, BUSY_STAT, WAIT_READY, rq, &startstop))
-		return startstop;
-
-	spin_lock_irqsave(ch->lock, flags);
-
-	if (info->dma) {
-		if (info->cmd == READ || info->cmd == WRITE)
-			info->dma = !udma_init(drive, rq);
-		else
-			printk("ide-cd: DMA set, but not allowed\n");
-	}
-
-	/* Set up the controller registers. */
-	OUT_BYTE(info->dma, IDE_FEATURE_REG);
-	OUT_BYTE(0, IDE_NSECTOR_REG);
-	OUT_BYTE(0, IDE_SECTOR_REG);
-
-	OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG);
-	OUT_BYTE(xferlen >> 8  , IDE_HCYL_REG);
-	ata_irq_enable(drive, 1);
-	if (info->dma)
-		udma_start(drive, rq);
-
-	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
-		ata_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
-		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
-		spin_unlock_irqrestore(ch->lock, flags);
+		ret = startstop;
+	else {
+		if (info->dma) {
+			if (info->cmd == READ || info->cmd == WRITE)
+				info->dma = !udma_init(drive, rq);
+			else
+				printk("ide-cd: DMA set, but not allowed\n");
+		}
 
-		return ide_started;
-	} else {
-		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
-		spin_unlock_irqrestore(ch->lock, flags);
+		/* Set up the controller registers. */
+		OUT_BYTE(info->dma, IDE_FEATURE_REG);
+		OUT_BYTE(0, IDE_NSECTOR_REG);
+		OUT_BYTE(0, IDE_SECTOR_REG);
+
+		OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG);
+		OUT_BYTE(xferlen >> 8  , IDE_HCYL_REG);
+		ata_irq_enable(drive, 1);
+		if (info->dma)
+			udma_start(drive, rq);
+
+		if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
+			ata_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
+			OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
+			ret = ide_started;
+		} else {
+			OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
 
-		/* FIXME: Woah we have to ungrab the lock before the IRQ
-		 * handler gets called.
-		 */
-		return handler(drive, rq);
+			/* FIXME: Oj kurwa! We have to ungrab the lock before
+			 * the IRQ handler gets called.
+			 */
+			spin_unlock_irqrestore(ch->lock, flags);
+			ret = handler(drive, rq);
+			spin_lock_irqsave(ch->lock, flags);
+		}
 	}
+	spin_unlock_irqrestore(ch->lock, flags);
+
+	return ret;
 }
 
 /*
@@ -797,10 +800,16 @@
 		if (cdrom_decode_status(&startstop, drive, rq, DRQ_STAT, &stat_dum))
 			return startstop;
 	} else {
+		/* FIXME: make this locking go away */
+		spin_lock_irqsave(ch->lock, flags);
 		/* Otherwise, we must wait for DRQ to get set. */
 		if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
-					WAIT_READY, rq, &startstop))
+					WAIT_READY, rq, &startstop)) {
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return startstop;
+		}
+		spin_unlock_irqrestore(ch->lock, flags);
 	}
 
 	/* Arm the interrupt handler and send the command to the device. */
@@ -1687,8 +1696,6 @@
 
 		return ret;
 	} else if (rq->flags & REQ_SPECIAL) {
-	        /* FIXME: make this unlocking go away*/
-		spin_unlock_irq(ch->lock);
 		/*
 		 * FIXME: Kill REQ_SEPCIAL and replace it with commands queued
 		 * at the request queue instead as suggested by Linus.
@@ -1696,6 +1703,8 @@
 		 * right now this can only be a reset...
 		 */
 
+	        /* FIXME: make this unlocking go away*/
+		spin_unlock_irq(ch->lock);
 		cdrom_end_request(drive, rq, 1);
 		spin_lock_irq(ch->lock);
 
@@ -1704,8 +1713,6 @@
 		struct packet_command pc;
 		ide_startstop_t startstop;
 
-		/* FIXME: make this unlocking go away*/
-		spin_unlock_irq(ch->lock);
 		memset(&pc, 0, sizeof(pc));
 		pc.quiet = 1;
 		pc.timeout = 60 * HZ;
@@ -1713,10 +1720,13 @@
 		/* FIXME --mdcki */
 		rq->special = (char *) &pc;
 
+		/* FIXME: make this unlocking go away*/
+		spin_unlock_irq(ch->lock);
 		startstop = cdrom_do_packet_command(drive, rq);
+		spin_lock_irq(ch->lock);
+
 		if (pc.stat)
 			++rq->errors;
-		spin_lock_irq(ch->lock);
 
 		return startstop;
 	}
@@ -2990,7 +3000,7 @@
 	attach:			ide_cdrom_attach,
 	cleanup:		ide_cdrom_cleanup,
 	standby:		NULL,
-	XXX_do_request:		ide_cdrom_do_request,
+	do_request:		ide_cdrom_do_request,
 	end_request:		NULL,
 	ioctl:			ide_cdrom_ioctl,
 	open:			ide_cdrom_open,
diff -urN linux-2.5.21/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.21/drivers/ide/ide-disk.c	2002-06-13 20:29:39.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-06-13 23:42:53.000000000 +0200
@@ -456,7 +456,7 @@
 
 	rq->special = &args;
 
-	return ata_taskfile(drive, &args, rq);
+	return ata_do_taskfile(drive, &args, rq);
 }
 
 static ide_startstop_t lba28_do_request(struct ata_device *drive, struct request *rq, sector_t block)
@@ -496,7 +496,7 @@
 
 	rq->special = &args;
 
-	return ata_taskfile(drive, &args, rq);
+	return ata_do_taskfile(drive, &args, rq);
 }
 
 /*
@@ -548,7 +548,7 @@
 
 	rq->special = &args;
 
-	return ata_taskfile(drive, &args, rq);
+	return ata_do_taskfile(drive, &args, rq);
 }
 
 /*
@@ -560,14 +560,16 @@
  */
 static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
-	unsigned long flags;
-	struct ata_channel *ch = drive->channel;
-	int ret;
+	/* This issues a special drive command.
+	 */
+	if (rq->flags & REQ_SPECIAL)
+		return ata_do_taskfile(drive, rq->special, rq);
 
 	/* FIXME: this check doesn't make sense */
 	if (!(rq->flags & REQ_CMD)) {
 		blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
 		__ata_end_request(drive, rq, 0, 0);
+
 		return ide_stopped;
 	}
 
@@ -590,6 +592,7 @@
 
 		if (st) {
 			BUG_ON(!ata_pending_commands(drive));
+
 			return ide_started;
 		}
 	}
@@ -1405,7 +1408,7 @@
 	attach:			idedisk_attach,
 	cleanup:		idedisk_cleanup,
 	standby:		idedisk_standby,
-	XXX_do_request:		idedisk_do_request,
+	do_request:		idedisk_do_request,
 	end_request:		NULL,
 	ioctl:			idedisk_ioctl,
 	open:			idedisk_open,
diff -urN linux-2.5.21/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.5.21/drivers/ide/ide-floppy.c	2002-06-13 20:29:39.000000000 +0200
+++ linux/drivers/ide/ide-floppy.c	2002-06-13 23:22:32.000000000 +0200
@@ -958,27 +958,25 @@
 	idefloppy_ireason_reg_t ireason;
 	int ret;
 
+	/* FIXME: Move this lock upwards.
+	 */
+	spin_lock_irqsave(ch->lock, flags);
 	if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
 				WAIT_READY, rq, &startstop)) {
 		printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
 
-		return startstop;
-	}
-
-	/* FIXME: this locking should encompass the above register
-	 * file access too.
-	 */
-
-	spin_lock_irqsave(ch->lock, flags);
-	ireason.all=IN_BYTE (IDE_IREASON_REG);
-
-	if (!ireason.b.cod || ireason.b.io) {
-		printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
-		ret = ide_stopped;
+		ret = startstop;
 	} else {
-		ata_set_handler (drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);	/* Set the interrupt routine */
-		atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */
-		ret = ide_started;
+		ireason.all=IN_BYTE (IDE_IREASON_REG);
+
+		if (!ireason.b.cod || ireason.b.io) {
+			printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
+			ret = ide_stopped;
+		} else {
+			ata_set_handler (drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);	/* Set the interrupt routine */
+			atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */
+			ret = ide_started;
+		}
 	}
 	spin_unlock_irqrestore(ch->lock, flags);
 
@@ -2047,7 +2045,7 @@
 	attach:			idefloppy_attach,
 	cleanup:		idefloppy_cleanup,
 	standby:		NULL,
-	XXX_do_request:		idefloppy_do_request,
+	do_request:		idefloppy_do_request,
 	end_request:		idefloppy_end_request,
 	ioctl:			idefloppy_ioctl,
 	open:			idefloppy_open,
diff -urN linux-2.5.21/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux-2.5.21/drivers/ide/ide-tape.c	2002-06-13 20:29:39.000000000 +0200
+++ linux/drivers/ide/ide-tape.c	2002-06-13 23:21:33.000000000 +0200
@@ -2067,6 +2067,7 @@
 			tape->dsc_polling_frequency = IDETAPE_DSC_MA_FAST;
 			tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
 			idetape_postpone_request(drive, rq);		/* Allow ide.c to handle other requests */
+
 			return ide_stopped;
 		}
 		if (tape->failed_pc == pc)
@@ -2074,20 +2075,22 @@
 		pc->callback(drive, rq);	/* Command finished - Call the callback function */
 		return ide_stopped;
 	}
+	/* FIXME: this locking should encompass the above register
+	 * file access too.
+	 */
+
+	spin_lock_irqsave(ch->lock, flags);
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
 		printk (KERN_ERR "ide-tape: The tape wants to issue more interrupts in DMA mode\n");
 		printk (KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
 		udma_enable(drive, 0, 1);
+		spin_unlock_irqrestore(ch->lock, flags);
 
 		return ide_stopped;
 	}
 #endif
-	/* FIXME: this locking should encompass the above register
-	 * file access too.
-	 */
 
-	spin_lock_irqsave(ch->lock, flags);
 	bcount.b.high = IN_BYTE (IDE_BCOUNTH_REG);			/* Get the number of bytes to transfer */
 	bcount.b.low  = IN_BYTE (IDE_BCOUNTL_REG);			/* on this interrupt */
 	ireason.all   = IN_BYTE (IDE_IREASON_REG);
@@ -2198,37 +2201,35 @@
 	ide_startstop_t startstop;
 	int ret;
 
+	/* FIXME: Move this lock upwards.
+	 */
+	spin_lock_irqsave(ch->lock, flags);
 	if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
 				WAIT_READY, rq, &startstop)) {
 		printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
 
-		return startstop;
-	}
-
-	/* FIXME: this locking should encompass the above register
-	 * file access too.
-	 */
-
-	spin_lock_irqsave(ch->lock, flags);
-	ireason.all = IN_BYTE (IDE_IREASON_REG);
-	while (retries-- && (!ireason.b.cod || ireason.b.io)) {
-		printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n");
-		udelay(100);
-		ireason.all = IN_BYTE(IDE_IREASON_REG);
-		if (retries == 0) {
-			printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, ignoring\n");
-			ireason.b.cod = 1;
-			ireason.b.io = 0;
-		}
-	}
-	if (!ireason.b.cod || ireason.b.io) {
-		printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
-		ret = ide_stopped;
+		ret = startstop;
 	} else {
-		tape->cmd_start_time = jiffies;
-		ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* Set the interrupt routine */
-		atapi_write(drive,pc->c,12);	/* Send the actual packet */
-		ret = ide_started;
+		ireason.all = IN_BYTE (IDE_IREASON_REG);
+		while (retries-- && (!ireason.b.cod || ireason.b.io)) {
+			printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n");
+			udelay(100);
+			ireason.all = IN_BYTE(IDE_IREASON_REG);
+			if (retries == 0) {
+				printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, ignoring\n");
+				ireason.b.cod = 1;
+				ireason.b.io = 0;
+			}
+		}
+		if (!ireason.b.cod || ireason.b.io) {
+			printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
+			ret = ide_stopped;
+		} else {
+			tape->cmd_start_time = jiffies;
+			ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* Set the interrupt routine */
+			atapi_write(drive,pc->c,12);	/* Send the actual packet */
+			ret = ide_started;
+		}
 	}
 	spin_unlock_irqrestore(ch->lock, flags);
 
@@ -2736,10 +2737,8 @@
 			}
 		} else if (jiffies - tape->dsc_polling_start > IDETAPE_DSC_MA_THRESHOLD)
 			tape->dsc_polling_frequency = IDETAPE_DSC_MA_SLOW;
-		/* FIXME: make this unlocking go away*/
-		spin_unlock_irq(ch->lock);
 		idetape_postpone_request(drive, rq);
-		spin_lock_irq(ch->lock);
+
 		return ide_stopped;
 	}
 	switch (rq->flags) {
@@ -6128,7 +6127,7 @@
 	attach:			idetape_attach,
 	cleanup:		idetape_cleanup,
 	standby:		NULL,
-	XXX_do_request:		idetape_do_request,
+	do_request:		idetape_do_request,
 	end_request:		idetape_end_request,
 	ioctl:			idetape_blkdev_ioctl,
 	open:			idetape_blkdev_open,
diff -urN linux-2.5.21/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.21/drivers/ide/ide-taskfile.c	2002-06-13 20:15:09.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-06-13 23:41:56.000000000 +0200
@@ -177,9 +177,9 @@
 }
 
 /*
- * FIXME: Channel lock should be held on entry.
+ * Channel lock should be held on entry.
  */
-ide_startstop_t ata_taskfile(struct ata_device *drive,
+ide_startstop_t ata_do_taskfile(struct ata_device *drive,
 		struct ata_taskfile *ar, struct request *rq)
 {
 	struct hd_driveid *id = drive->id;
@@ -196,27 +196,21 @@
 	if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) &&
 	    (drive->addressing == 1))
 		ata_out_regfile(drive, &ar->hobfile);
+
 	ata_out_regfile(drive, &ar->taskfile);
 
 	OUT_BYTE((ar->taskfile.device_head & (drive->addressing ? 0xE0 : 0xEF)) | drive->select.all,
 			IDE_SELECT_REG);
 
 	if (ar->handler) {
-		unsigned long flags;
 		struct ata_channel *ch = drive->channel;
 
 		/* This is apparently supposed to reset the wait timeout for
 		 * the interrupt to accur.
 		 */
 
-		/* FIXME: this locking should encompass the above register
-		 * file access too.
-		 */
-
-		spin_lock_irqsave(ch->lock, flags);
 		ata_set_handler(drive, ar->handler, WAIT_CMD, NULL);
 		OUT_BYTE(ar->cmd, IDE_COMMAND_REG);
-		spin_unlock_irqrestore(ch->lock, flags);
 
 		/* FIXME: Warning check for race between handler and prehandler
 		 * for writing first block of data.  however since we are well
@@ -240,6 +234,7 @@
 						WAIT_DRQ, rq, &startstop)) {
 				printk(KERN_ERR "%s: no DRQ after issuing %s\n",
 						drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
+
 				return startstop;
 			}
 
@@ -261,6 +256,7 @@
 				return ide_started;
 			} else {
 				int i;
+				int ret;
 
 				/* Polling wait until the drive is ready.
 				 *
@@ -278,7 +274,12 @@
 				if (!drive_is_ready(drive)) {
 					printk(KERN_ERR "DISASTER WAITING TO HAPPEN!\n");
 				}
-				return ar->handler(drive, rq);
+				/* FIXME: make this unlocking go away*/
+				spin_unlock_irq(ch->lock);
+				ret =  ar->handler(drive, rq);
+				spin_lock_irq(ch->lock);
+
+				return ret;
 			}
 		}
 	} else {
@@ -448,6 +449,6 @@
 EXPORT_SYMBOL(ide_do_drive_cmd);
 EXPORT_SYMBOL(ata_read);
 EXPORT_SYMBOL(ata_write);
-EXPORT_SYMBOL(ata_taskfile);
+EXPORT_SYMBOL(ata_do_taskfile);
 EXPORT_SYMBOL(ata_special_intr);
 EXPORT_SYMBOL(ide_raw_taskfile);
diff -urN linux-2.5.21/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.5.21/drivers/ide/pdc202xx.c	2002-06-13 20:29:39.000000000 +0200
+++ linux/drivers/ide/pdc202xx.c	2002-06-13 22:53:06.000000000 +0200
@@ -364,12 +364,12 @@
  * 180, 120,  90,  90,  90,  60,  30
  *  11,   5,   4,   3,   2,   1,   0
  */
-static void config_chipset_for_pio(struct ata_device *drive, byte pio)
+static void pdc202xx_tune_drive(struct ata_device *drive, u8 pio)
 {
-	byte speed;
+	u8 speed;
 
 	if (pio == 255)
-		speed = ata_timing_mode(drive, XFER_PIO | XFER_EPIO);
+		speed = ata_best_pio_mode(drive);
 	else	speed = XFER_PIO_0 + min_t(byte, pio, 4);
 
 	pdc202xx_tune_chipset(drive, speed);
@@ -543,7 +543,7 @@
 		} else goto no_dma_set;
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 no_dma_set:
-		config_chipset_for_pio(drive, 5);
+		pdc202xx_tune_drive(drive, 255);
 	}
 
 	udma_enable(drive, on, verbose);
@@ -723,7 +723,7 @@
 
 static void __init ide_init_pdc202xx(struct ata_channel *hwif)
 {
-	hwif->tuneproc  = &config_chipset_for_pio;
+	hwif->tuneproc  = &pdc202xx_tune_drive;
 	hwif->quirkproc = &check_in_drive_lists;
 
         switch(hwif->pci_dev->device) {
diff -urN linux-2.5.21/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c
--- linux-2.5.21/drivers/ide/pdc4030.c	2002-06-10 23:47:13.000000000 +0200
+++ linux/drivers/ide/pdc4030.c	2002-06-13 21:54:55.000000000 +0200
@@ -247,12 +247,19 @@
 	if (pdc4030_cmd(drive, PROMISE_GET_CONFIG)) {
 		return 0;
 	}
+
+	/* FIXME: Make this go away. */
+	spin_lock_irq(hwif->lock);
 	if (ata_status_poll(drive, DATA_READY, BAD_W_STAT,
 				WAIT_DRQ, NULL, &startstop)) {
 		printk(KERN_INFO
 			"%s: Failed Promise read config!\n",hwif->name);
+		spin_unlock_irq(hwif->lock);
+
 		return 0;
 	}
+	spin_unlock_irq(hwif->lock);
+
 	promise_read(drive, &ident, SECTOR_WORDS);
 	if (ident.id[1] != 'P' || ident.id[0] != 'T') {
 		return 0;
@@ -720,21 +727,34 @@
 
 	case WRITE: {
 		ide_startstop_t startstop;
-/*
- * Strategy on write is:
- *	look for the DRQ that should have been immediately asserted
- *	copy the request into the hwgroup's scratchpad
- *	call the promise_write function to deal with writing the data out
- * NOTE: No interrupts are generated on writes. Write completion must be polled
- */
+		unsigned long flags;
+		struct ata_channel *ch = drive->channel;
+
+		/*
+		 * Strategy on write is: look for the DRQ that should have been
+		 * immediately asserted copy the request into the hwgroup's
+		 * scratchpad call the promise_write function to deal with
+		 * writing the data out.
+		 *
+		 * NOTE: No interrupts are generated on writes. Write
+		 * completion must be polled
+		 */
+
+		/* FIXME: Move this lock upwards.
+		 */
+		spin_lock_irqsave(ch->lock, flags);
 		if (ata_status_poll(drive, DATA_READY, drive->bad_wstat,
 					WAIT_DRQ, rq, &startstop )) {
 			printk(KERN_ERR "%s: no DRQ after issuing "
 			       "PROMISE_WRITE\n", drive->name);
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return startstop;
 		}
 		if (!drive->channel->unmask)
 			__cli();	/* local CPU only */
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		return promise_do_write(drive, rq);
 	}
 
diff -urN linux-2.5.21/drivers/ide/serverworks.c linux/drivers/ide/serverworks.c
--- linux-2.5.21/drivers/ide/serverworks.c	2002-06-09 17:44:23.000000000 +0200
+++ linux/drivers/ide/serverworks.c	2002-06-13 22:53:06.000000000 +0200
@@ -226,44 +226,6 @@
 	return ide_config_drive_speed(drive, speed);
 }
 
-static void config_chipset_for_pio(struct ata_device *drive)
-{
-	unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
-	unsigned short xfer_pio = drive->id->eide_pio_modes;
-	byte timing, speed, pio;
-
-	pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	if (xfer_pio > 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0)
-		for (xfer_pio = 5;
-			xfer_pio>0 &&
-			drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio];
-			xfer_pio--);
-	else
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 :
-			   (drive->id->tPIO & 2) ? 0x02 :
-			   (drive->id->tPIO & 1) ? 0x01 : xfer_pio;
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
-	switch(timing) {
-		case 4: speed = XFER_PIO_4;break;
-		case 3: speed = XFER_PIO_3;break;
-		case 2: speed = XFER_PIO_2;break;
-		case 1: speed = XFER_PIO_1;break;
-		default:
-			speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
-			break;
-	}
-	(void) svwks_tune_chipset(drive, speed);
-	drive->current_speed = speed;
-}
-
 static void svwks_tune_drive(struct ata_device *drive, byte pio)
 {
 	byte speed;
@@ -337,7 +299,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		config_chipset_for_pio(drive);
+		svwks_tune_chipset(drive, ata_best_pio_mode(drive));
 	}
 
 	udma_enable(drive, on, verbose);
diff -urN linux-2.5.21/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c
--- linux-2.5.21/drivers/ide/sis5513.c	2002-06-09 07:29:00.000000000 +0200
+++ linux/drivers/ide/sis5513.c	2002-06-13 22:53:06.000000000 +0200
@@ -263,15 +263,11 @@
 
 
 /* Set per-drive active and recovery time */
-static void config_art_rwp_pio(struct ata_device *drive, u8 pio)
+static int config_art_rwp_pio(struct ata_device *drive, u8 pio)
 {
 	struct ata_channel *hwif = drive->channel;
-	struct pci_dev *dev	= hwif->pci_dev;
-
-	byte			timing, drive_pci, test1, test2;
-
-	unsigned short eide_pio_timing[6] = {600, 390, 240, 180, 120, 90};
-	unsigned short xfer_pio = drive->id->eide_pio_modes;
+	struct pci_dev *dev = hwif->pci_dev;
+	u8 drive_pci, test1, test2, speed;
 
 #ifdef DEBUG
 	sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
@@ -279,25 +275,6 @@
 
 	config_drive_art_rwp(drive);
 
-	if (pio == 255)
-		pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
-
-	if (xfer_pio> 4)
-		xfer_pio = 0;
-
-	if (drive->id->eide_pio_iordy > 0) {
-		for (xfer_pio = 5;
-			(xfer_pio > 0) &&
-			(drive->id->eide_pio_iordy > eide_pio_timing[xfer_pio]);
-			xfer_pio--);
-	} else {
-		xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 :
-			   (drive->id->eide_pio_modes & 2) ? 0x04 :
-			   (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio;
-	}
-
-	timing = (xfer_pio >= pio) ? xfer_pio : pio;
-
 #ifdef DEBUG
 	printk("SIS5513: config_drive_art_rwp_pio, drive %d, pio %d, timing %d\n",
 	       drive->dn, pio, timing);
@@ -308,7 +285,7 @@
 		case 1:		drive_pci = 0x42; break;
 		case 2:		drive_pci = 0x44; break;
 		case 3:		drive_pci = 0x46; break;
-		default:	return;
+		default:	return 1;
 	}
 
 	/* register layout changed with newer ATA100 chips */
@@ -320,7 +297,7 @@
 		test1 &= ~0x0F;
 		test2 &= ~0x07;
 
-		switch(timing) {
+		switch(pio) {
 			case 4:		test1 |= 0x01; test2 |= 0x03; break;
 			case 3:		test1 |= 0x03; test2 |= 0x03; break;
 			case 2:		test1 |= 0x04; test2 |= 0x04; break;
@@ -330,7 +307,7 @@
 		pci_write_config_byte(dev, drive_pci, test1);
 		pci_write_config_byte(dev, drive_pci+1, test2);
 	} else {
-		switch(timing) { /*   active  recovery
+		switch(pio) { /*   active  recovery
 					  v     v */
 			case 4:		test1 = 0x30|0x01; break;
 			case 3:		test1 = 0x30|0x03; break;
@@ -344,21 +321,7 @@
 #ifdef DEBUG
 	sis5513_load_verify_registers(dev, "config_drive_art_rwp_pio start");
 #endif
-}
-
-static int config_chipset_for_pio(struct ata_device *drive, u8 pio)
-{
-	u8 speed;
-
-	switch(pio) {
-		case 4:		speed = XFER_PIO_4; break;
-		case 3:		speed = XFER_PIO_3; break;
-		case 2:		speed = XFER_PIO_2; break;
-		case 1:		speed = XFER_PIO_1; break;
-		default:	speed = XFER_PIO_0; break;
-	}
-
-	config_art_rwp_pio(drive, pio);
+	speed = XFER_PIO_0 + min_t(u8, pio, 4);
 	drive->current_speed = speed;
 	return ide_config_drive_speed(drive, speed);
 }
@@ -424,12 +387,14 @@
 		case XFER_SW_DMA_0:
 			break;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
-		case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));
-		case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));
-		case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));
-		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
+		case XFER_PIO_4:
+		case XFER_PIO_3:
+		case XFER_PIO_2:
+		case XFER_PIO_1:
 		case XFER_PIO_0:
-		default:	 return((int) config_chipset_for_pio(drive, 0));
+			return config_art_rwp_pio(drive, speed - XFER_PIO_0);
+		default:
+			return config_art_rwp_pio(drive, 0);
 	}
 	drive->current_speed = speed;
 #ifdef DEBUG
@@ -440,7 +405,10 @@
 
 static void sis5513_tune_drive(struct ata_device *drive, u8 pio)
 {
-	(void) config_chipset_for_pio(drive, pio);
+	if (pio == 255)
+		pio = ata_best_pio_mode(drive) - XFER_PIO_0;
+
+	(void)config_art_rwp_pio(drive, min_t(u8, pio, 4));
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -473,8 +441,7 @@
 	int verbose = 1;
 
 	config_drive_art_rwp(drive);
-	config_art_rwp_pio(drive, 5);
-	config_chipset_for_pio(drive, 5);
+	sis5513_tune_drive(drive, 255);
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
@@ -515,7 +482,7 @@
 		on = 0;
 		verbose = 0;
 no_dma_set:
-		(void) config_chipset_for_pio(drive, 5);
+		sis5513_tune_drive(drive, 255);
 	}
 
 	udma_enable(drive, on, verbose);
diff -urN linux-2.5.21/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.5.21/drivers/scsi/ide-scsi.c	2002-06-13 20:29:39.000000000 +0200
+++ linux/drivers/scsi/ide-scsi.c	2002-06-13 23:23:25.000000000 +0200
@@ -403,25 +403,24 @@
 	ide_startstop_t startstop;
 	int ret;
 
+	/* FIXME: Move this lock upwards.
+	 */
+	spin_lock_irqsave(ch->lock, flags);
 	if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
 				WAIT_READY, rq, &startstop)) {
 		printk (KERN_ERR "ide-scsi: Strange, packet command initiated yet DRQ isn't asserted\n");
-		return startstop;
-	}
-
-	/* FIXME: this locking should encompass the above register
-	 * file access too.
-	 */
-	spin_lock_irqsave(ch->lock, flags);
-	ireason = IN_BYTE(IDE_IREASON_REG);
-
-	if ((ireason & (IDESCSI_IREASON_IO | IDESCSI_IREASON_COD)) != IDESCSI_IREASON_COD) {
-		printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
-		ret = ide_stopped;
+		ret = startstop;
 	} else {
-		ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
-		atapi_write(drive, scsi->pc->c, 12);
-		ret = ide_started;
+		ireason = IN_BYTE(IDE_IREASON_REG);
+
+		if ((ireason & (IDESCSI_IREASON_IO | IDESCSI_IREASON_COD)) != IDESCSI_IREASON_COD) {
+			printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
+			ret = ide_stopped;
+		} else {
+			ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
+			atapi_write(drive, scsi->pc->c, 12);
+			ret = ide_started;
+		}
 	}
 	spin_unlock_irqrestore(ch->lock, flags);
 
@@ -549,7 +548,7 @@
 	owner:			THIS_MODULE,
 	attach:			idescsi_attach,
 	cleanup:		idescsi_cleanup,
-	XXX_do_request:		idescsi_do_request,
+	do_request:		idescsi_do_request,
 	end_request:		idescsi_end_request,
 	open:			idescsi_open,
 	release:		idescsi_release,
diff -urN linux-2.5.21/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.21/include/linux/ide.h	2002-06-13 20:29:39.000000000 +0200
+++ linux/include/linux/ide.h	2002-06-13 23:29:55.000000000 +0200
@@ -545,7 +545,7 @@
 	void (*attach) (struct ata_device *);
 	int (*cleanup)(struct ata_device *);
 	int (*standby)(struct ata_device *);
-	ide_startstop_t	(*XXX_do_request)(struct ata_device *, struct request *, sector_t);
+	ide_startstop_t	(*do_request)(struct ata_device *, struct request *, sector_t);
 	int (*end_request)(struct ata_device *, struct request *, int);
 
 	int (*ioctl)(struct ata_device *, struct inode *, struct file *, unsigned int, unsigned long);
@@ -657,7 +657,7 @@
 extern void ata_read(struct ata_device *, void *, unsigned int);
 extern void ata_write(struct ata_device *, void *, unsigned int);
 
-extern ide_startstop_t ata_taskfile(struct ata_device *,
+extern ide_startstop_t ata_do_taskfile(struct ata_device *,
 	struct ata_taskfile *, struct request *);
 
 /*

  parent reply	other threads:[~2002-06-14 11:08 UTC|newest]

Thread overview: 99+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-06-09  5:42 Linux 2.5.21 Linus Torvalds
2002-06-09  7:10 ` 2.5.21 -- suspend.h:58: parse error before "__nosavedata" Miles Lane
2002-06-09  8:40   ` Skip Ford
2002-06-09 13:37 ` [PATCH] 2.5.20 IDE 86 Martin Dalecki
2002-06-09 13:39 ` [PATCH] 2.5.20 locks.h Martin Dalecki
2002-06-10 11:19 ` [PATCH] 2.5.21 "I can't get no compilation" Martin Dalecki
2002-06-10 12:32   ` Anton Altaparmakov
2002-06-10 11:54     ` Martin Dalecki
2002-06-10 13:08       ` Anton Altaparmakov
2002-06-10 11:21 ` [PATCH] 2.5.21 kill warnings 1/19 Martin Dalecki
2002-06-10 11:23 ` [PATCH] 2.5.21 kill warnings 2/19 Martin Dalecki
2002-06-10 11:24 ` [PATCH] 2.5.21 kill warnings 3/19 Martin Dalecki
2002-06-10 11:26 ` [PATCH] 2.5.21 kill warnings 4/19 Martin Dalecki
2002-06-10 18:46   ` Maksim (Max) Krasnyanskiy
2002-06-10 18:57     ` Thomas 'Dent' Mirlacher
2002-06-10 19:08       ` Roland Dreier
2002-06-10 19:14         ` Thomas 'Dent' Mirlacher
2002-06-10 19:19       ` Tom Rini
2002-06-10 19:30         ` Andrew Morton
2002-06-10 19:44           ` Tom Rini
2002-06-10 19:51             ` Andrew Morton
2002-06-10 20:03               ` Thunder from the hill
2002-06-10 20:08                 ` Tom Rini
2002-06-10 20:14                   ` Andrew Morton
2002-06-10 21:01                   ` Maksim (Max) Krasnyanskiy
2002-06-10 21:11                     ` Tom Rini
2002-06-10 21:34                       ` Thunder from the hill
2002-06-10 20:10                 ` Thunder from the hill
2002-06-10 20:15                   ` Tom Rini
2002-06-10 20:05               ` Tom Rini
2002-06-10 20:18                 ` Thomas 'Dent' Mirlacher
2002-06-10 19:46           ` Thunder from the hill
2002-06-10 20:00             ` Andrew Morton
2002-06-11  6:12           ` Martin Dalecki
2002-06-10 21:51     ` Neil Booth
2002-06-10 22:42       ` Maksim (Max) Krasnyanskiy
2002-06-11  6:10     ` Martin Dalecki
2002-06-13 12:01     ` Martin Dalecki
2002-06-11  0:40   ` Greg KH
2002-06-11  6:33     ` Martin Dalecki
2002-06-11  6:38       ` Greg KH
2002-06-11  8:26       ` Russell King
2002-06-11  8:34         ` Martin Dalecki
2002-06-11  9:06           ` Russell King
2002-06-11  9:09             ` Martin Dalecki
2002-06-11  9:28               ` Russell King
2002-06-11  9:42                 ` Martin Dalecki
2002-06-11 10:36                   ` Russell King
2002-06-11 11:06   ` Pavel Machek
2002-06-10 11:28 ` [PATCH] 2.5.21 kill warnings 5/19 Martin Dalecki
2002-06-10 22:24   ` William Lee Irwin III
2002-06-10 22:35     ` Russell King
2002-06-11  0:38   ` Greg KH
2002-06-10 11:35 ` [PATCH] 2.5.21 kill warnings 6/19 Martin Dalecki
2002-06-16 11:05   ` Adrian Bunk
2002-06-10 11:37 ` [PATCH] 2.5.21 kill warnings 7/19 Martin Dalecki
2002-06-10 11:38 ` [PATCH] 2.5.21 kill warnings 8/19 Martin Dalecki
2002-06-10 11:39 ` [PATCH] 2.5.21 kill warnings 9/19 Martin Dalecki
2002-06-10 11:40 ` [PATCH] 2.5.21 kill warnings 10/19 Martin Dalecki
2002-06-10 11:42 ` [PATCH] 2.5.21 kill warnings 11/19 Martin Dalecki
2002-06-10 11:43 ` [PATCH] 2.5.21 kill warnings 12/19 Martin Dalecki
2002-06-10 11:44 ` [PATCH] 2.5.21 kill warnings 13/19 Martin Dalecki
2002-06-10 11:45 ` [PATCH] 2.5.21 kill warinigs 14/19 Martin Dalecki
2002-06-10 18:47   ` Ingo Oeser
2002-06-11  8:07     ` Martin Dalecki
2002-06-11 11:59     ` Dave Jones
2002-06-10 11:46 ` [PATCH] 2.5.21 kill warnings 15/19 Martin Dalecki
2002-06-10 11:48 ` [PATCH] 2.5.21 kill warnings 16/19 Martin Dalecki
2002-06-10 11:49 ` [PATCH] 2.5.21 kill warnings 17/19 Martin Dalecki
2002-06-10 11:49 ` [PATCH] 2.5.21 kill warnings 18/19 Martin Dalecki
2002-06-10 11:50 ` [PATCH] 2.5.21 kill warnings 19/19 Martin Dalecki
2002-06-10 11:59 ` [REVERT] 2.5.21 s390/block/xpram.c Martin Dalecki
2002-06-11  7:46 ` [PATCH] 2.5.21 IDE 87 Martin Dalecki
2002-06-11 19:02   ` John Weber
2002-06-12  7:00     ` Martin Dalecki
2002-06-13  1:25       ` John Weber
2002-06-12 17:39   ` Brad Heilbrun
2002-06-12 10:50 ` [PATCH] 2.5.21 inline abuse Martin Dalecki
2002-06-13 12:45   ` Richard Zidlicky
2002-06-13  9:51 ` [PATCH] 2.5.21 IDE 88 Martin Dalecki
2002-06-14 11:06 ` [PATCH] 2.5.21 IDE 89 Martin Dalecki
2002-06-14 11:08 ` Martin Dalecki [this message]
2002-06-14 14:02 ` [PATCH] 2.5.21 IDE 91 Martin Dalecki
2002-06-14 15:17   ` Jens Axboe
2002-06-14 15:42     ` John Weber
2002-06-14 15:43     ` Dave Jones
2002-06-14 16:06       ` Bartlomiej Zolnierkiewicz
2002-06-14 16:33         ` Martin Dalecki
2002-06-14 17:56       ` Linus Torvalds
2002-06-14 15:56     ` Benjamin LaHaise
2002-06-14 16:04       ` Dave Jones
2002-06-14 17:23         ` Martin Dalecki
2002-06-14 16:09       ` Bartlomiej Zolnierkiewicz
2002-06-14 16:15     ` Martin Dalecki
2002-06-15  8:15       ` Jens Axboe
2002-06-14 16:43     ` Linus Torvalds
2002-06-14 16:47       ` Martin Dalecki
2002-06-15  8:19       ` Jens Axboe
2002-06-16 18:36 ` [PATCH] 2.5.21 ide 92 Martin Dalecki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3D09CE91.9010109@evision-ventures.com \
    --to=dalecki@evision-ventures.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.