All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Dalecki <dalecki@evision-ventures.com>
To: Linus Torvalds <torvalds@transmeta.com>,
	Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH] 2.5.21 IDE 87
Date: Tue, 11 Jun 2002 09:46:21 +0200	[thread overview]
Message-ID: <3D05AACD.2080504@evision-ventures.com> (raw)
In-Reply-To: <Pine.LNX.4.33.0206082235240.4635-100000@penguin.transmeta.com>

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

Sun Jun  9 15:31:56 CEST 2002 ide-clean-87

- Sync with 2.5.21

- Don't call put_device inside idedisk_cleanup(). This is apparently triggering
   some bug inside the handling of device trees. Or we don't register the device
   properly within the tree. Check this later.

- Further work on the channel register file access locking.  Push the locking
   out from __ide_end_request to ide_end_request.  Rename those functions to
   respective __ata_end_request() and ata_end_request().

- Move ide_wait_status to device.c rename it to ata_status_poll().

- Further work on locking scope issues.

- devfs showed us once again that it changed the policy from agnostic numbers
   to unpleasant string names. What a piece of crap!

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

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-09 07:28:51.000000000 +0200
+++ linux/drivers/ide/device.c	2002-06-11 00:17:34.000000000 +0200
@@ -80,7 +80,29 @@
 }
 
 /*
+ * Spin until the drive is no longer busy.
+ *
+ * Not exported, since it's not used within any modules.
+ */
+int ata_busy_poll(struct ata_device *drive, unsigned long timeout)
+{
+	/* spec allows drive 400ns to assert "BUSY" */
+	udelay(1);
+	if (!ata_status(drive, 0, BUSY_STAT)) {
+		timeout += jiffies;
+		while (!ata_status(drive, 0, BUSY_STAT)) {
+			if (time_after(jiffies, timeout))
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
  * Check the state of the status register.
+ *
+ * FIXME: Channel lock should be held.
  */
 int ata_status(struct ata_device *drive, u8 good, u8 bad)
 {
@@ -94,6 +116,57 @@
 EXPORT_SYMBOL(ata_status);
 
 /*
+ * Busy-wait for the drive status to be not "busy".  Check then the status for
+ * all of the "good" bits and none of the "bad" bits, and if all is okay it
+ * returns 0.  All other cases return 1 after invoking error handler -- caller
+ * should just return.
+ *
+ * This routine should get fixed to not hog the cpu during extra long waits..
+ * That could be done by busy-waiting for the first jiffy or two, and then
+ * setting a timer to wake up at half second intervals thereafter, until
+ * timeout is achieved, before timing out.
+ *
+ * FIXME: 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)
+{
+	int i;
+
+	/* bail early if we've exceeded max_failures */
+	if (drive->max_failures && (drive->failures > drive->max_failures)) {
+		*startstop = ide_stopped;
+
+		return 1;
+	}
+
+	if (ata_busy_poll(drive, timeout)) {
+		*startstop = ata_error(drive, rq, "status timeout");
+
+		return 1;
+	}
+
+	/*
+	 * Allow status to settle, then read it again.  A few rare drives
+	 * vastly violate the 400ns spec here, so we'll wait up to 10usec for a
+	 * "good" status rather than expensively fail things immediately.  This
+	 * fix courtesy of Matthew Faupel & Niccolo Rigacci.
+	 */
+	for (i = 0; i < 10; i++) {
+		udelay(1);
+		if (ata_status(drive, good, bad))
+			return 0;
+	}
+	*startstop = ata_error(drive, rq, "status error");
+
+	return 1;
+}
+
+EXPORT_SYMBOL(ata_status_poll);
+
+/*
  * Handle the nIEN - negated Interrupt ENable of the drive.
  * This is controlling whatever the drive will acnowlenge commands
  * with interrupts or not.
@@ -160,7 +233,7 @@
 }
 
 /*
- * Output a complete register file.
+ * Input a complete register file.
  */
 void ata_in_regfile(struct ata_device *drive, struct hd_drive_task_hdr *rf)
 {
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-11 02:11:03.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-06-11 01:02:30.000000000 +0200
@@ -106,18 +106,19 @@
 	return 0;
 }
 
-int __ide_end_request(struct ata_device *drive, struct request *rq, int uptodate, unsigned int nr_secs)
+/*
+ * Not locking variabt of the end_request method.
+ *
+ * Channel lock should be held.
+ */
+int __ata_end_request(struct ata_device *drive, struct request *rq, int uptodate, unsigned int nr_secs)
 {
-	unsigned long flags;
 	int ret = 1;
 
-	spin_lock_irqsave(drive->channel->lock, flags);
-
 	BUG_ON(!(rq->flags & REQ_STARTED));
 
-	/*
-	 * small hack to eliminate locking from ide_end_request to grab
-	 * the first segment number of sectors
+	/* FIXME: Make this "small" hack to eliminate locking from
+	 * ata_end_request to grab the first segment number of sectors go away.
 	 */
 	if (!nr_secs)
 		nr_secs = rq->hard_cur_sectors;
@@ -126,7 +127,6 @@
 	 * Decide whether to reenable DMA -- 3 is a random magic for now,
 	 * if we DMA timeout more than 3 times, just stay in PIO.
 	 */
-
 	if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
 		drive->state = 0;
 		udma_enable(drive, 1, 1);
@@ -143,15 +143,24 @@
 		ret = 0;
 	}
 
-	spin_unlock_irqrestore(drive->channel->lock, flags);
 
 	return ret;
 }
 
-/* This is the default end request function as well */
-int ide_end_request(struct ata_device *drive, struct request *rq, int uptodate)
+/*
+ * This is the default end request function as well
+ */
+int ata_end_request(struct ata_device *drive, struct request *rq, int uptodate)
 {
-	return __ide_end_request(drive, rq, uptodate, 0);
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
+	int ret;
+
+	spin_lock_irqsave(ch->lock, flags);
+	ret = __ata_end_request(drive, rq, uptodate, 0);
+	spin_unlock_irqrestore(drive->channel->lock, flags);
+
+	return ret;
 }
 
 /*
@@ -260,24 +269,25 @@
 	struct ata_channel *ch = drive->channel;
 	int ret = ide_stopped;
 
+	spin_lock_irqsave(ch->lock, flags);
 	ata_select(drive, 10);
-
 	if (!ata_status(drive, 0, BUSY_STAT)) {
 		if (time_before(jiffies, ch->poll_timeout)) {
-			spin_lock_irqsave(ch->lock, flags);
 			ata_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
-			spin_unlock_irqrestore(ch->lock, flags);
 			ret = ide_started;	/* continue polling */
 		} else {
 			ch->poll_timeout = 0;	/* end of polling */
 			printk("%s: ATAPI reset timed out, status=0x%02x\n", drive->name, drive->status);
 
-			ret = do_reset1(drive, 1);	/* do it the old fashioned way */
+			ret = do_reset1(drive, 0);	/* do it the old fashioned way */
 		}
 	} else {
 		printk("%s: ATAPI reset complete\n", drive->name);
 		ch->poll_timeout = 0;	/* done polling */
+
+		ret = ide_stopped;
 	}
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ret;
 }
