[LWN Logo]
[LWN.net]
From:	 Martin Dalecki <dalecki@evision-ventures.com>
To:	 Linus Torvalds <torvalds@transmeta.com>
Subject: [PATCH] 2.5.13 IDE 52
Date:	 Sun, 05 May 2002 17:54:37 +0200
Cc:	 linux-kernel@vger.kernel.org

Fri May  3 17:50:22 CEST 2002 ide-clean-52

Adapted from patch Bar,B3(Bomiej ,B/(Bo,B3(Bnierkiewicz:

- make straight8 a flag in ata_channel instead of byte

- don't store tables as code in drive_is_flashcard()
   and ide_xfer_verbose()

- fix init_gendisk() (due to 2.5.13 blksize_size[] change)

- compress region requesting/releasing
   in channel_probe() and ide_unregister()

- clean a bit ide_setup_ports()

Start of DMA handling tratment.

- Fix the parameters to ide_build_dmatable() to be channel and request.
   Rename it to udma_new_table(). udma will mark arch specific functions
   later.

- Let ide_start_dma() take the request directly as an arguemnt. Rename it to
   ata_start_dma(). After realizing that the usage of the func argument of it
   was bogous and that nobody is using rwproc we where able to remove both of
   them.

- Fix ide_destroy_dmatable() to take the channel as argument and rename it to
   udma_destroy_table(). This function should have possible architecture
   specific implementation as well at some point in time.

- Split up the TCQ UDMA handling stuff in to proper functions. Jens must has
   been dreaming as he introduced them ;-).

diff -urN linux-2.5.13/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- linux-2.5.13/arch/cris/drivers/ide.c	2002-05-03 02:22:45.000000000 +0200
+++ linux/arch/cris/drivers/ide.c	2002-05-04 04:01:08.000000000 +0200
@@ -191,7 +191,7 @@
 #define ATA_PIO0_STROBE 19
 #define ATA_PIO0_HOLD    4
 
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
+static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq);
 static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
 			  void *buffer, unsigned int length);
 
@@ -278,7 +278,7 @@
 
 		hwif->chipset = ide_etrax100;
 		hwif->tuneproc = &tune_e100_ide;
-		hwif->dmaproc = &e100_dmaproc;
+		hwif->udma = &e100_dmaproc;
 		hwif->ata_read = e100_ide_input_data;
 		hwif->ata_write = e100_ide_output_data;
 		hwif->atapi_read = e100_atapi_read;
@@ -564,13 +564,14 @@
 static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS];
 static unsigned int ata_tot_size;
 
+
 /*
- * e100_ide_build_dmatable() prepares a dma request.
- * Returns 0 if all went okay, returns 1 otherwise.
+ * This prepares a dma request.  Returns 0 if all went okay, returns 1
+ * otherwise.
  */
-static int e100_ide_build_dmatable (ide_drive_t *drive)
+
+static int e100_udma_new_table(struct ata_channel *ch, struct request *rq)
 {
-	struct request *rq = HWGROUP(drive)->rq;
 	struct buffer_head *bh = rq->bh;
 	unsigned long size, addr;
 	unsigned int count = 0;
@@ -602,7 +603,7 @@
 		/* did we run out of descriptors? */
 
 		if(count >= MAX_DMA_DESCRS) {
-			printk("%s: too few DMA descriptors\n", drive->name);
+			printk("%s: too few DMA descriptors\n", ch->name);
 			return 1;
 		}
 
@@ -623,7 +624,7 @@
                    size > 131072 only one split is necessary */
 
 		if(size > 65536) {
- 		        /* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
+		        /* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
                         ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
                         ata_descrs[count].ctrl = 0;
                         ata_descrs[count].buf = addr;
@@ -656,7 +657,7 @@
 		return 0;
 	}
 
-	printk("%s: empty DMA table?\n", drive->name);
+	printk("%s: empty DMA table?\n", ch->name);
 	return 1;	/* let the PIO routines handle this weirdness */
 }
 
@@ -695,7 +696,7 @@
 	LED_DISK_READ(0);
 	LED_DISK_WRITE(0);
 
-	dma_stat = drive->channel->dmaproc(ide_dma_end, drive);
+	dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
 	stat = GET_STAT();			/* get drive status */
 	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
 		if (!dma_stat) {
@@ -726,7 +727,7 @@
  * the caller should revert to PIO for the current request.
  */
 
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
         static unsigned int reading; /* static to support ide_dma_begin semantics */
 	int atapi = 0;
@@ -786,24 +787,21 @@
 
 		/* set up the Etrax DMA descriptors */
 
-		if(e100_ide_build_dmatable (drive))
+		if(e100_udma_new_table(drive->channel, rq))
 			return 1;
 
 		if(!atapi) {
 			/* set the irq handler which will finish the request when DMA is done */
-		
 			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
-			
+
 			/* issue cmd to drive */
-			
 			OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
 		}
 
 		/* begin DMA */
-	      
 		*R_DMA_CH3_FIRST = virt_to_phys(ata_descrs);
 		*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
-		
+
 		/* initiate a multi word dma read using DMA handshaking */
 		
 		*R_ATA_TRANSFER_CNT =
@@ -820,7 +818,7 @@
 		LED_DISK_READ(1);
 
 		D(printk("dma read of %d bytes.\n", ata_tot_size));
- 
+
 	} else {
 		/* writing */
 
@@ -829,29 +827,25 @@
 
 		/* set up the Etrax DMA descriptors */
 
-		if(e100_ide_build_dmatable (drive))
+		if(e100_udma_new_table(drive->channel, rq))
 			return 1;
 
 		if(!atapi) {
 			/* set the irq handler which will finish the request when DMA is done */
-				
 			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
-			
+
 			/* issue cmd to drive */
-			
 			OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
 		}
 
 		/* begin DMA */
-		
 		*R_DMA_CH2_FIRST = virt_to_phys(ata_descrs);
 		*R_DMA_CH2_CMD   = IO_STATE(R_DMA_CH2_CMD, cmd, start);
-		
+
 		/* initiate a multi word dma write using DMA handshaking */
-		
 		*R_ATA_TRANSFER_CNT =
 			IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
-		
+
 		*R_ATA_CTRL_DATA =
 			IO_FIELD(R_ATA_CTRL_DATA, data,     IDE_DATA_REG) |
 			IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
@@ -878,7 +872,7 @@
  * --- Marcin Dalecki
  */
 
-void ide_release_dma(struct ata_channel *hwif)
+void ide_release_dma(struct ata_channel *ch)
 {
 	/* empty */
 }
diff -urN linux-2.5.13/drivers/ide/ata-timing.h linux/drivers/ide/ata-timing.h
--- linux-2.5.13/drivers/ide/ata-timing.h	2002-05-03 02:22:55.000000000 +0200
+++ linux/drivers/ide/ata-timing.h	2002-05-04 05:43:45.000000000 +0200
@@ -74,12 +74,12 @@
  * It's a bit elaborate due to the legacy we have to bear.
  */
 
-extern short ata_timing_mode(ide_drive_t *drive, int map);
+extern short ata_timing_mode(struct ata_device *drive, int map);
 extern void ata_timing_quantize(struct ata_timing *t, struct ata_timing *q,
 		int T, int UT);
 extern void ata_timing_merge(struct ata_timing *a, struct ata_timing *b,
 		struct ata_timing *m, unsigned int what);
 extern struct ata_timing* ata_timing_data(short speed);
-extern int ata_timing_compute(ide_drive_t *drive,
+extern int ata_timing_compute(struct ata_device *drive,
 		short speed, struct ata_timing *t, int T, int UT);
 #endif
diff -urN linux-2.5.13/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c
--- linux-2.5.13/drivers/ide/cmd64x.c	2002-05-03 02:22:49.000000000 +0200
+++ linux/drivers/ide/cmd64x.c	2002-05-04 03:59:44.000000000 +0200
@@ -208,10 +208,10 @@
  * This routine writes the prepared setup/active/recovery counts
  * for a drive into the cmd646 chipset registers to active them.
  */
-static void program_drive_counts (ide_drive_t *drive, int setup_count, int active_count, int recovery_count)
+static void program_drive_counts(struct ata_device *drive, int setup_count, int active_count, int recovery_count)
 {
 	unsigned long flags;
-	ide_drive_t *drives = drive->channel->drives;
+	struct ata_device *drives = drive->channel->drives;
 	byte temp_b;
 	static const byte setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
 	static const byte recovery_counts[] =
@@ -277,7 +277,7 @@
  * 8: prefetch off, 9: prefetch on, 255: auto-select best mode.
  * Called with 255 at boot time.
  */
-static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted)
+static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted)
 {
 	int recovery_time, clock_time;
 	byte recovery_count2, cycle_count;
@@ -351,7 +351,7 @@
 	}
 }
 
-static void cmd680_tuneproc (ide_drive_t *drive, byte mode_wanted)
+static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted)
 {
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
@@ -381,7 +381,7 @@
 	pci_write_config_word(dev, drive_pci, speedt);
 }
 
-static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+static void config_cmd64x_chipset_for_pio(struct ata_device *drive, byte set_speed)
 {
 	byte speed	= 0x00;
 	byte set_pio	= ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
@@ -392,7 +392,7 @@
 		(void) ide_config_drive_speed(drive, speed);
 }
 
-static void config_cmd680_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+static void config_cmd680_chipset_for_pio(struct ata_device *drive, byte set_speed)
 {
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
@@ -418,7 +418,7 @@
 	}
 }
 
-static void config_chipset_for_pio (ide_drive_t *drive, byte set_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);
@@ -427,7 +427,7 @@
 	}
 }
 
-static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
+static int cmd64x_tune_chipset(struct ata_device *drive, byte speed)
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	struct ata_channel *hwif = drive->channel;
@@ -496,7 +496,7 @@
 	return err;
 }
 