@@ -289,20 +299,20 @@
  */
 static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *__rq)
 {
+	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
+	int ret;
 
+	spin_lock_irqsave(ch->lock, flags);
 	if (!ata_status(drive, 0, BUSY_STAT)) {
 		if (time_before(jiffies, ch->poll_timeout)) {
-			unsigned long flags;
-
-			spin_lock_irqsave(ch->lock, flags);
 			ata_set_handler(drive, reset_pollfunc, HZ/20, NULL);
-			spin_unlock_irqrestore(ch->lock, flags);
-
-			return ide_started;	/* continue polling */
+			ret = ide_started;	/* continue polling */
+		} else {
+			printk("%s: reset timed out, status=0x%02x\n", ch->name, drive->status);
+			++drive->failures;
+			ret = ide_stopped;
 		}
-		printk("%s: reset timed out, status=0x%02x\n", ch->name, drive->status);
-		++drive->failures;
 	} else  {
 		u8 stat;
 
@@ -333,8 +343,11 @@
 			printk(KERN_ERR "%s error [%02x]\n", msg, stat);
 			++drive->failures;
 		}
+
+		ret = ide_stopped;
 	}
 	ch->poll_timeout = 0;	/* done polling */
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_stopped;
 }
@@ -357,7 +370,7 @@
  * Channel lock should be held.
  */
 
-static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
+static ide_startstop_t do_reset1(struct ata_device *drive, int try_atapi)
 {
 	unsigned int unit;
 	unsigned long flags;
@@ -367,15 +380,17 @@
 	__cli();		/* local CPU only */
 
 	/* For an ATAPI device, first try an ATAPI SRST. */
-	if (drive->type != ATA_DISK && !do_not_try_atapi) {
-		check_crc_errors(drive);
-		ata_select(drive, 20);
-		OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
-		ch->poll_timeout = jiffies + WAIT_WORSTCASE;
-		ata_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
-		__restore_flags(flags);	/* local CPU only */
+	if (try_atapi) {
+		if (drive->type != ATA_DISK) {
+			check_crc_errors(drive);
+			ata_select(drive, 20);
+			OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
+			ch->poll_timeout = jiffies + WAIT_WORSTCASE;
+			ata_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
+			__restore_flags(flags);	/* local CPU only */
 
-		return ide_started;
+			return ide_started;
+		}
 	}
 
 	/*
@@ -572,6 +587,7 @@
 
 		return ide_stopped;
 	}
+
 	/* other bits are useless when BUSY */
 	if (stat & BUSY_STAT || ((stat & WRERR_STAT) && !drive->nowerr))
 		rq->errors |= ERROR_RESET; /* FIXME: What's that?! */
@@ -598,14 +614,15 @@
 
 	if (rq->errors >= ERROR_MAX) {
 		printk(KERN_ERR "%s: max number of retries exceeded!\n", drive->name);
+		/* FIXME: make sure all end_request implementations are lock free */
 		if (ata_ops(drive) && ata_ops(drive)->end_request)
 			ata_ops(drive)->end_request(drive, rq, 0);
 		else
-			ide_end_request(drive, rq, 0);
+			__ata_end_request(drive, rq, 0, 0);
 	} else {
 		++rq->errors;
 		if ((rq->errors & ERROR_RESET) == ERROR_RESET)
-			return do_reset1(drive, 0);
+			return do_reset1(drive, 1);
 		if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
 			return do_recalibrate(drive);
 	}
@@ -614,60 +631,6 @@
 }
 
 /*
- * Busy-wait for the drive status to be not "busy".  Check then the status for
- * all of the "good" bits and none of the "bad" bits, and if all is okay it
- * returns 0.  All other cases return 1 after invoking error handler -- caller
- * should just return.
- *
- * This routine should get fixed to not hog the cpu during extra long waits..
- * That could be done by busy-waiting for the first jiffy or two, and then
- * setting a timer to wake up at half second intervals thereafter, until
- * timeout is achieved, before timing out.
- *
- * FIXME: Channel lock should be held.
- */
-int ide_wait_stat(ide_startstop_t *startstop,
-		struct ata_device *drive, struct request *rq,
-		byte good, byte bad, unsigned long timeout)
-{
-	int i;
-
-	/* bail early if we've exceeded max_failures */
-	if (drive->max_failures && (drive->failures > drive->max_failures)) {
-		*startstop = ide_stopped;
-
-		return 1;
-	}
-
-	/* spec allows drive 400ns to assert "BUSY" */
-	udelay(1);
-	if (!ata_status(drive, 0, BUSY_STAT)) {
-		timeout += jiffies;
-		while (!ata_status(drive, 0, BUSY_STAT)) {
-			if (time_after(jiffies, timeout)) {
-				*startstop = ata_error(drive, rq, "status timeout");
-				return 1;
-			}
-		}
-	}
-
-	/*
-	 * Allow status to settle, then read it again.  A few rare drives
-	 * vastly violate the 400ns spec here, so we'll wait up to 10usec for a
-	 * "good" status rather than expensively fail things immediately.  This
-	 * fix courtesy of Matthew Faupel & Niccolo Rigacci.
-	 */
-	for (i = 0; i < 10; i++) {
-		udelay(1);
-		if (ata_status(drive, good, bad))
-			return 0;
-	}
-	*startstop = ata_error(drive, rq, "status error");
-
-	return 1;
-}
-
-/*
  * This initiates handling of a new I/O request.
  */
 static ide_startstop_t start_request(struct ata_device *drive, struct request *rq)
@@ -710,8 +673,8 @@
 		ide_startstop_t res;
 
 		ata_select(drive, 0);
-		if (ide_wait_stat(&res, drive, rq, drive->ready_stat,
-					BUSY_STAT|DRQ_STAT, WAIT_READY)) {
+		if (ata_status_poll(drive, drive->ready_stat, BUSY_STAT | DRQ_STAT,
+					WAIT_READY, rq, &res)) {
 			printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
 
 			return res;
@@ -731,7 +694,7 @@
 		if (ata_ops(drive)->do_request)
 			return ata_ops(drive)->do_request(drive, rq, block);
 		else {
-			ide_end_request(drive, rq, 0);
+			ata_end_request(drive, rq, 0);
 
 			return ide_stopped;
 		}
@@ -748,7 +711,7 @@
 	if (ata_ops(drive) && ata_ops(drive)->end_request)
 		ata_ops(drive)->end_request(drive, rq, 0);
 	else
-		ide_end_request(drive, rq, 0);
+		ata_end_request(drive, rq, 0);
 
 	return ide_stopped;
 }
@@ -1008,64 +971,24 @@
 }
 
 /*
- * Un-busy the hwgroup etc, and clear any pending DMA status. we want to
- * retry the current request in PIO mode instead of risking tossing it
- * all away
- */
-static void dma_timeout_retry(struct ata_device *drive, struct request *rq)
-{
-	/*
-	 * end current dma transaction
-	 */
-	udma_stop(drive);
-	udma_timeout(drive);
-
-	/*
-	 * Disable dma for now, but remember that we did so because of
-	 * a timeout -- we'll reenable after we finish this next request
-	 * (or rather the first chunk of it) in pio.
-	 */
-	drive->retry_pio++;
-	drive->state = DMA_PIO_RETRY;
-	udma_enable(drive, 0, 0);
-
-	/*
-	 * un-busy drive etc (hwgroup->busy is cleared on return) and
-	 * make sure request is sane
-	 */
-	drive->rq = NULL;
-
-	rq->errors = 0;
-	if (rq->bio) {
-		rq->sector = rq->bio->bi_sector;
-		rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
-		rq->buffer = NULL;
-	}
-}
-
-/*
  * This is our timeout function for all drive operations.  But note that it can
  * also be invoked as a result of a "sleep" operation triggered by the
  * mod_timer() call in do_request.
+ *
+ * FIXME: this should take a drive context instead of a channel.
  */
 void ide_timer_expiry(unsigned long data)
 {
-	struct ata_channel *ch = (struct ata_channel *) data;
-	ata_handler_t *handler;
-	ata_expiry_t *expiry;
 	unsigned long flags;
-	unsigned long wait;
-
-	/*
-	 * A global lock protects timers etc -- shouldn't get contention
-	 * worth mentioning.
-	 */
+	struct ata_channel *ch = (struct ata_channel *) data;
 
 	spin_lock_irqsave(ch->lock, flags);
 	del_timer(&ch->timer);
 
-	handler = ch->handler;
-	if (!handler) {
+	if (!ch->drive) {
+		printk(KERN_ERR "%s: IRQ handler was NULL\n", __FUNCTION__);
+		ch->handler = NULL;
+	} else if (!ch->handler) {
 
 		/*
 		 * Either a marginal timeout occurred (got the interrupt just
@@ -1078,69 +1001,103 @@
 			clear_bit(IDE_BUSY, ch->active);
 	} else {
 		struct ata_device *drive = ch->drive;
-		if (!drive) {
-			printk(KERN_ERR "ide_timer_expiry: IRQ handler was NULL\n");
-			ch->handler = NULL;
-		} else {
-			ide_startstop_t startstop;
+		ide_startstop_t ret;
+		ata_handler_t *handler;
 
-			/* paranoia */
-			if (!test_and_set_bit(IDE_BUSY, ch->active))
-				printk(KERN_ERR "%s: ide_timer_expiry: IRQ handler was not busy??\n", drive->name);
-			if ((expiry = ch->expiry) != NULL) {
-				/* continue */
-				if ((wait = expiry(drive, drive->rq)) != 0) {
-					/* reengage timer */
-					ch->timer.expires  = jiffies + wait;
-					add_timer(&ch->timer);
+		/* paranoia */
+		if (!test_and_set_bit(IDE_BUSY, ch->active))
+			printk(KERN_ERR "%s: %s: IRQ handler was not busy?!\n",
+					drive->name, __FUNCTION__);
+
+		if (ch->expiry) {
+			unsigned long wait;
+
+			/* continue */
+			if ((wait = ch->expiry(drive, drive->rq)) != 0) {
+				/* reengage timer */
+				ch->timer.expires  = jiffies + wait;
+				add_timer(&ch->timer);
 
-					spin_unlock_irqrestore(ch->lock, flags);
+				spin_unlock_irqrestore(ch->lock, flags);
 
-					return;
-				}
+				return;
 			}
-			ch->handler = NULL;
-			/*
-			 * We need to simulate a real interrupt when invoking
-			 * the handler() function, which means we need to globally
-			 * mask the specific IRQ:
-			 */
+		}
+
+		/*
+		 * We need to simulate a real interrupt when invoking the
+		 * handler() function, which means we need to globally mask the
+		 * specific IRQ:
+		 */
 
-			spin_unlock(ch->lock);
+		handler = ch->handler;
+		ch->handler = NULL;
+		spin_unlock(ch->lock);
 
-			ch = drive->channel;
+		ch = drive->channel;
 #if DISABLE_IRQ_NOSYNC
-			disable_irq_nosync(ch->irq);
+		disable_irq_nosync(ch->irq);
 #else
-			disable_irq(ch->irq);	/* disable_irq_nosync ?? */
+		disable_irq(ch->irq);	/* disable_irq_nosync ?? */
 #endif
-			__cli();	/* local CPU only, as if we were handling an interrupt */
-			if (ch->poll_timeout != 0) {
-				startstop = handler(drive, drive->rq);
-			} else if (drive_is_ready(drive)) {
-				if (drive->waiting_for_dma)
-					udma_irq_lost(drive);
-				(void) ide_ack_intr(ch);
-				printk("%s: lost interrupt\n", drive->name);
-				startstop = handler(drive, drive->rq);
-			} else {
-				if (drive->waiting_for_dma) {
-					startstop = ide_stopped;
-					dma_timeout_retry(drive, drive->rq);
-				} else
-					startstop = ata_error(drive, drive->rq, "irq timeout");
+		__cli();	/* local CPU only, as if we were handling an interrupt */
+		if (ch->poll_timeout) {
+			ret = handler(drive, drive->rq);
+		} else if (drive_is_ready(drive)) {
+			if (drive->waiting_for_dma)
+				udma_irq_lost(drive);
+			(void) ide_ack_intr(ch);
+			printk("%s: lost interrupt\n", drive->name);
+			ret = handler(drive, drive->rq);
+		} else if (drive->waiting_for_dma) {
+			struct request *rq = drive->rq;
+
+			/*
+			 * Un-busy the hwgroup etc, and clear any pending DMA
+			 * status. we want to retry the current request in PIO
+			 * mode instead of risking tossing it all away.
+			 */
+
+			udma_stop(drive);
+			udma_timeout(drive);
+
+			/* Disable dma for now, but remember that we did so
+			 * because of a timeout -- we'll reenable after we
+			 * finish this next request (or rather the first chunk
+			 * of it) in pio.
+			 */
+
+			drive->retry_pio++;
+			drive->state = DMA_PIO_RETRY;
+			udma_enable(drive, 0, 0);
+
+			/* Un-busy drive etc (hwgroup->busy is cleared on
+			 * return) and make sure request is sane.
+			 */
+
+			drive->rq = NULL;
+
+			rq->errors = 0;
+			if (rq->bio) {
+				rq->sector = rq->bio->bi_sector;
+				rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
+				rq->buffer = NULL;
 			}
-			enable_irq(ch->irq);
+			ret = ide_stopped;
+		} else
+			ret = ata_error(drive, drive->rq, "irq timeout");
 
-			spin_lock_irq(ch->lock);
+		enable_irq(ch->irq);
 
-			if (startstop == ide_stopped)
-				clear_bit(IDE_BUSY, ch->active);
-		}
-	}
+		spin_lock_irq(ch->lock);
+
+		if (ret == ide_stopped)
+			clear_bit(IDE_BUSY, ch->active);
 
-	do_request(ch->drive->channel);
 
+		/* Reenter the request handling engine */
+		do_request(ch);
+	}
 	spin_unlock_irqrestore(ch->lock, flags);
 }
 
@@ -1440,11 +1397,10 @@
 EXPORT_SYMBOL(ata_dump);
 EXPORT_SYMBOL(ata_error);
 
-EXPORT_SYMBOL(ide_wait_stat);
 /* FIXME: this is a trully bad name */
 EXPORT_SYMBOL(restart_request);
-EXPORT_SYMBOL(__ide_end_request);
-EXPORT_SYMBOL(ide_end_request);
+EXPORT_SYMBOL(ata_end_request);
+EXPORT_SYMBOL(__ata_end_request);
 EXPORT_SYMBOL(ide_stall_queue);
 
 EXPORT_SYMBOL(ide_setup_ports);
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-11 02:11:03.000000000 +0200
+++ linux/drivers/ide/ide-cd.c	2002-06-11 00:02:07.000000000 +0200
@@ -556,7 +556,7 @@
 	if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
 		uptodate = 1;
 
-	ide_end_request(drive, rq, uptodate);
+	ata_end_request(drive, rq, uptodate);
 }
 
 
@@ -734,7 +734,7 @@
 	struct cdrom_info *info = drive->driver_data;
 
 	/* Wait for the controller to be idle. */
-	if (ide_wait_stat(&startstop, drive, rq, 0, BUSY_STAT, WAIT_READY))
+	if (ata_status_poll(drive, 0, BUSY_STAT, WAIT_READY, rq, &startstop))
 		return startstop;
 
 	spin_lock_irqsave(ch->lock, flags);
@@ -798,7 +798,8 @@
 			return startstop;
 	} else {
 		/* Otherwise, we must wait for DRQ to get set. */
-		if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY))
+		if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
+					WAIT_READY, rq, &startstop))
 			return startstop;
 	}
 