-static int cmd680_tune_chipset (ide_drive_t *drive, byte speed)
+static int cmd680_tune_chipset(struct ata_device *drive, byte speed)
 {
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
@@ -612,7 +612,7 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_cmd64x_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
+static int config_cmd64x_chipset_for_dma(struct ata_device *drive, unsigned int rev, byte ultra_66)
 {
 	struct hd_driveid *id	= drive->id;
 	struct ata_channel *hwif = drive->channel;
@@ -697,7 +697,7 @@
 	return rval;
 }
 
-static int config_cmd680_chipset_for_dma (ide_drive_t *drive)
+static int config_cmd680_chipset_for_dma(struct ata_device *drive)
 {
 	struct hd_driveid *id	= drive->id;
 	byte udma_66		= eighty_ninty_three(drive);
@@ -739,14 +739,14 @@
 	return rval;
 }
 
-static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
+static int config_chipset_for_dma(struct ata_device *drive, unsigned int rev, byte ultra_66)
 {
 	if (drive->channel->pci_dev->device == PCI_DEVICE_ID_CMD_680)
 		return (config_cmd680_chipset_for_dma(drive));
 	return (config_cmd64x_chipset_for_dma(drive, rev, ultra_66));
 }
 
-static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
+static int cmd64x_config_drive_for_dma(struct ata_device *drive)
 {
 	struct hd_driveid *id	= drive->id;
 	struct ata_channel *hwif = drive->channel;
@@ -839,11 +839,12 @@
 
 static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	byte dma_stat		= 0;
-	byte dma_alt_stat	= 0;
-	byte mask		= (drive->channel->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
-	unsigned long dma_base	= drive->channel->dma_base;
-	struct pci_dev *dev	= drive->channel->pci_dev;
+	struct ata_channel *ch = drive->channel;
+	u8 dma_stat = 0;
+	u8 dma_alt_stat	= 0;
+	u8 mask	= (ch->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
+	unsigned long dma_base	= ch->dma_base;
+	struct pci_dev *dev	= ch->pci_dev;
 	byte jack_slap		= ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
 
 	switch (func) {
@@ -855,9 +856,9 @@
 			dma_stat = inb(dma_base+2);		/* get DMA status */
 			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
 			if (jack_slap) {
-				byte dma_intr	= 0;
-				byte dma_mask	= (drive->channel->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
-				byte dma_reg	= (drive->channel->unit) ? ARTTIM2 : CFR;
+				byte dma_intr = 0;
+				byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
+				byte dma_reg = (ch->unit) ? ARTTIM2 : CFR;
 				(void) pci_read_config_byte(dev, dma_reg, &dma_intr);
 				/*
 				 * DAMN BMIDE is not connected to PCI space!
@@ -866,7 +867,7 @@
 				 */
 				(void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask);	/* clear the INTR bit */
 			}
-			ide_destroy_dmatable(drive);		/* purge DMA mappings */
+			udma_destroy_table(ch);	/* purge DMA mappings */
 			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
 			dma_stat = inb(dma_base+2);
@@ -891,8 +892,8 @@
  */
 static int cmd646_1_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
-	unsigned long dma_base = hwif->dma_base;
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
 	byte dma_stat;
 
 	switch (func) {
@@ -903,7 +904,7 @@
 			dma_stat = inb(dma_base+2);		/* get DMA status */
 			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
 			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
-			ide_destroy_dmatable(drive);		/* and free any DMA resources */
+			udma_destroy_table(ch);			/* and free any DMA resources */
 			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		default:
 			break;
@@ -914,48 +915,48 @@
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
-static int cmd680_busproc (ide_drive_t * drive, int state)
+static int cmd680_busproc(struct ata_device * drive, int state)
 {
 #if 0
-	struct ata_channel *hwif	= drive->channel;
-	u8 addr_mask		= (hwif->unit) ? 0xB0 : 0xA0;
+	struct ata_channel *ch	= drive->channel;
+	u8 addr_mask		= (ch->unit) ? 0xB0 : 0xA0;
 	u32 stat_config		= 0;
 
-        pci_read_config_dword(hwif->pci_dev, addr_mask, &stat_config);
+        pci_read_config_dword(ch->pci_dev, addr_mask, &stat_config);
 
-	if (!hwif)
+	if (!ch)
 		return -EINVAL;
 
 	switch (state) {
 		case BUSSTATE_ON:
-			hwif->drives[0].failures = 0;
-			hwif->drives[1].failures = 0;
+			ch->drives[0].failures = 0;
+			ch->drives[1].failures = 0;
 			break;
 		case BUSSTATE_OFF:
-			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
-			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+			ch->drives[0].failures = ch->drives[0].max_failures + 1;
+			ch->drives[1].failures = ch->drives[1].max_failures + 1;
 			break;
 		case BUSSTATE_TRISTATE:
-			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
-			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+			ch->drives[0].failures = ch->drives[0].max_failures + 1;
+			ch->drives[1].failures = ch->drives[1].max_failures + 1;
 			break;
 		default:
 			return 0;
 	}
-	hwif->bus_state = state;
+	ch->bus_state = state;
 #endif
 	return 0;
 }
 
-static void cmd680_reset (ide_drive_t *drive)
+static void cmd680_reset(struct ata_device *drive)
 {
 #if 0
-	struct ata_channel *hwif = drive->channel;
-	u8 addr_mask		= (hwif->unit) ? 0xB0 : 0xA0;
-	byte reset		= 0;
+	struct ata_channel *ch = drive->channel;
+	u8 addr_mask = (ch->unit) ? 0xB0 : 0xA0;
+	u8 reset = 0;
 
-	pci_read_config_byte(hwif->pci_dev, addr_mask, &reset);
-	pci_write_config_byte(hwif->pci_dev, addr_mask, reset|0x03);
+	pci_read_config_byte(ch->pci_dev, addr_mask, &reset);
+	pci_write_config_byte(ch->pci_dev, addr_mask, reset|0x03);
 #endif
 }
 
diff -urN linux-2.5.13/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- linux-2.5.13/drivers/ide/hpt34x.c	2002-05-04 06:07:13.000000000 +0200
+++ linux/drivers/ide/hpt34x.c	2002-05-04 03:53:29.000000000 +0200
@@ -312,10 +312,10 @@
  * by HighPoint|Triones Technologies, Inc.
  */
 
-int hpt34x_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+int hpt34x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
-	unsigned long dma_base = hwif->dma_base;
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
 	unsigned int count, reading = 0;
 	byte dma_stat;
 
@@ -325,9 +325,9 @@
 		case ide_dma_read:
 			reading = 1 << 3;
 		case ide_dma_write:
-			if (!(count = ide_build_dmatable(drive, func)))
+			if (!(count = udma_new_table(ch, rq)))
 				return 1;	/* try PIO instead of DMA */
-			outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
+			outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
 			reading |= 0x01;
 			outb(reading, dma_base);		/* specify r/w */
 			outb(inb(dma_base+2)|6, dma_base+2);	/* clear INTR & ERROR flags */
@@ -342,7 +342,7 @@
 			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
 			dma_stat = inb(dma_base+2);		/* get DMA status */
 			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
-			ide_destroy_dmatable(drive);		/* purge DMA mappings */
+			udma_destroy_table(ch);			/* purge DMA mappings */
 			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		default:
 			break;
diff -urN linux-2.5.13/drivers/ide/icside.c linux/drivers/ide/icside.c
--- linux-2.5.13/drivers/ide/icside.c	2002-05-03 02:22:41.000000000 +0200
+++ linux/drivers/ide/icside.c	2002-05-04 05:33:38.000000000 +0200
@@ -242,9 +242,9 @@
 }
 
 static int
-icside_build_dmatable(ide_drive_t *drive, int reading)
+icside_udma_new_table(struct ata_channel *ch, struct request *rq)
 {
-	return drive->channel->sg_nents = ide_build_sglist(drive->channel, HWGROUP(drive)->rq);
+	return ch->sg_nents = ide_build_sglist(ch, rq);
 }
 
 /* Teardown mappings after DMA has completed.  */
@@ -332,7 +332,7 @@
 	int i;
 	byte stat, dma_stat;
 
-	dma_stat = drive->channel->dmaproc(ide_dma_end, drive);
+	dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
 	stat = GET_STAT();			/* get drive status */
 	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
 		if (!dma_stat) {
@@ -350,7 +350,7 @@
 
 
 static int
-icside_dma_check(ide_drive_t *drive)
+icside_dma_check(struct ata_device *drive, struct request *rq)
 {
 	struct hd_driveid *id = drive->id;
 	struct ata_channel *hwif = drive->channel;
@@ -381,14 +381,7 @@
 out:
 	func = icside_config_if(drive, xfer_mode);
 
-	return hwif->dmaproc(func, drive);
-}
-
-static int
-icside_dma_verbose(ide_drive_t *drive)
-{
-	printk(", DMA");
-	return 1;
+	return hwif->udma(func, drive, rq);
 }
 
 static int
@@ -413,12 +406,12 @@
 		return 0;
 
 	case ide_dma_check:
-		return icside_dma_check(drive);
+		return icside_dma_check(drive, rq);
 
 	case ide_dma_read:
 		reading = 1;
 	case ide_dma_write:
-		count = icside_build_dmatable(drive, reading);
+		count = icside_udma_new_table(hwif, rq);
 		if (!count)
 			return 1;
 		disable_dma(hwif->hw.dma);
@@ -458,9 +451,6 @@
 	case ide_dma_test_irq:
 		return inb((unsigned long)hwif->hw.priv) & 1;
 
-	case ide_dma_verbose:
-		return icside_dma_verbose(drive);
-
 	case ide_dma_timeout:
 	default:
 		printk("icside_dmaproc: unsupported function: %d\n", func);
diff -urN linux-2.5.13/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.13/drivers/ide/ide.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-05-04 05:31:42.000000000 +0200
@@ -226,7 +226,7 @@
  * of the kernel (such as memory allocation) to be functioning yet.
  *
  * This is too bad, as otherwise we could dynamically allocate the
- * ide_drive_t structs as needed, rather than always consuming memory
+ * ata_device structs as needed, rather than always consuming memory
  * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them.
  */
 #define MAGIC_COOKIE 0x12345678
@@ -263,24 +263,29 @@
  * At that time, we might also consider parameterizing the timeouts and retries,
  * since these are MUCH faster than mechanical drives.	-M.Lord
  */
-int drive_is_flashcard (ide_drive_t *drive)
+int drive_is_flashcard(struct ata_device *drive)
 {
 	struct hd_driveid *id = drive->id;
+	int i;
+
+	char *flashcards[] = {
+		"KODAK ATA_FLASH",
+		"Hitachi CV",
+		"SunDisk SDCFB",
+		"HAGIWARA HPC",
+		"LEXAR ATA_FLASH",
+		"ATA_FLASH"		/* Simple Tech */
+	};
 
 	if (drive->removable && id != NULL) {
 		if (id->config == 0x848a)
 			return 1;	/* CompactFlash */
-		if (!strncmp(id->model, "KODAK ATA_FLASH", 15)	/* Kodak */
-		 || !strncmp(id->model, "Hitachi CV", 10)	/* Hitachi */
-		 || !strncmp(id->model, "SunDisk SDCFB", 13)	/* SunDisk */
-		 || !strncmp(id->model, "HAGIWARA HPC", 12)	/* Hagiwara */
-		 || !strncmp(id->model, "LEXAR ATA_FLASH", 15)	/* Lexar */
-		 || !strncmp(id->model, "ATA_FLASH", 9))	/* Simple Tech */
-		{
-			return 1;	/* yes, it is a flash memory card */
-		}
+		for (i = 0; i < ARRAY_SIZE(flashcards); i++)
+			if (!strncmp(id->model, flashcards[i],
+				     strlen(flashcards[i])))
+				return 1;
 	}
-	return 0;	/* no, it is not a flash memory card */
+	return 0;
 }
 
 int __ide_end_request(struct ata_device *drive, struct request *rq, int uptodate, int nr_secs)
@@ -446,7 +451,7 @@
 	}
 }
 
-static ide_startstop_t do_reset1(ide_drive_t *, int);		/* needed below */
+static ide_startstop_t do_reset1(struct ata_device *, int); /* needed below */
 
 /*
  * Poll the interface for completion every 50ms during an ATAPI drive reset
@@ -546,7 +551,7 @@
  * for it, we set a timer to poll at 50ms intervals.
  */
 
-static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
+static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
 {
 	unsigned int unit;
 	unsigned long flags;
@@ -614,7 +619,7 @@
 	return ide_started;
 }
 
-static inline u32 read_24 (ide_drive_t *drive)
+static inline u32 read_24(struct ata_device *drive)
 {
 	return  (IN_BYTE(IDE_HCYL_REG)<<16) |
 		(IN_BYTE(IDE_LCYL_REG)<<8) |
@@ -678,7 +683,7 @@
 /*
  * Error reporting, in human readable form (luxurious, but a memory hog).
  */
-byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat)
+byte ide_dump_status(struct ata_device *drive, const char *msg, byte stat)
 {
 	unsigned long flags;
 	byte err = 0;
@@ -770,7 +775,7 @@
  * condition by reading a sector's worth of data from the drive.  Of course,
  * this may not help if the drive is *waiting* for data from *us*.
  */
-static void try_to_flush_leftover_data (ide_drive_t *drive)
+static void try_to_flush_leftover_data(struct ata_device *drive)
 {
 	int i;
 
@@ -787,7 +792,7 @@
 /*
  * Take action based on the error returned by the drive.
  */
-ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, byte stat)
+ide_startstop_t ide_error(struct ata_device *drive, const char *msg, byte stat)
 {
 	struct request *rq;
 	byte err;
@@ -844,7 +849,7 @@
 /*
  * Issue a simple drive command.  The drive must be selected beforehand.
  */
-void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ata_handler_t handler)
+void ide_cmd(struct ata_device *drive, byte cmd, byte nsect, ata_handler_t handler)
 {
 	ide_set_handler (drive, handler, WAIT_CMD, NULL);
 	if (IDE_CONTROL_REG)
@@ -889,7 +894,7 @@
  * setting a timer to wake up at half second intervals thereafter, until
  * timeout is achieved, before timing out.
  */
-int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
+int ide_wait_stat(ide_startstop_t *startstop, struct ata_device *drive, byte good, byte bad, unsigned long timeout) {
 	byte stat;
 	int i;
 	unsigned long flags;
@@ -933,7 +938,7 @@
 /*
  * This initiates handling of a new I/O request.
  */
-static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
+static ide_startstop_t start_request(struct ata_device *drive, struct request *rq)
 {
 	sector_t block;
 	unsigned int minor = minor(rq->rq_dev);
@@ -1081,7 +1086,7 @@
 	return ide_stopped;
 }
 
-ide_startstop_t restart_request(ide_drive_t *drive)
+ide_startstop_t restart_request(struct ata_device *drive)
 {
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
 	unsigned long flags;
@@ -1100,7 +1105,7 @@
  * This is used by a drive to give excess bandwidth back to the hwgroup by
  * sleeping for timeout jiffies.
  */
-void ide_stall_queue(ide_drive_t *drive, unsigned long timeout)
+void ide_stall_queue(struct ata_device *drive, unsigned long timeout)
 {
 	if (timeout > WAIT_WORSTCASE)
 		timeout = WAIT_WORSTCASE;
@@ -1681,10 +1686,10 @@
 }
 
 /*
- * get_info_ptr() returns the (ide_drive_t *) for a given device number.
+ * get_info_ptr() returns the (struct ata_device *) for a given device number.
  * It returns NULL if the given device number does not match any present drives.
  */
-ide_drive_t *get_info_ptr(kdev_t i_rdev)
+struct ata_device *get_info_ptr(kdev_t i_rdev)
 {
 	unsigned int major = major(i_rdev);
 	int h;
@@ -2012,25 +2017,13 @@
 	if (ch->straight8) {
 		release_region(ch->io_ports[IDE_DATA_OFFSET], 8);
 	} else {
-		if (ch->io_ports[IDE_DATA_OFFSET])
-			release_region(ch->io_ports[IDE_DATA_OFFSET], 1);
-		if (ch->io_ports[IDE_ERROR_OFFSET])
-			release_region(ch->io_ports[IDE_ERROR_OFFSET], 1);
-		if (ch->io_ports[IDE_NSECTOR_OFFSET])
-			release_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1);
-		if (ch->io_ports[IDE_SECTOR_OFFSET])
-			release_region(ch->io_ports[IDE_SECTOR_OFFSET], 1);
-		if (ch->io_ports[IDE_LCYL_OFFSET])
-			release_region(ch->io_ports[IDE_LCYL_OFFSET], 1);
-		if (ch->io_ports[IDE_HCYL_OFFSET])
-			release_region(ch->io_ports[IDE_HCYL_OFFSET], 1);
-		if (ch->io_ports[IDE_SELECT_OFFSET])
-			release_region(ch->io_ports[IDE_SELECT_OFFSET], 1);
-		if (ch->io_ports[IDE_STATUS_OFFSET])
-			release_region(ch->io_ports[IDE_STATUS_OFFSET], 1);
+		for (i = 0; i < 8; i++)
+			if (ch->io_ports[i])
+				release_region(ch->io_ports[i], 1);
 	}
 	if (ch->io_ports[IDE_CONTROL_OFFSET])
 		release_region(ch->io_ports[IDE_CONTROL_OFFSET], 1);
+/* FIXME: check if we can remove this ifdef */
 #if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
 	if (ch->io_ports[IDE_IRQ_OFFSET])
 		release_region(ch->io_ports[IDE_IRQ_OFFSET], 1);
@@ -2129,7 +2122,6 @@
 	ch->intrproc = old.intrproc;
 	ch->maskproc = old.maskproc;
 	ch->quirkproc = old.quirkproc;
-	ch->rwproc	= old.rwproc;
 	ch->ata_read = old.ata_read;
 	ch->ata_write = old.ata_write;
 	ch->atapi_read = old.atapi_read;
@@ -2172,24 +2164,18 @@
 	int i;
 
 	for (i = 0; i < IDE_NR_PORTS; i++) {
-		if (offsets[i] == -1) {
-			switch(i) {
-				case IDE_CONTROL_OFFSET:
-					hw->io_ports[i] = ctrl;
-					break;
-#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
-				case IDE_IRQ_OFFSET:
-					hw->io_ports[i] = intr;
-					break;
-#endif
-				default:
-					hw->io_ports[i] = 0;
-					break;
-			}
-		} else {
+		if (offsets[i] != -1)
 			hw->io_ports[i] = base + offsets[i];
-		}
+		else
+			hw->io_ports[i] = 0;
 	}
+	if (offsets[IDE_CONTROL_OFFSET] == -1)
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl;
+/* FIMXE: check if we can remove this ifdef */
+#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
+	if (offsets[IDE_IRQ_OFFSET] == -1)
+		hw->io_ports[IDE_IRQ_OFFSET] = intr;
+#endif
 	hw->irq = irq;
 	hw->dma = NO_DMA;
 	hw->ack_intr = ack_intr;
@@ -2261,7 +2247,7 @@
 	return ide_register_hw(&hw, NULL);
 }
 
-void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
+void ide_add_setting(struct ata_device *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
 {
 	ide_settings_t **p = &drive->settings;
 	ide_settings_t *setting = NULL;
@@ -2288,7 +2274,7 @@
 		kfree(setting);
 }
 
-void ide_remove_setting (ide_drive_t *drive, char *name)
+void ide_remove_setting(struct ata_device *drive, char *name)
 {
 	ide_settings_t **p = &drive->settings, *setting;
 
@@ -2301,7 +2287,7 @@
 	kfree(setting);
 }
 
-static void auto_remove_settings (ide_drive_t *drive)
+static void auto_remove_settings(struct ata_device *drive)
 {
 	ide_settings_t *setting;
 repeat:
@@ -2315,10 +2301,10 @@
 	}
 }
 
-int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting)
+int ide_read_setting(struct ata_device *drive, ide_settings_t *setting)
 {
-	int		val = -EINVAL;
-	unsigned long	flags;
+	int val = -EINVAL;
+	unsigned long flags;
 
 	if ((setting->rw & SETTING_READ)) {
 		spin_lock_irqsave(&ide_lock, flags);
@@ -2339,7 +2325,7 @@
 	return val;
 }
 
-int ide_spin_wait_hwgroup (ide_drive_t *drive)
+int ide_spin_wait_hwgroup(struct ata_device *drive)
 {
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
 	unsigned long timeout = jiffies + (3 * HZ);
@@ -2367,7 +2353,7 @@
  * to the driver to change settings, and then wait on a semaphore for completion.
  * The current scheme of polling is kludgey, though safe enough.
  */
-int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
+int ide_write_setting(struct ata_device *drive, ide_settings_t *setting, int val)
 {
 	int i;
 	u32 *p;
@@ -2412,7 +2398,7 @@
 	return 0;
 }
 
-static int set_using_dma(ide_drive_t *drive, int arg)
+static int set_using_dma(struct ata_device *drive, int arg)
 {
 	if (!drive->driver)
 		return -EPERM;
@@ -2423,7 +2409,7 @@
 	return 0;
 }
 
-static int set_pio_mode(ide_drive_t *drive, int arg)
+static int set_pio_mode(struct ata_device *drive, int arg)
 {
 	struct request rq;
 
@@ -2441,7 +2427,7 @@
 	return 0;
 }
 
-void ide_add_generic_settings (ide_drive_t *drive)
+void ide_add_generic_settings(struct ata_device *drive)
 {
 /*			drive	setting name		read/write access				read ioctl		write ioctl		data type	min	max				mul_factor	div_factor	data pointer			set function */
 	ide_add_setting(drive,	"io_32bit",		drive->channel->no_io_32bit ? SETTING_READ : SETTING_RW,	HDIO_GET_32BIT,		HDIO_SET_32BIT,		TYPE_BYTE,	0,	1 + (SUPPORT_VLB_SYNC << 1),	1,		1,		&drive->channel->io_32bit,		set_io_32bit);
@@ -2476,7 +2462,7 @@
 static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	int err = 0, major, minor;
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	struct request rq;
 	kdev_t dev;
 	ide_settings_t *setting;
@@ -2630,7 +2616,7 @@
 
 static int ide_check_media_change (kdev_t i_rdev)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	int res = 0; /* not changed */
 
 	drive = get_info_ptr(i_rdev);
@@ -2828,7 +2814,7 @@
 {
 	int i, vals[3];
 	struct ata_channel *hwif;
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	unsigned int hw, unit;
 	const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
 	const char max_hwif  = '0' + (MAX_HWIFS - 1);
@@ -3144,7 +3130,7 @@
 /*
  * Lookup ATA devices, which requested a particular driver.
  */
-ide_drive_t *ide_scan_devices(byte type, const char *name, struct ata_operations *driver, int n)
+struct ata_device *ide_scan_devices(byte type, const char *name, struct ata_operations *driver, int n)
 {
 	unsigned int unit, index, i;
 
@@ -3171,7 +3157,7 @@
 /*
  * This is in fact registering a drive not a driver.
  */
-int ide_register_subdriver(ide_drive_t *drive, struct ata_operations *driver)
+int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driver)
 {
 	unsigned long flags;
 
@@ -3204,7 +3190,7 @@
 			drive->channel->udma(ide_dma_off_quietly, drive, NULL);
 			drive->channel->udma(ide_dma_check, drive, NULL);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-			drive->channel->udma(ide_dma_queued_on, drive, NULL);
+			udma_tcq_enable(drive, 1);
 #endif
 		}
 
@@ -3238,7 +3224,7 @@
  *
  * FIXME: Check whatever we maybe don't call it twice!.
  */
-int ide_unregister_subdriver(ide_drive_t *drive)
+int ide_unregister_subdriver(struct ata_device *drive)
 {
 	unsigned long flags;
 
diff -urN linux-2.5.13/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.13/drivers/ide/ide-cd.c	2002-05-03 02:22:51.000000000 +0200
+++ linux/drivers/ide/ide-cd.c	2002-05-04 04:27:35.000000000 +0200
@@ -2652,7 +2652,7 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (drive->using_dma)
-		(void) drive->channel->udma(ide_dma_verbose, drive, NULL);
+		udma_print(drive);
 #endif
 	printk("\n");
 
diff -urN linux-2.5.13/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.13/drivers/ide/ide-disk.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-05-04 05:54:14.000000000 +0200
@@ -89,7 +89,7 @@
 	return 0;	/* lba_capacity value may be bad */
 }
 
-static u8 get_command(ide_drive_t *drive, int cmd)
+static u8 get_command(struct ata_device *drive, int cmd)
 {
 	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
 
@@ -345,7 +345,7 @@
 	return chs_do_request(drive, rq, block);
 }
 
-static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *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) {
@@ -370,7 +370,7 @@
 	return 0;
 }
 
-static int idedisk_flushcache(ide_drive_t *drive)
+static int idedisk_flushcache(struct ata_device *drive)
 {
 	struct ata_taskfile args;
 
@@ -386,7 +386,7 @@
 	return ide_raw_taskfile(drive, &args, NULL);
 }
 
-static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
+static void idedisk_release (struct inode *inode, struct file *filp, struct ata_device *drive)
 {
 	if (drive->removable && !drive->usage) {
 		struct ata_taskfile args;
@@ -408,7 +408,7 @@
 	MOD_DEC_USE_COUNT;
 }
 
-static int idedisk_check_media_change (ide_drive_t *drive)
+static int idedisk_check_media_change(struct ata_device *drive)
 {
 	/* if removable, always assume it was changed */
 	return drive->removable;
@@ -474,7 +474,7 @@
 	return IS_PDC4030_DRIVE ? ide_stopped : ide_started;
 }
 
-static void idedisk_pre_reset (ide_drive_t *drive)
+static void idedisk_pre_reset(struct ata_device *drive)
 {
 	int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1;
 
@@ -490,7 +490,7 @@
 
 #ifdef CONFIG_PROC_FS
 
-static int smart_enable(ide_drive_t *drive)
+static int smart_enable(struct ata_device *drive)
 {
 	struct ata_taskfile args;
 
@@ -504,7 +504,7 @@
 	return ide_raw_taskfile(drive, &args, NULL);
 }
 
-static int get_smart_values(ide_drive_t *drive, u8 *buf)
+static int get_smart_values(struct ata_device *drive, u8 *buf)
 {
 	struct ata_taskfile args;
 
@@ -521,7 +521,7 @@
 	return ide_raw_taskfile(drive, &args, buf);
 }
 
-static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
+static int get_smart_thresholds(struct ata_device *drive, u8 *buf)
 {
 	struct ata_taskfile args;
 
@@ -541,7 +541,7 @@
 static int proc_idedisk_read_cache
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
+	struct ata_device *drive = (struct ata_device *) data;
 	char		*out = page;
 	int		len;
 
@@ -555,7 +555,7 @@
 static int proc_idedisk_read_smart_thresholds
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	ide_drive_t	*drive = (ide_drive_t *)data;
+	struct ata_device *drive = (struct ata_device *)data;
 	int		len = 0, i = 0;
 
 	if (!get_smart_thresholds(drive, page)) {
@@ -574,8 +574,8 @@
 static int proc_idedisk_read_smart_values
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	ide_drive_t	*drive = (ide_drive_t *)data;
-	int		len = 0, i = 0;
+	struct ata_device *drive = (struct ata_device *)data;
+	int len = 0, i = 0;
 
 	if (!get_smart_values(drive, page)) {
 		unsigned short *val = (unsigned short *) page;
@@ -594,7 +594,7 @@
 static int proc_idedisk_read_tcq
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
+	struct ata_device *drive = (struct ata_device *) data;
 	char		*out = page;
 	int		len, cmds, i;
 	unsigned long	flags;
@@ -658,7 +658,7 @@
  * This is tightly woven into the driver->special can not touch.
  * DON'T do it again until a total personality rewrite is committed.
  */
-static int set_multcount(ide_drive_t *drive, int arg)
+static int set_multcount(struct ata_device *drive, int arg)
 {
 	struct request rq;
 
@@ -670,12 +670,12 @@
 	drive->mult_req = arg;
 	drive->special_cmd |= ATA_SPECIAL_MMODE;
 
-	ide_do_drive_cmd (drive, &rq, ide_wait);
+	ide_do_drive_cmd(drive, &rq, ide_wait);
 
 	return (drive->mult_count == arg) ? 0 : -EIO;
 }
 
-static int set_nowerr(ide_drive_t *drive, int arg)
+static int set_nowerr(struct ata_device *drive, int arg)
 {
 	if (ide_spin_wait_hwgroup(drive))
 		return -EBUSY;
@@ -686,7 +686,7 @@
 	return 0;
 }
 
-static int write_cache(ide_drive_t *drive, int arg)
+static int write_cache(struct ata_device *drive, int arg)
 {
 	struct ata_taskfile args;
 
@@ -704,7 +704,7 @@
 	return 0;
 }
 
-static int idedisk_standby(ide_drive_t *drive)
+static int idedisk_standby(struct ata_device *drive)
 {
 	struct ata_taskfile args;
 
@@ -715,7 +715,7 @@
 	return ide_raw_taskfile(drive, &args, NULL);
 }
 
-static int set_acoustic(ide_drive_t *drive, int arg)
+static int set_acoustic(struct ata_device *drive, int arg)
 {
 	struct ata_taskfile args;
 
@@ -732,7 +732,7 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDE_TCQ
-static int set_using_tcq(ide_drive_t *drive, int arg)
+static int set_using_tcq(struct ata_device *drive, int arg)
 {
 	if (!drive->driver)
 		return -EPERM;
@@ -750,14 +750,14 @@
 			drive->queue_depth = drive->id->queue_depth + 1;
 	}
 
-	if (drive->channel->udma(arg ? ide_dma_queued_on : ide_dma_queued_off, drive, NULL))
+	if (udma_tcq_enable(drive, arg))
 		return -EIO;
 
 	return 0;
 }
 #endif
 
-static int probe_lba_addressing (ide_drive_t *drive, int arg)
+static int probe_lba_addressing(struct ata_device *drive, int arg)
 {
 	drive->addressing =  0;
 
@@ -768,12 +768,12 @@
 	return 0;
 }
 
-static int set_lba_addressing (ide_drive_t *drive, int arg)
+static int set_lba_addressing(struct ata_device *drive, int arg)
 {
 	return (probe_lba_addressing(drive, arg));
 }
 
-static void idedisk_add_settings(ide_drive_t *drive)
+static void idedisk_add_settings(struct ata_device *drive)
 {
 	struct hd_driveid *id = drive->id;
 
@@ -795,7 +795,7 @@
 
 static int idedisk_suspend(struct device *dev, u32 state, u32 level)
 {
-	ide_drive_t *drive = dev->driver_data;
+	struct ata_device *drive = dev->driver_data;
 
 	/* I hope that every freeze operations from the upper levels have
 	 * already been done...
@@ -822,7 +822,7 @@
 
 static int idedisk_resume(struct device *dev, u32 level)
 {
-	ide_drive_t *drive = dev->driver_data;
+	struct ata_device *drive = dev->driver_data;
 
 	if (level != RESUME_RESTORE_STATE)
 		return 0;
@@ -916,7 +916,7 @@
  * Sets maximum virtual LBA address of the drive.
  * Returns new maximum virtual LBA address (> 0) or 0 on failure.
  */
-static sector_t set_max_address(ide_drive_t *drive, sector_t addr_req)
+static sector_t set_max_address(struct ata_device *drive, sector_t addr_req)
 {
 	struct ata_taskfile args;
 	sector_t addr_set = 0;
@@ -945,7 +945,7 @@
 	return addr_set;
 }
 
-static u64 set_max_address_ext(ide_drive_t *drive, u64 addr_req)
+static u64 set_max_address_ext(struct ata_device *drive, u64 addr_req)
 {
 	struct ata_taskfile args;
 	u64 addr_set = 0;
@@ -1177,7 +1177,7 @@
 	       drive->bios_cyl, drive->bios_head, drive->bios_sect);
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (drive->using_dma)
-		(void) drive->channel->udma(ide_dma_verbose, drive, NULL);
+		udma_print(drive);
 #endif
 	printk("\n");
 
@@ -1213,7 +1213,7 @@
 	probe_lba_addressing(drive, 1);
 }
 
-static int idedisk_cleanup(ide_drive_t *drive)
+static int idedisk_cleanup(struct ata_device *drive)
 {
 	if (!drive)
 	    return 0;
@@ -1250,7 +1250,7 @@
 
 static void __exit idedisk_exit (void)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	int failed = 0;
 
 	while ((drive = ide_scan_devices(ATA_DISK, "ide-disk", &idedisk_driver, failed)) != NULL) {
@@ -1267,9 +1267,9 @@
 	}
 }
 
-int idedisk_init (void)
+int idedisk_init(void)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	int failed = 0;
 
 	MOD_INC_USE_COUNT;
diff -urN linux-2.5.13/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.13/drivers/ide/ide-dma.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide-dma.c	2002-05-04 06:00:00.000000000 +0200
@@ -1,4 +1,5 @@
-/*
+/**** vi:set ts=8 sts=8 sw=8:************************************************
+ *
  *  Copyright (c) 1999-2000  Andre Hedrick <andre@linux-ide.org>
  *  Copyright (c) 1995-1998  Mark Lord
  *
@@ -63,12 +64,12 @@
  *
  * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports.
  *
- * check_drive_lists(ide_drive_t *drive, int good_bad)
- *
  * ATA-66/100 and recovery functions, I forgot the rest......
  */
 
 #include <linux/config.h>
+#define __NO_VERSION__
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
@@ -192,11 +193,11 @@
 #endif
 
 /*
- * dma_intr() is the handler for disk read/write DMA interrupts
+ * This is the handler for disk read/write DMA interrupts.
  */
 ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
 {
-	byte stat, dma_stat;
+	u8 stat, dma_stat;
 
 	dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
 	if (OK_STAT(stat = GET_STAT(),DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
@@ -204,7 +205,7 @@
 			__ide_end_request(drive, rq, 1, rq->nr_sectors);
 			return ide_stopped;
 		}
-		printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
+		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
 		       drive->name, dma_stat);
 	}
 	return ide_error(drive, "dma_intr", stat);
@@ -270,106 +271,11 @@
 }
 
 /*
- * This prepares a dma request.  Returns 0 if all went okay, returns 1
- * otherwise.  May also be invoked from trm290.c
- */
-int ide_build_dmatable(struct ata_device *drive, ide_dma_action_t func)
-{
-	struct ata_channel *ch = drive->channel;
-	unsigned int *table = ch->dmatable_cpu;
-#ifdef CONFIG_BLK_DEV_TRM290
-	unsigned int is_trm290_chipset = (ch->chipset == ide_trm290);
-#else
-	const int is_trm290_chipset = 0;
-#endif
-	unsigned int count = 0;
-	int i;
-	struct scatterlist *sg;
-
-	ch->sg_nents = i = build_sglist(ch, HWGROUP(drive)->rq);
-	if (!i)
-		return 0;
-
-	sg = ch->sg_table;
-	while (i) {
-		u32 cur_addr;
-		u32 cur_len;
-
-		cur_addr = sg_dma_address(sg);
-		cur_len = sg_dma_len(sg);
-
-		/*
-		 * Fill in the dma table, without crossing any 64kB boundaries.
-		 * Most hardware requires 16-bit alignment of all blocks,
-		 * but the trm290 requires 32-bit alignment.
-		 */
-
-		while (cur_len) {
-			u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
-
-			if (count++ >= PRD_ENTRIES) {
-				printk("ide-dma: count %d, sg_nents %d, cur_len %d, cur_addr %u\n",
-						count, ch->sg_nents, cur_len, cur_addr);
-				BUG();
-			}
-
-			if (bcount > cur_len)
-				bcount = cur_len;
-			*table++ = cpu_to_le32(cur_addr);
-			xcount = bcount & 0xffff;
-			if (is_trm290_chipset)
-				xcount = ((xcount >> 2) - 1) << 16;
-			if (xcount == 0x0000) {
-		        /*
-			 * Most chipsets correctly interpret a length of
-			 * 0x0000 as 64KB, but at least one (e.g. CS5530)
-			 * misinterprets it as zero (!). So here we break
-			 * the 64KB entry into two 32KB entries instead.
-			 */
-				if (count++ >= PRD_ENTRIES) {
-					pci_unmap_sg(ch->pci_dev, sg,
-						     ch->sg_nents,
-						     ch->sg_dma_direction);
-					return 0;
-				}
-
-				*table++ = cpu_to_le32(0x8000);
-				*table++ = cpu_to_le32(cur_addr + 0x8000);
-				xcount = 0x8000;
-			}
-			*table++ = cpu_to_le32(xcount);
-			cur_addr += bcount;
-			cur_len -= bcount;
-		}
-
-		sg++;
-		i--;
-	}
-
-	if (!count)
-		printk("%s: empty DMA table?\n", drive->name);
-	else if (!is_trm290_chipset)
-		*--table |= cpu_to_le32(0x80000000);
-
-	return count;
-}
-
-/* Teardown mappings after DMA has completed.  */
-void ide_destroy_dmatable (ide_drive_t *drive)
-{
-	struct pci_dev *dev = drive->channel->pci_dev;
-	struct scatterlist *sg = drive->channel->sg_table;
-	int nents = drive->channel->sg_nents;
-
-	pci_unmap_sg(dev, sg, nents, drive->channel->sg_dma_direction);
-}
-
-/*
  *  For both Blacklisted and Whitelisted drives.
  *  This is setup to be called as an extern for future support
  *  to other special driver code.
  */
-int check_drive_lists (ide_drive_t *drive, int good_bad)
+int check_drive_lists(struct ata_device *drive, int good_bad)
 {
 	struct hd_driveid *id = drive->id;
 
@@ -407,80 +313,43 @@
 	return 0;
 }
 
-int report_drive_dmaing (ide_drive_t *drive)
-{
-	struct hd_driveid *id = drive->id;
-
-	if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
-	    (id->dma_ultra & (id->dma_ultra >> 14) & 3)) {
-		if ((id->dma_ultra >> 15) & 1) {
-			printk(", UDMA(mode 7)");	/* UDMA BIOS-enabled! */
-		} else {
-			printk(", UDMA(133)");	/* UDMA BIOS-enabled! */
-		}
-	} else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
-	  	  (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
-		if ((id->dma_ultra >> 13) & 1) {
-			printk(", UDMA(100)");	/* UDMA BIOS-enabled! */
-		} else if ((id->dma_ultra >> 12) & 1) {
-			printk(", UDMA(66)");	/* UDMA BIOS-enabled! */
-		} else {
-			printk(", UDMA(44)");	/* UDMA BIOS-enabled! */
-		}
-	} else if ((id->field_valid & 4) &&
-		   (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
-		if ((id->dma_ultra >> 10) & 1) {
-			printk(", UDMA(33)");	/* UDMA BIOS-enabled! */
-		} else if ((id->dma_ultra >> 9) & 1) {
-			printk(", UDMA(25)");	/* UDMA BIOS-enabled! */
-		} else {
-			printk(", UDMA(16)");	/* UDMA BIOS-enabled! */
-		}
-	} else if (id->field_valid & 4) {
-		printk(", (U)DMA");	/* Can be BIOS-enabled! */
-	} else {
-		printk(", DMA");
-	}
-	return 1;
-}
-
-static int config_drive_for_dma (ide_drive_t *drive)
+static int config_drive_for_dma(struct ata_device *drive)
 {
 	int config_allows_dma = 1;
 	struct hd_driveid *id = drive->id;
-	struct ata_channel *hwif = drive->channel;
+	struct ata_channel *ch = drive->channel;
 
 #ifdef CONFIG_IDEDMA_ONLYDISK
 	if (drive->type != ATA_DISK)
 		config_allows_dma = 0;
 #endif
 
-	if (id && (id->capability & 1) && hwif->autodma && config_allows_dma) {
+	if (id && (id->capability & 1) && ch->autodma && config_allows_dma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL))
-			return hwif->udma(ide_dma_off, drive, NULL);
+			return ch->udma(ide_dma_off, drive, NULL);
 
 		/* Enable DMA on any drive that has UltraDMA (mode 6/7/?) enabled */
 		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
 			if ((id->dma_ultra & (id->dma_ultra >> 14) & 2))
-				return hwif->udma(ide_dma_on, drive, NULL);
+				return ch->udma(ide_dma_on, drive, NULL);
 		/* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */
 		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
 			if ((id->dma_ultra & (id->dma_ultra >> 11) & 7))
-				return hwif->udma(ide_dma_on, drive, NULL);
+				return ch->udma(ide_dma_on, drive, NULL);
 		/* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */
 		if (id->field_valid & 4)	/* UltraDMA */
 			if ((id->dma_ultra & (id->dma_ultra >> 8) & 7))
-				return hwif->udma(ide_dma_on, drive, NULL);
+				return ch->udma(ide_dma_on, drive, NULL);
 		/* Enable DMA on any drive that has mode2 DMA (multi or single) enabled */
 		if (id->field_valid & 2)	/* regular DMA */
 			if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404)
-				return hwif->udma(ide_dma_on, drive, NULL);
+				return ch->udma(ide_dma_on, drive, NULL);
 		/* Consult the list of known "good" drives */
 		if (ide_dmaproc(ide_dma_good_drive, drive, NULL))
-			return hwif->udma(ide_dma_on, drive, NULL);
+			return ch->udma(ide_dma_on, drive, NULL);
 	}
-	return hwif->udma(ide_dma_off_quietly, drive, NULL);
+	return ch->udma(ide_dma_off_quietly, drive, NULL);
 }
 
 /*
@@ -508,7 +377,7 @@
 	return 0;
 }
 
-static void ide_toggle_bounce(ide_drive_t *drive, int on)
+static void ide_toggle_bounce(struct ata_device *drive, int on)
 {
 	u64 addr = BLK_BOUNCE_HIGH;
 
@@ -522,26 +391,20 @@
 	blk_queue_bounce_limit(&drive->queue, addr);
 }
 
-int ide_start_dma(ide_dma_action_t func, struct ata_device *drive)
+int ata_start_dma(struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
-	unsigned long dma_base = hwif->dma_base;
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
 	unsigned int reading = 0;
 
-	if (rq_data_dir(HWGROUP(drive)->rq) == READ)
+	if (rq_data_dir(rq) == READ)
 		reading = 1 << 3;
 
-	/* active tuning based on IO direction */
-	if (hwif->rwproc)
-		hwif->rwproc(drive, func);
-
-	/*
-	 * try PIO instead of DMA
-	 */
-	if (!ide_build_dmatable(drive, func))
+	/* try PIO instead of DMA */
+	if (!udma_new_table(ch, rq))
 		return 1;
 
-	outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
+	outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
 	outb(reading, dma_base);		/* specify r/w */
 	outb(inb(dma_base+2)|6, dma_base+2);	/* clear INTR & ERROR flags */
 	drive->waiting_for_dma = 1;
@@ -566,11 +429,11 @@
  */
 int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
-	unsigned long dma_base = hwif->dma_base;
-	byte unit = (drive->select.b.unit & 0x01);
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+	u8 unit = (drive->select.b.unit & 0x01);
 	unsigned int reading = 0, set_high = 1;
-	byte dma_stat;
+	u8 dma_stat;
 
 	switch (func) {
 		case ide_dma_off:
@@ -579,7 +442,7 @@
 			set_high = 0;
 			outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ
-			hwif->udma(ide_dma_queued_off, drive, rq);
+			udma_tcq_enable(drive, 0);
 #endif
 		case ide_dma_on:
 			ide_toggle_bounce(drive, set_high);
@@ -587,7 +450,7 @@
 			if (drive->using_dma) {
 				outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-				hwif->udma(ide_dma_queued_on, drive, rq);
+				udma_tcq_enable(drive, 1);
 #endif
 			}
 			return 0;
@@ -596,7 +459,7 @@
 		case ide_dma_read:
 			reading = 1 << 3;
 		case ide_dma_write:
-			if (ide_start_dma(func, drive))
+			if (ata_start_dma(drive, rq))
 				return 1;
 
 			if (drive->type != ATA_DISK)
@@ -613,14 +476,6 @@
 				OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 			}
 			return drive->channel->udma(ide_dma_begin, drive, NULL);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-		case ide_dma_queued_on:
-		case ide_dma_queued_off:
-		case ide_dma_read_queued:
-		case ide_dma_write_queued:
-		case ide_dma_queued_start:
-			return ide_tcq_dmaproc(func, drive, rq);
-#endif
 		case ide_dma_begin:
 			/* Note that this is done *after* the cmd has
 			 * been issued to the drive, as per the BM-IDE spec.
@@ -634,13 +489,13 @@
 			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
 			dma_stat = inb(dma_base+2);		/* get DMA status */
 			outb(dma_stat|6, dma_base+2);	/* clear the INTR & ERROR bits */
-			ide_destroy_dmatable(drive);	/* purge DMA mappings */
+			udma_destroy_table(ch);	/* purge DMA mappings */
 			return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
 		case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
 			dma_stat = inb(dma_base+2);
 #if 0  /* do not set unless you know what you are doing */
 			if (dma_stat & 4) {
-				byte stat = GET_STAT();
+				u8 stat = GET_STAT();
 				outb(dma_base+2, dma_stat & 0xE4);
 			}
 #endif
@@ -648,8 +503,6 @@
 		case ide_dma_bad_drive:
 		case ide_dma_good_drive:
 			return check_drive_lists(drive, (func == ide_dma_good_drive));
-		case ide_dma_verbose:
-			return report_drive_dmaing(drive);
 		case ide_dma_timeout:
 			printk(KERN_ERR "%s: DMA timeout occured!\n", __FUNCTION__);
 			return 1;
@@ -666,61 +519,61 @@
 /*
  * Needed for allowing full modular support of ide-driver
  */
-void ide_release_dma(struct ata_channel *hwif)
+void ide_release_dma(struct ata_channel *ch)
 {
-	if (!hwif->dma_base)
+	if (!ch->dma_base)
 		return;
 
-	if (hwif->dmatable_cpu) {
-		pci_free_consistent(hwif->pci_dev,
+	if (ch->dmatable_cpu) {
+		pci_free_consistent(ch->pci_dev,
 				    PRD_ENTRIES * PRD_BYTES,
-				    hwif->dmatable_cpu,
-				    hwif->dmatable_dma);
-		hwif->dmatable_cpu = NULL;
-	}
-	if (hwif->sg_table) {
-		kfree(hwif->sg_table);
-		hwif->sg_table = NULL;
-	}
-	if ((hwif->dma_extra) && (hwif->unit == 0))
-		release_region((hwif->dma_base + 16), hwif->dma_extra);
-	release_region(hwif->dma_base, 8);
-	hwif->dma_base = 0;
+				    ch->dmatable_cpu,
+				    ch->dmatable_dma);
+		ch->dmatable_cpu = NULL;
+	}
+	if (ch->sg_table) {
+		kfree(ch->sg_table);
+		ch->sg_table = NULL;
+	}
+	if ((ch->dma_extra) && (ch->unit == 0))
+		release_region((ch->dma_base + 16), ch->dma_extra);
+	release_region(ch->dma_base, 8);
+	ch->dma_base = 0;
 }
 
 /*
  * This can be called for a dynamically installed interface. Don't __init it
  */
-void ide_setup_dma(struct ata_channel *hwif, unsigned long dma_base, unsigned int num_ports)
+void ide_setup_dma(struct ata_channel *ch, unsigned long dma_base, unsigned int num_ports)
 {
-	printk("    %s: BM-DMA at 0x%04lx-0x%04lx", hwif->name, dma_base, dma_base + num_ports - 1);
+	printk("    %s: BM-DMA at 0x%04lx-0x%04lx", ch->name, dma_base, dma_base + num_ports - 1);
 	if (check_region(dma_base, num_ports)) {
 		printk(" -- ERROR, PORT ADDRESSES ALREADY IN USE\n");
 		return;
 	}
-	request_region(dma_base, num_ports, hwif->name);
-	hwif->dma_base = dma_base;
-	hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
+	request_region(dma_base, num_ports, ch->name);
+	ch->dma_base = dma_base;
+	ch->dmatable_cpu = pci_alloc_consistent(ch->pci_dev,
 						  PRD_ENTRIES * PRD_BYTES,
-						  &hwif->dmatable_dma);
-	if (hwif->dmatable_cpu == NULL)
+						  &ch->dmatable_dma);
+	if (ch->dmatable_cpu == NULL)
 		goto dma_alloc_failure;
 
-	hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
+	ch->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
 				 GFP_KERNEL);
-	if (hwif->sg_table == NULL) {
-		pci_free_consistent(hwif->pci_dev, PRD_ENTRIES * PRD_BYTES,
-				    hwif->dmatable_cpu, hwif->dmatable_dma);
+	if (ch->sg_table == NULL) {
+		pci_free_consistent(ch->pci_dev, PRD_ENTRIES * PRD_BYTES,
+				    ch->dmatable_cpu, ch->dmatable_dma);
 		goto dma_alloc_failure;
 	}
 
-	hwif->udma = ide_dmaproc;
+	ch->udma = ide_dmaproc;
 
-	if (hwif->chipset != ide_trm290) {
-		byte dma_stat = inb(dma_base+2);
+	if (ch->chipset != ide_trm290) {
+		u8 dma_stat = inb(dma_base+2);
 		printk(", BIOS settings: %s:%s, %s:%s",
-		       hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
-		       hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
+		       ch->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
+		       ch->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
 	}
 	printk("\n");
 	return;
@@ -728,3 +581,141 @@
 dma_alloc_failure:
 	printk(" -- ERROR, UNABLE TO ALLOCATE DMA TABLES\n");
 }
+
+/****************************************************************************
+ * UDMA function which should have architecture specific counterparts where
+ * neccessary.
+ */
+
+/*
+ * This prepares a dma request.  Returns 0 if all went okay, returns 1
+ * otherwise.  May also be invoked from trm290.c
+ */
+int udma_new_table(struct ata_channel *ch, struct request *rq)
+{
+	unsigned int *table = ch->dmatable_cpu;
+#ifdef CONFIG_BLK_DEV_TRM290
+	unsigned int is_trm290_chipset = (ch->chipset == ide_trm290);
+#else
+	const int is_trm290_chipset = 0;
+#endif
+	unsigned int count = 0;
+	int i;
+	struct scatterlist *sg;
+
+	ch->sg_nents = i = build_sglist(ch, rq);
+	if (!i)
+		return 0;
+
+	sg = ch->sg_table;
+	while (i) {
+		u32 cur_addr;
+		u32 cur_len;
+
+		cur_addr = sg_dma_address(sg);
+		cur_len = sg_dma_len(sg);
+
+		/*
+		 * Fill in the dma table, without crossing any 64kB boundaries.
+		 * Most hardware requires 16-bit alignment of all blocks,
+		 * but the trm290 requires 32-bit alignment.
+		 */
+
+		while (cur_len) {
+			u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
+
+			if (count++ >= PRD_ENTRIES) {
+				printk("ide-dma: count %d, sg_nents %d, cur_len %d, cur_addr %u\n",
+						count, ch->sg_nents, cur_len, cur_addr);
+				BUG();
+			}
+
+			if (bcount > cur_len)
+				bcount = cur_len;
+			*table++ = cpu_to_le32(cur_addr);
+			xcount = bcount & 0xffff;
+			if (is_trm290_chipset)
+				xcount = ((xcount >> 2) - 1) << 16;
+			if (xcount == 0x0000) {
+		        /*
+			 * Most chipsets correctly interpret a length of
+			 * 0x0000 as 64KB, but at least one (e.g. CS5530)
+			 * misinterprets it as zero (!). So here we break
+			 * the 64KB entry into two 32KB entries instead.
+			 */
+				if (count++ >= PRD_ENTRIES) {
+					pci_unmap_sg(ch->pci_dev, sg,
+						     ch->sg_nents,
+						     ch->sg_dma_direction);
+					return 0;
+				}
+
+				*table++ = cpu_to_le32(0x8000);
+				*table++ = cpu_to_le32(cur_addr + 0x8000);
+				xcount = 0x8000;
+			}
+			*table++ = cpu_to_le32(xcount);
+			cur_addr += bcount;
+			cur_len -= bcount;
+		}
+
+		sg++;
+		i--;
+	}
+
+	if (!count)
+		printk(KERN_ERR "%s: empty DMA table?\n", ch->name);
+	else if (!is_trm290_chipset)
+		*--table |= cpu_to_le32(0x80000000);
+
+	return count;
+}
+
+/* Teardown mappings after DMA has completed.  */
+void udma_destroy_table(struct ata_channel *ch)
+{
+	pci_unmap_sg(ch->pci_dev, ch->sg_table, ch->sg_nents, ch->sg_dma_direction);
+}
+
+void udma_print(struct ata_device *drive)
+{
+#ifdef CONFIG_ARCH_ACORN
+	printk(", DMA");
+#else
+	struct hd_driveid *id = drive->id;
+	char *str = NULL;
+
+	if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
+	    (id->dma_ultra & (id->dma_ultra >> 14) & 3)) {
+		if ((id->dma_ultra >> 15) & 1)
+			str = ", UDMA(mode 7)";	/* UDMA BIOS-enabled! */
+		else
+			str = ", UDMA(133)";	/* UDMA BIOS-enabled! */
+	} else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
+		  (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
+		if ((id->dma_ultra >> 13) & 1) {
+			str = ", UDMA(100)";	/* UDMA BIOS-enabled! */
+		} else if ((id->dma_ultra >> 12) & 1) {
+			str = ", UDMA(66)";	/* UDMA BIOS-enabled! */
+		} else {
+			str = ", UDMA(44)";	/* UDMA BIOS-enabled! */
+		}
+	} else if ((id->field_valid & 4) &&
+		   (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
+		if ((id->dma_ultra >> 10) & 1) {
+			str = ", UDMA(33)";	/* UDMA BIOS-enabled! */
+		} else if ((id->dma_ultra >> 9) & 1) {
+			str = ", UDMA(25)";	/* UDMA BIOS-enabled! */
+		} else {
+			str = ", UDMA(16)";	/* UDMA BIOS-enabled! */
+		}
+	} else if (id->field_valid & 4)
+		str = ", (U)DMA";	/* Can be BIOS-enabled! */
+	else
+		str = ", DMA";
+
+	printk(str);
+#endif
+}
+
+EXPORT_SYMBOL(udma_print);
diff -urN linux-2.5.13/drivers/ide/ide-features.c linux/drivers/ide/ide-features.c
--- linux-2.5.13/drivers/ide/ide-features.c	2002-05-03 02:22:55.000000000 +0200
+++ linux/drivers/ide/ide-features.c	2002-05-03 18:03:00.000000000 +0200
@@ -44,29 +44,38 @@
  */
 char *ide_xfer_verbose (byte xfer_rate)
 {
-	switch(xfer_rate) {
-		case XFER_UDMA_7:	return("UDMA 7");
-		case XFER_UDMA_6:	return("UDMA 6");
-		case XFER_UDMA_5:	return("UDMA 5");
-		case XFER_UDMA_4:	return("UDMA 4");
-		case XFER_UDMA_3:	return("UDMA 3");
-		case XFER_UDMA_2:	return("UDMA 2");
-		case XFER_UDMA_1:	return("UDMA 1");
-		case XFER_UDMA_0:	return("UDMA 0");
-		case XFER_MW_DMA_2:	return("MW DMA 2");
-		case XFER_MW_DMA_1:	return("MW DMA 1");
-		case XFER_MW_DMA_0:	return("MW DMA 0");
-		case XFER_SW_DMA_2:	return("SW DMA 2");
-		case XFER_SW_DMA_1:	return("SW DMA 1");
-		case XFER_SW_DMA_0:	return("SW DMA 0");
-		case XFER_PIO_4:	return("PIO 4");
-		case XFER_PIO_3:	return("PIO 3");
-		case XFER_PIO_2:	return("PIO 2");
-		case XFER_PIO_1:	return("PIO 1");
-		case XFER_PIO_0:	return("PIO 0");
-		case XFER_PIO_SLOW:	return("PIO SLOW");
-		default:		return("XFER ERROR");
-	}
+	static struct ide_xfer_par {
+		byte rate;
+		char *name;
+	} xfer_verbose[] = {
+		{ XFER_UDMA_7,		"UDMA 7" },
+		{ XFER_UDMA_6,		"UDMA 6" },
+		{ XFER_UDMA_5,		"UDMA 5" },
+		{ XFER_UDMA_4,		"UDMA 4" },
+		{ XFER_UDMA_3,		"UDMA 3" },
+		{ XFER_UDMA_2,		"UDMA 2" },
+		{ XFER_UDMA_1,		"UDMA 1" },
+		{ XFER_UDMA_0,		"UDMA 0" },
+		{ XFER_MW_DMA_2,	"MW DMA 2" },
+		{ XFER_MW_DMA_1,	"MW DMA 1" },
+		{ XFER_MW_DMA_0,	"MW DMA 0" },
+		{ XFER_SW_DMA_2,	"SW DMA 2" },
+		{ XFER_SW_DMA_1,	"SW DMA 1" },
+		{ XFER_SW_DMA_0,	"SW DMA 0" },
+		{ XFER_PIO_4,		"PIO 4" },
+		{ XFER_PIO_3,		"PIO 3" },
+		{ XFER_PIO_2,		"PIO 2" },
+		{ XFER_PIO_1,		"PIO 1" },
+		{ XFER_PIO_0,		"PIO 0" },
+		{ XFER_PIO_SLOW,	"PIO SLOW" },
+	};
+
+	int i = 0;
+
+	for (; i < ARRAY_SIZE(xfer_verbose); i++)
+		if (xfer_verbose[i].rate == xfer_rate)
+			return xfer_verbose[i].name;
+	return "XFER ERROR";
 }
 
 byte ide_auto_reduce_xfer (ide_drive_t *drive)
diff -urN linux-2.5.13/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.13/drivers/ide/ide-pmac.c	2002-05-03 02:22:55.000000000 +0200
+++ linux/drivers/ide/ide-pmac.c	2002-05-04 04:59:34.000000000 +0200
@@ -1164,9 +1164,9 @@
 
 /* Teardown mappings after DMA has completed.  */
 static void
-pmac_ide_destroy_dmatable (ide_drive_t *drive, int ix)
+pmac_ide_destroy_dmatable(struct ata_channel *ch, int ix)
 {
-	struct pci_dev *dev = drive->channel->pci_dev;
+	struct pci_dev *dev = ch->pci_dev;
 	struct scatterlist *sg = pmac_ide[ix].sg_table;
 	int nents = pmac_ide[ix].sg_nents;
 
@@ -1367,10 +1367,6 @@
 		break;
 	case ide_dma_read:
 	case ide_dma_write:
-		/* this almost certainly isn't needed since we don't
-		   appear to have a rwproc */
-		if (drive->channel->rwproc)
-			drive->channel->rwproc(drive, func);
 		reading = (func == ide_dma_read);
 		if (!pmac_ide_build_dmatable(drive, rq, ix, !reading))
 			return 1;
@@ -1404,7 +1400,7 @@
 		drive->waiting_for_dma = 0;
 		dstat = in_le32(&dma->status);
 		out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
-		pmac_ide_destroy_dmatable(drive, ix);
+		pmac_ide_destroy_dmatable(drive->channel, ix);
 		/* verify good dma status */
 		return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
 	case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
@@ -1453,8 +1449,6 @@
 	case ide_dma_bad_drive:
 	case ide_dma_good_drive:
 		return check_drive_lists(drive, (func == ide_dma_good_drive));
-	case ide_dma_verbose:
-		return report_drive_dmaing(drive);
 	case ide_dma_retune:
 	case ide_dma_lostirq:
 	case ide_dma_timeout:
diff -urN linux-2.5.13/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.13/drivers/ide/ide-probe.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-05-03 18:03:00.000000000 +0200
@@ -448,7 +448,7 @@
  */
 static void channel_probe(struct ata_channel *ch)
 {
-	unsigned int unit;
+	unsigned int i;
 	unsigned long flags;
 	int error;
 
@@ -463,8 +463,8 @@
 	/*
 	 * Check for the presence of a channel by probing for drives on it.
 	 */
-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		struct ata_device *drive = &ch->drives[unit];
+	for (i = 0; i < MAX_DRIVES; ++i) {
+		struct ata_device *drive = &ch->drives[i];
 
 		probe_for_drive(drive);
 
@@ -483,23 +483,8 @@
 		error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 8, ch->name);
 		ch->straight8 = 1;
 	} else {
-		if (ch->io_ports[IDE_DATA_OFFSET])
-			error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 1, ch->name);
-		if (ch->io_ports[IDE_ERROR_OFFSET])
-			error += !request_region(ch->io_ports[IDE_ERROR_OFFSET], 1, ch->name);
-		if (ch->io_ports[IDE_NSECTOR_OFFSET])
-			error += !request_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1, ch->name);
-		if (ch->io_ports[IDE_SECTOR_OFFSET])
-			error += !request_region(ch->io_ports[IDE_SECTOR_OFFSET], 1, ch->name);
-		if (ch->io_ports[IDE_LCYL_OFFSET])
-			error += !request_region(ch->io_ports[IDE_LCYL_OFFSET], 1, ch->name);
-		if (ch->io_ports[IDE_HCYL_OFFSET])
-			error += !request_region(ch->io_ports[IDE_HCYL_OFFSET], 1, ch->name);
-		if (ch->io_ports[IDE_SELECT_OFFSET])
-			error += !request_region(ch->io_ports[IDE_SELECT_OFFSET], 1, ch->name);
-		if (ch->io_ports[IDE_STATUS_OFFSET])
-			error += !request_region(ch->io_ports[IDE_STATUS_OFFSET], 1, ch->name);
-
+		for (i = 0; i < 8; i++)
+			error += !request_region(ch->io_ports[i], 1, ch->name);
 	}
 	if (ch->io_ports[IDE_CONTROL_OFFSET])
 		error += !request_region(ch->io_ports[IDE_CONTROL_OFFSET], 1, ch->name);
@@ -561,8 +546,8 @@
 	/*
 	 * Now setup the PIO transfer modes of the drives on this channel.
 	 */
-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		struct ata_device *drive = &ch->drives[unit];
+	for (i = 0; i < MAX_DRIVES; ++i) {
+		struct ata_device *drive = &ch->drives[i];
 
 		if (drive->present && (drive->autotune == 1)) {
 			if (drive->channel->tuneproc)
@@ -819,6 +804,16 @@
 		goto err_kmalloc_gd_part;
 	memset(gd->part, 0, ATA_MINORS * sizeof(struct hd_struct));
 
+	gd->de_arr = kmalloc (sizeof(*gd->de_arr) * MAX_DRIVES, GFP_KERNEL);
+	if (!gd->de_arr)
+		goto err_kmalloc_gd_de_arr;
+	memset(gd->de_arr, 0, sizeof(*gd->de_arr) * MAX_DRIVES);
+
+	gd->flags = kmalloc (sizeof(*gd->flags) * MAX_DRIVES, GFP_KERNEL);
+	if (!gd->flags)
+		goto err_kmalloc_gd_flags;
+	memset(gd->flags, 0, sizeof(*gd->flags) * MAX_DRIVES);
+
 	for (unit = 0; unit < MAX_DRIVES; ++unit)
 		ch->drives[unit].part = &gd->part[unit << PARTN_BITS];
 
diff -urN linux-2.5.13/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.13/drivers/ide/ide-taskfile.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-05-04 05:59:57.000000000 +0200
@@ -130,12 +130,12 @@
 }
 #endif
 
-static void ata_read_16(ide_drive_t *drive, void *buffer, unsigned int wcount)
+static void ata_read_16(struct ata_device *drive, void *buffer, unsigned int wcount)
 {
 	insw(IDE_DATA_REG, buffer, wcount<<1);
 }
 
-static void ata_write_16(ide_drive_t *drive, void *buffer, unsigned int wcount)
+static void ata_write_16(struct ata_device *drive, void *buffer, unsigned int wcount)
 {
 	outsw(IDE_DATA_REG, buffer, wcount<<1);
 }
@@ -143,7 +143,7 @@
 /*
  * This is used for most PIO data transfers *from* the device.
  */
-void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount)
+void ata_read(struct ata_device *drive, void *buffer, unsigned int wcount)
 {
 	int io_32bit;
 
@@ -178,7 +178,7 @@
 /*
  * This is used for most PIO data transfers *to* the device interface.
  */
-void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount)
+void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount)
 {
 	int io_32bit;
 
@@ -213,7 +213,7 @@
  * so if an odd bytecount is specified, be sure that there's at least one
  * extra byte allocated for the buffer.
  */
-void atapi_read(ide_drive_t *drive, void *buffer, unsigned int bytecount)
+void atapi_read(struct ata_device *drive, void *buffer, unsigned int bytecount)
 {
 	if (drive->channel->atapi_read) {
 		drive->channel->atapi_read(drive, buffer, bytecount);
@@ -233,7 +233,7 @@
 		insw(IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
 }
 
-void atapi_write(ide_drive_t *drive, void *buffer, unsigned int bytecount)
+void atapi_write(struct ata_device *drive, void *buffer, unsigned int bytecount)
 {
 	if (drive->channel->atapi_write) {
 		drive->channel->atapi_write(drive, buffer, bytecount);
@@ -256,7 +256,7 @@
 /*
  * Needed for PCI irq sharing
  */
-int drive_is_ready(ide_drive_t *drive)
+int drive_is_ready(struct ata_device *drive)
 {
 	byte stat = 0;
 	if (drive->waiting_for_dma)
@@ -290,7 +290,7 @@
  * Stuff the first sector(s) by implicitly calling the handler driectly
  * therafter.
  */
-void ata_poll_drive_ready(ide_drive_t *drive)
+void ata_poll_drive_ready(struct ata_device *drive)
 {
 	int i;
 
@@ -399,7 +399,7 @@
 	return ide_started;
 }
 
-ide_startstop_t ata_taskfile(ide_drive_t *drive,
+ide_startstop_t ata_taskfile(struct ata_device *drive,
 		struct ata_taskfile *args, struct request *rq)
 {
 	struct hd_driveid *id = drive->id;
@@ -456,39 +456,38 @@
 		if (args->prehandler != NULL)
 			return args->prehandler(drive, rq);
 	} else {
+		/*
+		 * FIXME: this is a gross hack, need to unify tcq dma proc and
+		 * regular dma proc -- basically split stuff that needs to act
+		 * on a request from things like ide_dma_check etc.
+		 */
 		ide_dma_action_t dma_act;
-		int tcq = 0;
 
 		if (!drive->using_dma)
 			return ide_started;
 
 		/* for dma commands we don't set the handler */
-		if (args->taskfile.command == WIN_WRITEDMA || args->taskfile.command == WIN_WRITEDMA_EXT)
+		if (args->taskfile.command == WIN_WRITEDMA
+		 || args->taskfile.command == WIN_WRITEDMA_EXT)
 			dma_act = ide_dma_write;
-		else if (args->taskfile.command == WIN_READDMA || args->taskfile.command == WIN_READDMA_EXT)
+		else if (args->taskfile.command == WIN_READDMA
+		      || args->taskfile.command == WIN_READDMA_EXT)
 			dma_act = ide_dma_read;
-		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT) {
-			tcq = 1;
-			dma_act = ide_dma_write_queued;
-		} else if (args->taskfile.command == WIN_READDMA_QUEUED || args->taskfile.command == WIN_READDMA_QUEUED_EXT) {
-			tcq = 1;
-			dma_act = ide_dma_read_queued;
-		} else {
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED
+		      || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT
+		      || args->taskfile.command == WIN_READDMA_QUEUED
+		      || args->taskfile.command == WIN_READDMA_QUEUED_EXT)
+			return udma_tcq_taskfile(drive, rq);
+#endif
+		else {
 			printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
 			return ide_stopped;
 		}
 
-		/*
-		 * FIXME: this is a gross hack, need to unify tcq dma proc and
-		 * regular dma proc -- basically split stuff that needs to act
-		 * on a request from things like ide_dma_check etc.
-		 */
-		if (tcq)
-			return drive->channel->udma(dma_act, drive, rq);
-		else {
-			if (drive->channel->udma(dma_act, drive, rq))
-				return ide_stopped;
-		}
+
+		if (drive->channel->udma(dma_act, drive, rq))
+			return ide_stopped;
 	}
 
 	return ide_started;
@@ -900,7 +899,7 @@
 	}
 }
 
-int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
+int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *args, byte *buf)
 {
 	struct request rq;
 
@@ -926,7 +925,7 @@
  * interface.
  */
 
-int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
+int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg)
 {
 	int err = 0;
 	u8 vals[4];
diff -urN linux-2.5.13/drivers/ide/Makefile linux/drivers/ide/Makefile
--- linux-2.5.13/drivers/ide/Makefile	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/Makefile	2002-05-04 06:02:26.000000000 +0200
@@ -10,7 +10,7 @@
 
 O_TARGET := idedriver.o
 
-export-objs		:= ide-taskfile.o ide.o ide-features.o ide-probe.o ataraid.o
+export-objs	:= ide-taskfile.o ide.o ide-features.o ide-probe.o ide-dma.o ataraid.o
 
 obj-y		:=
 obj-m		:=
diff -urN linux-2.5.13/drivers/ide/ns87415.c linux/drivers/ide/ns87415.c
--- linux-2.5.13/drivers/ide/ns87415.c	2002-05-03 02:22:48.000000000 +0200
+++ linux/drivers/ide/ns87415.c	2002-05-04 03:51:59.000000000 +0200
@@ -93,7 +93,7 @@
 			dma_stat = inb(hwif->dma_base+2);
 			outb(inb(hwif->dma_base)&~1, hwif->dma_base);	/* stop DMA */
 			outb(inb(hwif->dma_base)|6, hwif->dma_base);	/* from ERRATA: clear the INTR & ERROR bits */
-			ide_destroy_dmatable(drive);			/* and free any DMA resources */
+			udma_destroy_table(hwif);			/* and free any DMA resources */
 			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		case ide_dma_write:
 		case ide_dma_read:
diff -urN linux-2.5.13/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.13/drivers/ide/tcq.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/tcq.c	2002-05-04 05:25:59.000000000 +0200
@@ -215,6 +215,8 @@
 	return 0;
 }
 
+static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq);
+
 /*
  * issue SERVICE command to drive -- drive must have been selected first,
  * and it must have reported a need for service (status has SERVICE_STAT set)
@@ -296,7 +298,7 @@
 	 * interrupt to indicate end of transfer, release is not allowed
 	 */
 	TCQ_PRINTK("%s: starting command %x\n", __FUNCTION__, stat);
-	return drive->channel->udma(ide_dma_queued_start, drive, rq);
+	return udma_tcq_start(drive, rq);
 }
 
 static ide_startstop_t check_service(struct ata_device *drive)
@@ -483,11 +485,119 @@
 	return 0;
 }
 
+static int tcq_wait_dataphase(struct ata_device *drive)
+{
+	u8 stat;
+	int i;
+
+	while ((stat = GET_STAT()) & BUSY_STAT)
+		udelay(10);
+
+	if (OK_STAT(stat, READY_STAT | DRQ_STAT, drive->bad_wstat))
+		return 0;
+
+	i = 0;
+	udelay(1);
+	while (!OK_STAT(GET_STAT(), READY_STAT | DRQ_STAT, drive->bad_wstat)) {
+		if (unlikely(i++ > IDE_TCQ_WAIT))
+			return 1;
+
+		udelay(10);
+	}
+
+	return 0;
+}
+
+/****************************************************************************
+ * UDMA transfer handling functions.
+ */
+
+/*
+ * Invoked from a SERVICE interrupt, command etc already known.  Just need to
+ * start the dma engine for this tag.
+ */
+static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq)
+{
+	struct ata_channel *ch = drive->channel;
+
+	TCQ_PRINTK("%s: setting up queued %d\n", __FUNCTION__, rq->tag);
+	if (!test_bit(IDE_BUSY, &ch->hwgroup->flags))
+		printk("queued_rw: IDE_BUSY not set\n");
+
+	if (tcq_wait_dataphase(drive))
+		return ide_stopped;
+
+	if (ata_start_dma(drive, rq))
+		return ide_stopped;
+
+	set_irq(drive, ide_dmaq_intr);
+	if (!ch->udma(ide_dma_begin, drive, rq))
+		return ide_started;
+
+	return ide_stopped;
+}
+
 /*
- * for now assume that command list is always as big as we need and don't
- * attempt to shrink it on tcq disable
+ * Start a queued command from scratch.
  */
-static int enable_queued(struct ata_device *drive, int on)
+ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
+{
+	u8 stat;
+	u8 feat;
+
+	struct ata_taskfile *args = rq->special;
+
+	TCQ_PRINTK("%s: start tag %d\n", drive->name, rq->tag);
+
+	/*
+	 * set nIEN, tag start operation will enable again when
+	 * it is safe
+	 */
+	drive_ctl_nien(drive, 1);
+
+	OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
+
+	if (wait_altstat(drive, &stat, BUSY_STAT)) {
+		ide_dump_status(drive, "queued start", stat);
+		tcq_invalidate_queue(drive);
+		return ide_stopped;
+	}
+
+	drive_ctl_nien(drive, 0);
+
+	if (stat & ERR_STAT) {
+		ide_dump_status(drive, "tcq_start", stat);
+		return ide_stopped;
+	}
+
+	/*
+	 * drive released the bus, clear active tag and
+	 * check for service
+	 */
+	if ((feat = GET_FEAT()) & NSEC_REL) {
+		drive->immed_rel++;
+		HWGROUP(drive)->rq = NULL;
+		set_irq(drive, ide_dmaq_intr);
+
+		TCQ_PRINTK("REL in queued_start\n");
+
+		if ((stat = GET_STAT()) & SERVICE_STAT)
+			return service(drive);
+
+		return ide_released;
+	}
+
+	TCQ_PRINTK("IMMED in queued_start\n");
+	drive->immed_comp++;
+
+	return udma_tcq_start(drive, rq);
+}
+
+/*
+ * For now assume that command list is always as big as we need and don't
+ * attempt to shrink it on tcq disable.
+ */
+int udma_tcq_enable(struct ata_device *drive, int on)
 {
 	int depth = drive->using_tcq ? drive->queue_depth : 0;
 
@@ -523,120 +633,3 @@
 	drive->using_tcq = 1;
 	return 0;
 }
-
-static int tcq_wait_dataphase(struct ata_device *drive)
-{
-	u8 stat;
-	int i;
-
-	while ((stat = GET_STAT()) & BUSY_STAT)
-		udelay(10);
-
-	if (OK_STAT(stat, READY_STAT | DRQ_STAT, drive->bad_wstat))
-		return 0;
-
-	i = 0;
-	udelay(1);
-	while (!OK_STAT(GET_STAT(), READY_STAT | DRQ_STAT, drive->bad_wstat)) {
-		if (unlikely(i++ > IDE_TCQ_WAIT))
-			return 1;
-
-		udelay(10);
-	}
-
-	return 0;
-}
-
-ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
-{
-	struct ata_channel *hwif = drive->channel;
-	unsigned int enable_tcq = 1;
-	u8 stat;
-	u8 feat;
-
-	switch (func) {
-		/*
-		 * invoked from a SERVICE interrupt, command etc already known.
-		 * just need to start the dma engine for this tag
-		 */
-		case ide_dma_queued_start:
-			TCQ_PRINTK("ide_dma: setting up queued %d\n", rq->tag);
-			if (!test_bit(IDE_BUSY, &HWGROUP(drive)->flags))
-				printk("queued_rw: IDE_BUSY not set\n");
-
-			if (tcq_wait_dataphase(drive))
-				return ide_stopped;
-
-			if (ide_start_dma(func, drive))
-				return ide_stopped;
-
-			set_irq(drive, ide_dmaq_intr);
-			if (!hwif->udma(ide_dma_begin, drive, rq))
-				return ide_started;
-
-			return ide_stopped;
-
-			/*
-			 * start a queued command from scratch
-			 */
-		case ide_dma_read_queued:
-		case ide_dma_write_queued: {
-			struct ata_taskfile *args = rq->special;
-
-			TCQ_PRINTK("%s: start tag %d\n", drive->name, rq->tag);
-
-			/*
-			 * set nIEN, tag start operation will enable again when
-			 * it is safe
-			 */
-			drive_ctl_nien(drive, 1);
-
-			OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
-
-			if (wait_altstat(drive, &stat, BUSY_STAT)) {
-				ide_dump_status(drive, "queued start", stat);
-				tcq_invalidate_queue(drive);
-				return ide_stopped;
-			}
-
-			drive_ctl_nien(drive, 0);
-
-			if (stat & ERR_STAT) {
-				ide_dump_status(drive, "tcq_start", stat);
-				return ide_stopped;
-			}
-
-			/*
-			 * drive released the bus, clear active tag and
-			 * check for service
-			 */
-			if ((feat = GET_FEAT()) & NSEC_REL) {
-				drive->immed_rel++;
-				HWGROUP(drive)->rq = NULL;
-				set_irq(drive, ide_dmaq_intr);
-
-				TCQ_PRINTK("REL in queued_start\n");
-
-				if ((stat = GET_STAT()) & SERVICE_STAT)
-					return service(drive);
-
-				return ide_released;
-			}
-
-			TCQ_PRINTK("IMMED in queued_start\n");
-			drive->immed_comp++;
-			return hwif->udma(ide_dma_queued_start, drive, rq);
-			}
-
-		case ide_dma_queued_off:
-			enable_tcq = 0;
-		case ide_dma_queued_on:
-			if (enable_tcq && !drive->using_dma)
-				return 1;
-			return enable_queued(drive, enable_tcq);
-		default:
-			break;
-	}
-
-	return 1;
-}
diff -urN linux-2.5.13/drivers/ide/trm290.c linux/drivers/ide/trm290.c
--- linux-2.5.13/drivers/ide/trm290.c	2002-05-03 02:22:44.000000000 +0200
+++ linux/drivers/ide/trm290.c	2002-05-04 03:52:43.000000000 +0200
@@ -175,7 +175,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
+	struct ata_channel *ch = drive->channel;
 	unsigned int count, reading = 2, writing = 0;
 
 	switch (func) {
@@ -186,12 +186,12 @@
 			break;	/* always use PIO for writes */
 #endif
 		case ide_dma_read:
-			if (!(count = ide_build_dmatable(drive, func)))
+			if (!(count = udma_new_table(ch, rq)))
 				break;		/* try PIO instead of DMA */
 			trm290_prepare_drive(drive, 1);	/* select DMA xfer */
-			outl(hwif->dmatable_dma|reading|writing, hwif->dma_base);
+			outl(ch->dmatable_dma|reading|writing, ch->dma_base);
 			drive->waiting_for_dma = 1;
-			outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
+			outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
 			if (drive->type != ATA_DISK)
 				return 0;
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
@@ -201,10 +201,10 @@
 			return 0;
 		case ide_dma_end:
 			drive->waiting_for_dma = 0;
-			ide_destroy_dmatable(drive);		/* purge DMA mappings */
-			return (inw(hwif->dma_base+2) != 0x00ff);
+			udma_destroy_table(ch);	/* purge DMA mappings */
+			return (inw(ch->dma_base + 2) != 0x00ff);
 		case ide_dma_test_irq:
-			return (inw(hwif->dma_base+2) == 0x00ff);
+			return (inw(ch->dma_base + 2) == 0x00ff);
 		default:
 			return ide_dmaproc(func, drive, rq);
 	}
diff -urN linux-2.5.13/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.13/include/linux/ide.h	2002-05-04 06:07:15.000000000 +0200
+++ linux/include/linux/ide.h	2002-05-04 05:41:33.000000000 +0200
@@ -368,32 +368,24 @@
 	/*
 	 * tcq statistics
 	 */
-	unsigned long	immed_rel;	
+	unsigned long	immed_rel;
 	unsigned long	immed_comp;
 	int		max_last_depth;
 	int		max_depth;
 } ide_drive_t;
 
-/*
- * This initiates/aborts DMA read/write operations on a drive.
- *
- * The caller is assumed to have selected the drive and programmed the drive's
- * sector address using CHS or LBA.  All that remains is to prepare for DMA
- * and then issue the actual read/write DMA/PIO command to the drive.
- *
- * Returns 0 if all went well.
- * Returns 1 if DMA read/write could not be started, in which case the caller
- * should either try again later, or revert to PIO for the current request.
- */
-typedef enum {	ide_dma_read,	ide_dma_write,		ide_dma_begin,
-		ide_dma_end,	ide_dma_check,		ide_dma_on,
-		ide_dma_off,	ide_dma_off_quietly,	ide_dma_test_irq,
-		ide_dma_bad_drive,			ide_dma_good_drive,
-		ide_dma_verbose,			ide_dma_retune,
-		ide_dma_lostirq,			ide_dma_timeout,
-		ide_dma_read_queued,			ide_dma_write_queued,
-		ide_dma_queued_start,			ide_dma_queued_on,
-		ide_dma_queued_off,
+typedef enum {
+	ide_dma_read,	ide_dma_write,
+	ide_dma_begin,	ide_dma_end,
+	ide_dma_check,
+	ide_dma_on, ide_dma_off,
+	ide_dma_off_quietly,
+	ide_dma_test_irq,
+	ide_dma_bad_drive,
+	ide_dma_good_drive,
+	ide_dma_retune,
+	ide_dma_lostirq,
+	ide_dma_timeout
 } ide_dma_action_t;
 
 enum {
@@ -436,9 +428,6 @@
 	/* special host masking for drive selection */
 	void (*maskproc) (struct ata_device *, int);
 
-	/* adjust timing based upon rq->cmd direction */
-	void (*rwproc) (struct ata_device *, ide_dma_action_t);
-
 	/* check host's drive quirk list */
 	int (*quirkproc) (struct ata_device *);
 
@@ -472,6 +461,7 @@
 	unsigned autodma	: 1;	/* automatically try to enable DMA at boot */
 	unsigned udma_four	: 1;	/* 1=ATA-66 capable, 0=default */
 	unsigned highmem	: 1;	/* can do full 32-bit dma */
+	unsigned straight8	: 1;	/* Alan's straight 8 check */
 	unsigned no_io_32bit	: 1;	/* disallow enabling 32bit I/O */
 	unsigned no_unmask	: 1;	/* disallow setting unmask bit */
 	unsigned auto_poll	: 1;	/* supports nop auto-poll */
@@ -482,8 +472,8 @@
 #if (DISK_RECOVERY_TIME > 0)
 	unsigned long	last_time;	/* time when previous rq was done */
 #endif
-	byte		straight8;	/* Alan's straight 8 check */
-	int (*busproc)(struct ata_device *, int);	/* driver soft-power interface */
+	/* driver soft-power interface */
+	int (*busproc)(struct ata_device *, int);
 	byte		bus_state;	/* power state of the IDE bus */
 };
 
@@ -562,7 +552,7 @@
 #define SETTING_WRITE	(1 << 1)
 #define SETTING_RW	(SETTING_READ | SETTING_WRITE)
 
-typedef int (ide_procset_t)(ide_drive_t *, int);
+typedef int (ide_procset_t)(struct ata_device *, int);
 typedef struct ide_settings_s {
 	char			*name;
 	int			rw;
@@ -579,11 +569,11 @@
 	struct ide_settings_s	*next;
 } ide_settings_t;
 
-void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set);
-void ide_remove_setting(ide_drive_t *drive, char *name);
-int ide_read_setting(ide_drive_t *t, ide_settings_t *setting);
-int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val);
-void ide_add_generic_settings(ide_drive_t *drive);
+extern void ide_add_setting(struct ata_device *, const char *, int, int, int, int, int, int, int, int, void *, ide_procset_t *);
+extern void ide_remove_setting(struct ata_device *, char *);
+extern int ide_read_setting(struct ata_device *, ide_settings_t *);
+extern int ide_write_setting(struct ata_device *, ide_settings_t *, int);
+extern void ide_add_generic_settings(struct ata_device *);
 
 /*
  * /proc/ide interface
@@ -696,19 +686,19 @@
 /*
  * Error reporting, in human readable form (luxurious, but a memory hog).
  */
-byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat);
+extern byte ide_dump_status(struct ata_device *, const char *, byte);
 
 /*
  * ide_error() takes action based on the error returned by the controller.
  * The caller should return immediately after invoking this.
  */
-ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
+extern ide_startstop_t ide_error(struct ata_device *, const char *, byte);
 
 /*
  * Issue a simple drive command
  * The drive must be selected beforehand.
  */
-void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ata_handler_t handler);
+void ide_cmd(struct ata_device *, byte, byte, ata_handler_t);
 
 /*
  * ide_fixstring() cleans up and (optionally) byte-swaps a text string,
@@ -726,9 +716,9 @@
  * caller should return the updated value of "startstop" in this case.
  * "startstop" is unchanged when the function returns 0;
  */
-int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout);
+extern int ide_wait_stat(ide_startstop_t *, struct ata_device *, byte, byte, unsigned long);
 
-int ide_wait_noerr(ide_drive_t *drive, byte good, byte bad, unsigned long timeout);
+extern int ide_wait_noerr(struct ata_device *, byte, byte, unsigned long);
 
 /*
  * This routine is called from the partition-table code in genhd.c
@@ -737,15 +727,15 @@
 int ide_xlate_1024(kdev_t, int, int, const char *);
 
 /*
- * Convert kdev_t structure into ide_drive_t * one.
+ * Convert kdev_t structure into struct ata_device * one.
  */
-ide_drive_t *get_info_ptr(kdev_t i_rdev);
+struct ata_device *get_info_ptr(kdev_t i_rdev);
 
 /*
  * Re-Start an operation for an IDE interface.
  * The caller should return immediately after invoking this.
  */
-ide_startstop_t restart_request(ide_drive_t *);
+ide_startstop_t restart_request(struct ata_device *);
 
 /*
  * This function is intended to be used prior to invoking ide_do_drive_cmd().
@@ -767,12 +757,12 @@
  */
 #define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
 
-extern int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action);
+extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t);
 
 /*
  * Clean up after success/failure of an explicit drive cmd.
  */
-void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err);
+extern void ide_end_drive_cmd(struct ata_device *, byte, byte);
 
 struct ata_taskfile {
 	struct hd_drive_task_hdr taskfile;
@@ -809,31 +799,20 @@
 
 void ide_delay_50ms(void);
 
-byte ide_auto_reduce_xfer (ide_drive_t *drive);
-int ide_driveid_update (ide_drive_t *drive);
-int ide_ata66_check (ide_drive_t *drive, struct ata_taskfile *args);
-int ide_config_drive_speed (ide_drive_t *drive, byte speed);
-byte eighty_ninty_three (ide_drive_t *drive);
-int set_transfer (ide_drive_t *drive, struct ata_taskfile *args);
+extern byte ide_auto_reduce_xfer(struct ata_device *);
+extern int ide_driveid_update(struct ata_device *);
+extern int ide_ata66_check(struct ata_device *, struct ata_taskfile *);
+extern int ide_config_drive_speed(struct ata_device *, byte);
+extern byte eighty_ninty_three(struct ata_device *);
+extern int set_transfer(struct ata_device *, struct ata_taskfile *);
 
 extern int system_bus_speed;
 
 /*
- * idedisk_input_data() is a wrapper around ide_input_data() which copes
- * with byte-swapping the input data if required.
- */
-extern void idedisk_input_data(ide_drive_t *drive, void *buffer, unsigned int wcount);
-
-/*
  * ide_stall_queue() can be used by a drive to give excess bandwidth back
  * to the hwgroup by sleeping for timeout jiffies.
  */
-void ide_stall_queue (ide_drive_t *drive, unsigned long timeout);
-
-/*
- * ide_get_queue() returns the queue which corresponds to a given device.
- */
-request_queue_t *ide_get_queue(kdev_t dev);
+void ide_stall_queue(struct ata_device *, unsigned long);
 
 /*
  * CompactFlash cards and their brethern pretend to be removable hard disks,
@@ -842,9 +821,9 @@
  * config bits.
  */
 
-extern int drive_is_flashcard(ide_drive_t *drive);
+extern int drive_is_flashcard(struct ata_device *);
 
-int ide_spin_wait_hwgroup (ide_drive_t *drive);
+int ide_spin_wait_hwgroup(struct ata_device *);
 void ide_timer_expiry (unsigned long data);
 extern void ata_irq_request(int irq, void *data, struct pt_regs *regs);
 void do_ide_request (request_queue_t * q);
@@ -890,15 +869,21 @@
 void __init ide_scan_pcibus(int scan_direction);
 #endif
 #ifdef CONFIG_BLK_DEV_IDEDMA
-extern int ide_build_dmatable(struct ata_device *, ide_dma_action_t);
-extern void ide_destroy_dmatable(struct ata_device *);
+
+extern int udma_new_table(struct ata_channel *, struct request *);
+extern void udma_destroy_table(struct ata_channel *);
+extern void udma_print(struct ata_device *);
+
+extern ide_startstop_t udma_tcq_taskfile(struct ata_device *, struct request *);
+extern int udma_tcq_enable(struct ata_device *, int);
+
 extern ide_startstop_t ide_dma_intr(struct ata_device *, struct request *);
 extern int check_drive_lists(struct ata_device *, int good_bad);
 extern int ide_dmaproc(ide_dma_action_t func, struct ata_device *, struct request *);
 extern ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t, struct ata_device *, struct request *);
 extern void ide_release_dma(struct ata_channel *);
 extern void ide_setup_dma(struct ata_channel *,	unsigned long, unsigned int) __init;
-extern int ide_start_dma(ide_dma_action_t, struct ata_device *);
+extern int ata_start_dma(struct ata_device *, struct request *rq);
 #endif
 
 extern spinlock_t ide_lock;