@@ -926,7 +927,14 @@
 
 	if (dma) {
 		if (!dma_error) {
-			__ide_end_request(drive, rq, 1, rq->nr_sectors);
+			/* FIXME: this locking should encompass the above register
+			 * file access too.
+			 */
+
+			spin_lock_irqsave(ch->lock, flags);
+			__ata_end_request(drive, rq, 1, rq->nr_sectors);
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return ide_stopped;
 		} else
 			return ata_error(drive, rq, "dma error");
@@ -1518,7 +1526,14 @@
 		if (dma_error)
 			return ata_error(drive, rq, "dma error");
 
-		__ide_end_request(drive, rq, 1, rq->nr_sectors);
+		/* FIXME: this locking should encompass the above register
+		 * file access too.
+		 */
+
+		spin_lock_irqsave(ch->lock, flags);
+		__ata_end_request(drive, rq, 1, rq->nr_sectors);
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		return ide_stopped;
 	}
 
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-11 02:11:03.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-06-11 02:02:50.000000000 +0200
@@ -91,104 +91,99 @@
 }
 
 /*
- * Handler for command with PIO data-in phase
+ * Handler for command with PIO data-in phase.
  */
 static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
 {
 	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
-	char *buf = NULL;
+	int ret;
+
+	spin_lock_irqsave(ch->lock, flags);
 
 	if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
-		if (drive->status & (ERR_STAT|DRQ_STAT))
+		if (drive->status & (ERR_STAT|DRQ_STAT)) {
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return ata_error(drive, rq, __FUNCTION__);
+		}
 
 		if (!(drive->status & BUSY_STAT)) {
-#if 0
-			printk("task_in_intr to Soon wait for next interrupt\n");
-#endif
-
-			/* FIXME: this locking should encompass the above register
-			 * file access too.
-			 */
-
-			spin_lock_irqsave(ch->lock, flags);
+//			printk("task_in_intr to Soon wait for next interrupt\n");
 			ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
 			spin_unlock_irqrestore(ch->lock, flags);
 
 			return ide_started;
 		}
 	}
-	buf = ide_map_rq(rq, &flags);
-#if 0
-	printk("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
-#endif
 
-	ata_read(drive, buf, SECTOR_WORDS);
-	ide_unmap_rq(rq, buf, &flags);
+//	printk("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
+	{
+		unsigned long flags;
+		char *buf;
+
+		buf = ide_map_rq(rq, &flags);
+		ata_read(drive, buf, SECTOR_WORDS);
+		ide_unmap_rq(rq, buf, &flags);
+	}
 
 	/* First segment of the request is complete. note that this does not
 	 * necessarily mean that the entire request is done!! this is only true
-	 * if ide_end_request() returns 0.
+	 * if ata_end_request() returns 0.
 	 */
 
-	if (--rq->current_nr_sectors <= 0) {
-#if 0
-		printk("Request Ended stat: %02x\n", drive->status);
-#endif
-		if (!ide_end_request(drive, rq, 1))
-			return ide_stopped;
-	}
-
-	/* FIXME: this locking should encompass the above register
-	 * file access too.
-	 */
+	if (--rq->current_nr_sectors <= 0 && !__ata_end_request(drive, rq, 1, 0)) {
+//		printk("Request Ended stat: %02x\n", drive->status);
+		ret = ide_stopped;
+	} else {
+		/* still data left to transfer */
+		ata_set_handler(drive, task_in_intr,  WAIT_CMD, NULL);
 
-	spin_lock_irqsave(ch->lock, flags);
-	/* still data left to transfer */
-	ata_set_handler(drive, task_in_intr,  WAIT_CMD, NULL);
+		ret = ide_started;
+	}
 	spin_unlock_irqrestore(ch->lock, flags);
 
-	return ide_started;
+	return ret;
 }
 
 /*
- * Handler for command with PIO data-out phase
+ * Handler for command with PIO data-out phase.
  */
 static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
 {
 	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
-	char *buf = NULL;
+	int ret;
 
-	if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
-		return ata_error(drive, rq, __FUNCTION__);
+	spin_lock_irqsave(ch->lock, flags);
+	if (!ata_status(drive, DRIVE_READY, drive->bad_wstat)) {
+		spin_unlock_irqrestore(ch->lock, flags);
 
-	if (!rq->current_nr_sectors)
-		if (!ide_end_request(drive, rq, 1))
-			return ide_stopped;
+		return ata_error(drive, rq, __FUNCTION__);
+	}
 
-	if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
-		buf = ide_map_rq(rq, &flags);
-#if 0
-		printk("write: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
-#endif
+	if (!rq->current_nr_sectors && !__ata_end_request(drive, rq, 1, 0)) {
+		ret = ide_stopped;
+	} else {
+		if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
+			unsigned long flags;
+			char *buf;
 
-		ata_write(drive, buf, SECTOR_WORDS);
-		ide_unmap_rq(rq, buf, &flags);
-		rq->errors = 0;
-		rq->current_nr_sectors--;
-	}
+//			printk("write: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
+			buf = ide_map_rq(rq, &flags);
+			ata_write(drive, buf, SECTOR_WORDS);
+			ide_unmap_rq(rq, buf, &flags);
 
-	/* FIXME: this locking should encompass the above register
-	 * file access too.
-	 */
+			rq->errors = 0;
+			--rq->current_nr_sectors;
+		}
+		ata_set_handler(drive, task_out_intr, WAIT_CMD, NULL);
 
-	spin_lock_irqsave(ch->lock, flags);
-	ata_set_handler(drive, task_out_intr, WAIT_CMD, NULL);
+		ret = ide_started;
+	}
 	spin_unlock_irqrestore(ch->lock, flags);
 
-	return ide_started;
+	return ret;
 }
 
 /*
@@ -198,63 +193,68 @@
 {
 	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
-	char *buf = NULL;
-	unsigned int msect;
-	unsigned int nsect;
+	int ret;
 
+	spin_lock_irqsave(ch->lock, flags);
 	if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
-		if (drive->status & (ERR_STAT|DRQ_STAT))
-			return ata_error(drive, rq, __FUNCTION__);
+		if (drive->status & (ERR_STAT|DRQ_STAT)) {
+			spin_unlock_irqrestore(ch->lock, flags);
 
-		/* FIXME: this locking should encompass the above register
-		 * file access too.
-		 */
+			return ata_error(drive, rq, __FUNCTION__);
+		}
 
-		spin_lock_irqsave(ch->lock, flags);
 		/* no data yet, so wait for another interrupt */
 		ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
-		spin_unlock_irqrestore(ch->lock, flags);
 
-		return ide_started;
-	}
+		ret = ide_started;
+	} else {
+		unsigned int msect;
 
-	/* (ks/hs): Fixed Multi-Sector transfer */
-	msect = drive->mult_count;
+		/* (ks/hs): Fixed Multi-Sector transfer */
+		msect = drive->mult_count;
 
-	do {
-		nsect = rq->current_nr_sectors;
-		if (nsect > msect)
-			nsect = msect;
+		do {
+			unsigned int nsect;
 
-		buf = ide_map_rq(rq, &flags);
+			nsect = rq->current_nr_sectors;
+			if (nsect > msect)
+				nsect = msect;
 
 #if 0
-		printk("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n",
-			buf, nsect, rq->current_nr_sectors);
+			printk("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n",
+					buf, nsect, rq->current_nr_sectors);
 #endif
-		ata_read(drive, buf, nsect * SECTOR_WORDS);
-		ide_unmap_rq(rq, buf, &flags);
-		rq->errors = 0;
-		rq->current_nr_sectors -= nsect;
-		msect -= nsect;
-		if (!rq->current_nr_sectors) {
-			if (!ide_end_request(drive, rq, 1))
-				return ide_stopped;
-		}
-	} while (msect);
+			{
+				unsigned long flags;
+				char *buf;
+
+				buf = ide_map_rq(rq, &flags);
+				ata_read(drive, buf, nsect * SECTOR_WORDS);
+				ide_unmap_rq(rq, buf, &flags);
+			}
 
-	/* FIXME: this locking should encompass the above register
-	 * file access too.
-	 */
+			rq->errors = 0;
+			rq->current_nr_sectors -= nsect;
+			msect -= nsect;
+
+			/* FIXME: this seems buggy */
+			if (!rq->current_nr_sectors) {
+				if (!__ata_end_request(drive, rq, 1, 0)) {
+					spin_unlock_irqrestore(ch->lock, flags);
 
-	spin_lock_irqsave(ch->lock, flags);
-	/*
-	 * more data left
-	 */
-	ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
+					return ide_stopped;
+				}
+			}
+		} while (msect);
+
+		/* more data left */
+		ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
+
+		ret = ide_started;
+	}
 	spin_unlock_irqrestore(ch->lock, flags);
 
-	return ide_started;
+	return ret;
 }
 
 static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq)
@@ -262,9 +262,9 @@
 	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
 	int ok;
-	int mcount = drive->mult_count;
-	ide_startstop_t startstop;
+	int ret;
 
+	spin_lock_irqsave(ch->lock, flags);
 
 	/*
 	 * FIXME: the drive->status checks here seem to be messy.
@@ -277,80 +277,67 @@
 
 	if (!ok || !rq->nr_sectors) {
 		if (drive->status & (ERR_STAT | DRQ_STAT)) {
-			startstop = ata_error(drive, rq, __FUNCTION__);
+			spin_unlock_irqrestore(ch->lock, flags);
 
-			return startstop;
+			return ata_error(drive, rq, __FUNCTION__);
 		}
 	}
-
 	if (!rq->nr_sectors) {
-		__ide_end_request(drive, rq, 1, rq->hard_nr_sectors);
+		__ata_end_request(drive, rq, 1, rq->hard_nr_sectors);
 		rq->bio = NULL;
-
-		return ide_stopped;
-	}
-
-	if (!ok) {
+		ret = ide_stopped;
+	} else if (!ok) {
 		/* no data yet, so wait for another interrupt */
-		if (!ch->handler) {
-			/* FIXME: this locking should encompass the above register
-			 * file access too.
-			 */
-
-			spin_lock_irqsave(ch->lock, flags);
+		if (!ch->handler)
 			ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
-			spin_unlock_irqrestore(ch->lock, flags);
-		}
+		ret = ide_started;
+	} else {
+		int mcount = drive->mult_count;
 
-		return ide_started;
-	}
+		do {
+			char *buf;
+			int nsect = rq->current_nr_sectors;
+			unsigned long flags;
+
+			if (nsect > mcount)
+				nsect = mcount;
+			mcount -= nsect;
+
+			buf = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
+			rq->sector += nsect;
+			rq->nr_sectors -= nsect;
+			rq->current_nr_sectors -= nsect;
+
+			/* Do we move to the next bio after this? */
+			if (!rq->current_nr_sectors) {
+				/* remember to fix this up /jens */
+				struct bio *bio = rq->bio->bi_next;
+
+				/* end early if we ran out of requests */
+				if (!bio) {
+					mcount = 0;
+				} else {
+					rq->bio = bio;
+					rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
+				}
+			}
 
-	do {
-		char *buffer;
-		int nsect = rq->current_nr_sectors;
-		unsigned long flags;
+			/*
+			 * Ok, we're all setup for the interrupt re-entering us on the
+			 * last transfer.
+			 */
+			ata_write(drive, buf, nsect * SECTOR_WORDS);
+			bio_kunmap_irq(buffer, &flags);
+		} while (mcount);
 
-		if (nsect > mcount)
-			nsect = mcount;
-		mcount -= nsect;
-
-		buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
-		rq->sector += nsect;
-		rq->nr_sectors -= nsect;
-		rq->current_nr_sectors -= nsect;
-
-		/* Do we move to the next bio after this? */
-		if (!rq->current_nr_sectors) {
-			/* remember to fix this up /jens */
-			struct bio *bio = rq->bio->bi_next;
-
-			/* end early if we ran out of requests */
-			if (!bio) {
-				mcount = 0;
-			} else {
-				rq->bio = bio;
-				rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
-			}
-		}
+		rq->errors = 0;
 
-		/*
-		 * Ok, we're all setup for the interrupt re-entering us on the
-		 * last transfer.
-		 */
-		ata_write(drive, buffer, nsect * SECTOR_WORDS);
-		bio_kunmap_irq(buffer, &flags);
-	} while (mcount);
-
-	rq->errors = 0;
-	if (!ch->handler) {
-		/* FIXME: this locking should encompass the above register
-		 * file access too.
-		 */
+		if (!ch->handler)
+			ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
 
-		spin_lock_irqsave(ch->lock, flags);
-		ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
-		spin_unlock_irqrestore(ch->lock, flags);
+		ret = ide_started;
 	}
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_started;
 }
@@ -571,24 +558,34 @@
  */
 static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
-	/*
-	 * Wait until all request have bin finished.
-	 */
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
+	int ret;
 
+	/* make sure all request have bin finished
+	 * FIXME: this check doesn't make sense go! */
 	while (drive->blocked) {
 		yield();
 		printk(KERN_ERR "ide: Request while drive blocked?");
 	}
 
+	/* FIXME: Move this lock entiery upstream. */
+	spin_lock_irqsave(ch->lock, flags);
+
+	/* FIXME: this check doesn't make sense */
 	if (!(rq->flags & REQ_CMD)) {
 		blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
-		ide_end_request(drive, rq, 0);
+		__ata_end_request(drive, rq, 0, 0);
+		spin_unlock_irqrestore(ch->lock, flags);
+
 		return ide_stopped;
 	}
 
 	if (IS_PDC4030_DRIVE) {
 		extern ide_startstop_t promise_do_request(struct ata_device *, struct request *, sector_t);
 
+		spin_unlock_irqrestore(drive->channel->lock, flags);
+
 		return promise_do_request(drive, rq, block);
 	}
 
@@ -596,11 +593,8 @@
 	 * start a tagged operation
 	 */
 	if (drive->using_tcq) {
-		unsigned long flags;
 		int ret;
 
-		spin_lock_irqsave(drive->channel->lock, flags);
-
 		ret = blk_queue_start_tag(&drive->queue, rq);
 
 		if (ata_pending_commands(drive) > drive->max_depth)
@@ -608,27 +602,27 @@
 		if (ata_pending_commands(drive) > drive->max_last_depth)
 			drive->max_last_depth = ata_pending_commands(drive);
 
-		spin_unlock_irqrestore(drive->channel->lock, flags);
-
 		if (ret) {
 			BUG_ON(!ata_pending_commands(drive));
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return ide_started;
 		}
 	}
 
-	/* 48-bit LBA */
 	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
-		return lba48_do_request(drive, rq, block);
+		ret = lba48_do_request(drive, rq, block);
+	else if (drive->select.b.lba)
+		ret = lba28_do_request(drive, rq, block);
+	else
+		ret = chs_do_request(drive, rq, block);
 
-	/* 28-bit LBA */
-	if (drive->select.b.lba)
-		return lba28_do_request(drive, rq, block);
+	spin_unlock_irqrestore(ch->lock, flags);
 
-	/* 28-bit CHS */
-	return chs_do_request(drive, rq, block);
+	return ret;
 }
 
-static int idedisk_open (struct inode *inode, struct file *filp, struct ata_device *drive)
+static int idedisk_open(struct inode *inode, struct file *filp, struct ata_device *drive)
 {
 	MOD_INC_USE_COUNT;
 	if (drive->removable && drive->usage == 1) {
@@ -648,10 +642,11 @@
 				drive->doorlocking = 0;
 		}
 	}
+
 	return 0;
 }
 
-static int idedisk_flushcache(struct ata_device *drive)
+static int flush_cache(struct ata_device *drive)
 {
 	struct ata_taskfile args;
 
@@ -661,6 +656,7 @@
 		args.cmd = WIN_FLUSH_CACHE_EXT;
 	else
 		args.cmd = WIN_FLUSH_CACHE;
+
 	return ide_raw_taskfile(drive, &args);
 }
 
@@ -680,7 +676,7 @@
 		}
 	}
 	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
-		if (idedisk_flushcache(drive))
+		if (flush_cache(drive))
 			printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
 				drive->name);
 	MOD_DEC_USE_COUNT;
@@ -1244,15 +1240,27 @@
 
 static int idedisk_cleanup(struct ata_device *drive)
 {
+	int ret;
+
 	if (!drive)
 	    return 0;
 
-	put_device(&drive->device);
-	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
-		if (idedisk_flushcache(drive))
+	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) {
+		if (flush_cache(drive))
 			printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
 				drive->name);
-	return ide_unregister_subdriver(drive);
+	}
+	ret = ide_unregister_subdriver(drive);
+
+	/* FIXME: This is killing the kernel with BUG 185 at asm/spinlocks.h
+	 * horribly.  Check whatever we did REGISTER the device properly
+	 * in front?
+	 */
+#if 0
+	put_device(&drive->device);
+#endif
+
+	return ret;
 }
 
 static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
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-11 02:11:03.000000000 +0200
+++ linux/drivers/ide/ide-floppy.c	2002-06-10 23:58:47.000000000 +0200
@@ -608,7 +608,7 @@
 /*
  *	idefloppy_end_request is used to finish servicing a request.
  *
- *	For read/write requests, we will call ide_end_request to pass to the
+ *	For read/write requests, we will call ata_end_request to pass to the
  *	next buffer.
  */
 static int idefloppy_end_request(struct ata_device *drive, struct request *rq, int uptodate)
@@ -632,7 +632,7 @@
 		return 0;
 
 	if (!(rq->flags & REQ_SPECIAL)) {
-		ide_end_request(drive, rq, uptodate);
+		ata_end_request(drive, rq, uptodate);
 		return 0;
 	}
 
@@ -956,9 +956,12 @@
 	ide_startstop_t startstop;
 	idefloppy_floppy_t *floppy = drive->driver_data;
 	idefloppy_ireason_reg_t ireason;
+	int ret;
 
-	if (ide_wait_stat (&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
+	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;
 	}
 
@@ -968,18 +971,18 @@
 
 	spin_lock_irqsave(ch->lock, flags);
 	ireason.all=IN_BYTE (IDE_IREASON_REG);
-	if (!ireason.b.cod || ireason.b.io) {
-		spin_unlock_irqrestore(ch->lock, flags);
 
+	if (!ireason.b.cod || ireason.b.io) {
 		printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
-		return ide_stopped;
+		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;
 	}
-
-	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 */
 	spin_unlock_irqrestore(ch->lock, flags);
 
-	return ide_started;
+	return ret;
 }
 
 
@@ -1010,39 +1013,43 @@
 	idefloppy_floppy_t *floppy = drive->driver_data;
 	ide_startstop_t startstop;
 	idefloppy_ireason_reg_t ireason;
+	int ret;
 
-	if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
+	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);
+	ireason.all=IN_BYTE(IDE_IREASON_REG);
 	if (!ireason.b.cod || ireason.b.io) {
-		spin_unlock_irqrestore(ch->lock, flags);
-
 		printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
-		return ide_stopped;
-	}
+		ret = ide_stopped;
+	} else {
 
-	/*
-	 * The following delay solves a problem with ATAPI Zip 100 drives where
-	 * the Busy flag was apparently being deasserted before the unit was
-	 * ready to receive data. This was happening on a 1200 MHz Athlon
-	 * system. 10/26/01 25msec is too short, 40 and 50msec work well.
-	 * idefloppy_pc_intr will not be actually used until after the packet
-	 * is moved in about 50 msec.
-	 */
-	ata_set_handler(drive,
-			idefloppy_pc_intr,	/* service routine for packet command */
-			floppy->ticks,		/* wait this long before "failing" */
-			idefloppy_transfer_pc2);	/* fail == transfer_pc2 */
+		/*
+		 * The following delay solves a problem with ATAPI Zip 100 drives where
+		 * the Busy flag was apparently being deasserted before the unit was
+		 * ready to receive data. This was happening on a 1200 MHz Athlon
+		 * system. 10/26/01 25msec is too short, 40 and 50msec work well.
+		 * idefloppy_pc_intr will not be actually used until after the packet
+		 * is moved in about 50 msec.
+		 */
+		ata_set_handler(drive,
+				idefloppy_pc_intr,	/* service routine for packet command */
+				floppy->ticks,		/* wait this long before "failing" */
+				idefloppy_transfer_pc2);	/* fail == transfer_pc2 */
+		ret = ide_started;
+	}
 	spin_unlock_irqrestore(ch->lock, flags);
 
-	return ide_started;
+	return ret;
 }
 
 /*
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-11 02:11:03.000000000 +0200
+++ linux/drivers/ide/ide-tape.c	2002-06-11 00:18:38.000000000 +0200
@@ -2196,9 +2196,12 @@
 	idetape_ireason_reg_t ireason;
 	int retries = 100;
 	ide_startstop_t startstop;
+	int ret;
 
-	if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
+	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;
 	}
 
@@ -2220,16 +2223,16 @@
 	}
 	if (!ireason.b.cod || ireason.b.io) {
 		printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
-		spin_unlock_irqrestore(ch->lock, flags);
-
-		return ide_stopped;
+		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;
 	}
-	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 */
 	spin_unlock_irqrestore(ch->lock, flags);
 
-	return ide_started;
+	return ret;
 }
 
 static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive,
@@ -2618,7 +2621,7 @@
 		 *	We do not support buffer cache originated requests.
 		 */
 		printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request queue (%ld)\n", drive->name, rq->flags);
-		ide_end_request(drive, rq, 0);			/* Let the common code handle it */
+		ata_end_request(drive, rq, 0);			/* Let the common code handle it */
 		return ide_stopped;
 	}
 
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-11 02:11:03.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-06-10 23:42:40.000000000 +0200
@@ -233,7 +233,8 @@
 		    ar->cmd == WIN_MULTWRITE_EXT) {
 			ide_startstop_t startstop;
 
-			if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
+			if (ata_status_poll(drive, DATA_READY, drive->bad_wstat,
+						WAIT_DRQ, rq, &startstop)) {
 				printk(KERN_ERR "%s: no DRQ after issuing %s\n",
 						drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
 				return startstop;
diff -urN linux-2.5.21/drivers/ide/main.c linux/drivers/ide/main.c
--- linux-2.5.21/drivers/ide/main.c	2002-06-11 02:11:03.000000000 +0200
+++ linux/drivers/ide/main.c	2002-06-11 02:04:39.000000000 +0200
@@ -430,7 +430,7 @@
 		struct ata_device *drive = &ch->drives[i];
 
 		if (drive->de) {
-			devfs_unregister (drive->de);
+			devfs_unregister(drive->de);
 			drive->de = NULL;
 		}
 		if (!drive->present)
@@ -1246,7 +1246,7 @@
 			return NOTIFY_DONE;
 	}
 
-	printk("flushing ide devices: ");
+	printk(KERN_INFO "flushing ATA/ATAPI devices: ");
 
 	for (i = 0; i < MAX_HWIFS; i++) {
 		int unit;
@@ -1264,9 +1264,10 @@
 			/* set the drive to standby */
 			printk("%s ", drive->name);
 			if (ata_ops(drive)) {
-				if (event != SYS_RESTART)
+				if (event != SYS_RESTART) {
 					if (ata_ops(drive)->standby && ata_ops(drive)->standby(drive))
 						continue;
+				}
 
 				if (ata_ops(drive)->cleanup)
 					ata_ops(drive)->cleanup(drive);
@@ -1290,8 +1291,7 @@
 {
 	printk(KERN_INFO "ATA/ATAPI device driver v" VERSION "\n");
 
-	ide_devfs_handle = devfs_mk_dir(NULL, "ata", NULL);
-	devfs_mk_symlink(NULL, "ide", DEVFS_FL_DEFAULT, "ata", NULL, NULL);
+	ide_devfs_handle = devfs_mk_dir(NULL, "ide", NULL);
 
 	/*
 	 * Because most of the ATA adapters represent the timings in unit of
diff -urN linux-2.5.21/drivers/ide/pcidma.c linux/drivers/ide/pcidma.c
--- linux-2.5.21/drivers/ide/pcidma.c	2002-06-11 02:11:03.000000000 +0200
+++ linux/drivers/ide/pcidma.c	2002-06-10 03:24:16.000000000 +0200
@@ -44,7 +44,17 @@
 
 	if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
 		if (!dma_stat) {
-			__ide_end_request(drive, rq, 1, rq->nr_sectors);
+			unsigned long flags;
+			struct ata_channel *ch = drive->channel;
+
+			/* FIXME: this locking should encompass the above register
+			 * file access too.
+			 */
+
+			spin_lock_irqsave(ch->lock, flags);
+			__ata_end_request(drive, rq, 1, rq->nr_sectors);
+			spin_unlock_irqrestore(ch->lock, flags);
+
 			return ide_stopped;
 		}
 		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
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-11 02:11:07.000000000 +0200
+++ linux/drivers/ide/pdc4030.c	2002-06-10 23:47:13.000000000 +0200
@@ -247,7 +247,8 @@
 	if (pdc4030_cmd(drive, PROMISE_GET_CONFIG)) {
 		return 0;
 	}
-	if (ide_wait_stat(&startstop, drive, NULL, DATA_READY,BAD_W_STAT,WAIT_DRQ)) {
+	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);
 		return 0;
@@ -407,7 +408,8 @@
 	rq->nr_sectors -= nsect;
 	total_remaining = rq->nr_sectors;
 	if ((rq->current_nr_sectors -= nsect) <= 0) {
-		ide_end_request(drive, rq, 1);
+		/* FIXME: no queue locking above! */
+		ata_end_request(drive, rq, 1);
 	}
 
 	/*
@@ -461,13 +463,11 @@
  */
 static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
 	struct ata_channel *ch = drive->channel;
 
 	if (!ata_status(drive, 0, BUSY_STAT)) {
 		if (time_before(jiffies, ch->poll_timeout)) {
-			unsigned long flags;
-			struct ata_channel *ch = drive->channel;
-
 			/* FIXME: this locking should encompass the above
 			 * register file access too.
 			 */
@@ -488,7 +488,13 @@
 #ifdef DEBUG_WRITE
 	printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name);
 #endif
-	__ide_end_request(drive, rq, 1, rq->nr_sectors);
+	/* FIXME: this locking should encompass the above
+	 * register file access too.
+	 */
+
+	spin_lock_irqsave(ch->lock, flags);
+	__ata_end_request(drive, rq, 1, rq->nr_sectors);
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	return ide_stopped;
 }
@@ -653,7 +659,7 @@
 	/* Check that it's a regular command. If not, bomb out early. */
 	if (!(rq->flags & REQ_CMD)) {
 		blk_dump_rq_flags(rq, "pdc4030 bad flags");
-		ide_end_request(drive, rq, 0);
+		ata_end_request(drive, rq, 0);
 
 		return ide_stopped;
 	}
@@ -721,7 +727,8 @@
  *	call the promise_write function to deal with writing the data out
  * NOTE: No interrupts are generated on writes. Write completion must be polled
  */
-		if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
+		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);
 			return startstop;
@@ -733,7 +740,8 @@
 
 	default:
 		printk(KERN_ERR "pdc4030: command not READ or WRITE! Huh?\n");
-		ide_end_request(drive, rq, 0);
+		/* FIXME: This should already run under the lock. */
+		ata_end_request(drive, rq, 0);
 		return ide_stopped;
 	}
 }
diff -urN linux-2.5.21/drivers/ide/probe.c linux/drivers/ide/probe.c
--- linux-2.5.21/drivers/ide/probe.c	2002-06-09 07:26:25.000000000 +0200
+++ linux/drivers/ide/probe.c	2002-06-11 00:18:00.000000000 +0200
@@ -307,16 +307,7 @@
 		(drive->id->hw_config & 0x6000)) ? 1 : 0);
 }
 
-/*
- * Similar to ide_wait_stat(), except it never calls ata_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.
+/* FIXME: Channel lock should be held.
  */
 int ide_config_drive_speed(struct ata_device *drive, byte speed)
 {
@@ -329,12 +320,10 @@
 	outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2);
 #endif
 
-	/*
-	 * Don't use ide_wait_cmd here - it will attempt to set_geometry and
+	/* Don't use ide_wait_cmd here - it will attempt to set_geometry and
 	 * recalibrate, but for some reason these don't work at this point
 	 * (lost interrupt).
-	 */
-        /*
+         *
          * Select the drive, and issue the SETFEATURES command
          */
 	disable_irq(ch->irq);	/* disable_irq_nosync ?? */
@@ -350,20 +339,7 @@
 		ata_irq_enable(drive, 1);
 	udelay(1);
 
-	/*
-	 * Wait for drive to become non-BUSY
-	 */
-	if (!ata_status(drive, 0, BUSY_STAT)) {
-		unsigned long flags, timeout;
-		__save_flags(flags);	/* local CPU only */
-		ide__sti();		/* local CPU only -- for jiffies */
-		timeout = jiffies + WAIT_CMD;
-		while (!ata_status(drive, 0, BUSY_STAT)) {
-			if (time_after(jiffies, timeout))
-				break;
-		}
-		__restore_flags(flags); /* local CPU only */
-	}
+	ata_busy_poll(drive, WAIT_CMD);
 
 	/*
 	 * Allow status to settle, then read it again.
diff -urN linux-2.5.21/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.21/drivers/ide/tcq.c	2002-06-11 02:11:07.000000000 +0200
+++ linux/drivers/ide/tcq.c	2002-06-10 03:25:55.000000000 +0200
@@ -327,6 +327,8 @@
 
 static ide_startstop_t dmaq_complete(struct ata_device *drive, struct request *rq)
 {
+	unsigned long flags;
+	struct ata_channel *ch = drive->channel;
 	u8 dma_stat;
 
 	/*
@@ -348,7 +350,14 @@
 		printk("%s: bad DMA status (dma_stat=%x)\n", drive->name, dma_stat);
 
 	TCQ_PRINTK("%s: ending %p, tag %d\n", __FUNCTION__, rq, rq->tag);
-	__ide_end_request(drive, rq, !dma_stat, rq->nr_sectors);
+
+	/* FIXME: this locking should encompass the above register
+	 * file access too.
+	 */
+
+	spin_lock_irqsave(ch->lock, flags);
+	__ata_end_request(drive, rq, !dma_stat, rq->nr_sectors);
+	spin_unlock_irqrestore(ch->lock, flags);
 
 	/*
 	 * we completed this command, check if we can service a new command
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-11 02:11:07.000000000 +0200
+++ linux/drivers/scsi/ide-scsi.c	2002-06-10 23:54:50.000000000 +0200
@@ -244,7 +244,7 @@
 	unsigned long flags;
 
 	if (!(rq->flags & REQ_PC)) {
-		ide_end_request(drive, rq, uptodate);
+		ata_end_request(drive, rq, uptodate);
 		return 0;
 	}
 
@@ -399,29 +399,33 @@
 	struct Scsi_Host *host = drive->driver_data;
 	idescsi_scsi_t *scsi = idescsi_private(host);
 	struct atapi_packet_command *pc = scsi->pc;
-	byte ireason;
+	u8 ireason;
 	ide_startstop_t startstop;
+	int ret;
 
-	if (ide_wait_stat(&startstop, drive, rq, DRQ_STAT, BUSY_STAT, WAIT_READY)) {
+	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;
 	}
-	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");
-		return ide_stopped;
-	}
 
 	/* FIXME: this locking should encompass the above register
 	 * file access too.
 	 */
-
 	spin_lock_irqsave(ch->lock, flags);
-	ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);	/* Set the interrupt routine */
+	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);
 
-	atapi_write(drive, scsi->pc->c, 12);			/* Send the actual packet */
-	return ide_started;
+	return ret;
 }
 
 /*
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-11 02:11:07.000000000 +0200
+++ linux/include/linux/ide.h	2002-06-11 00:17:30.000000000 +0200
@@ -601,8 +601,9 @@
 #define LOCAL_END_REQUEST	/* Don't generate end_request in blk.h */
 #include <linux/blk.h>
 
-extern int __ide_end_request(struct ata_device *, struct request *, int, unsigned int);
-extern int ide_end_request(struct ata_device *drive, struct request *, int);
+/* Not locking and locking variant: */
+extern int __ata_end_request(struct ata_device *, struct request *, int, unsigned int);
+extern int ata_end_request(struct ata_device *drive, struct request *, int);
 
 extern void ata_set_handler(struct ata_device *drive, ata_handler_t handler,
 		unsigned long timeout, ata_expiry_t expiry);
@@ -611,11 +612,6 @@
 extern ide_startstop_t ata_error(struct ata_device *, struct request *rq, const char *);
 
 extern void ide_fixstring(char *s, const int bytecount, const int byteswap);
-
-extern int ide_wait_stat(ide_startstop_t *,
-		struct ata_device *, struct request *rq,
-		byte, byte, unsigned long);
-
 extern int ide_wait_noerr(struct ata_device *, byte, byte, unsigned long);
 
 /*
@@ -831,7 +827,11 @@
 
 extern void ata_select(struct ata_device *, unsigned long);
 extern void ata_mask(struct ata_device *);
+extern int ata_busy_poll(struct ata_device *, unsigned long);
 extern int ata_status(struct ata_device *, u8, u8);
+extern int ata_status_poll( struct ata_device *, u8, u8,
+		unsigned long, struct request *rq, ide_startstop_t *);
+
 extern int ata_irq_enable(struct ata_device *, int);
 extern void ata_reset(struct ata_channel *);
 extern void ata_out_regfile(struct ata_device *, struct hd_drive_task_hdr *);

  parent reply	other threads:[~2002-06-11  7:47 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 ` Martin Dalecki [this message]
2002-06-11 19:02   ` [PATCH] 2.5.21 IDE 87 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 ` [PATCH] 2.5.21 IDE 90 Martin Dalecki
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=3D05AACD.2080504@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.