diff --git a/arch/cris/arch-v10/drivers/ide.c b/arch/cris/arch-v10/drivers/ide.c
index 473e4d1332020e933cc1dad4ea7d19ad2011910f..cd97e6f9071c1dbceef2b6bb0853e3181939979d 100644
--- a/arch/cris/arch-v10/drivers/ide.c
+++ b/arch/cris/arch-v10/drivers/ide.c
@@ -656,15 +656,9 @@ static int e100_ide_build_dmatable (ide_drive_t *drive)
 
 	ata_tot_size = 0;
 
-	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
-		sg_init_one(&sg[0], rq->buffer, rq->nr_sectors * SECTOR_SIZE);
-		hwif->sg_nents = i = 1;
-	}
-	else
-	{
-		hwif->sg_nents = i = blk_rq_map_sg(drive->queue, rq, hwif->sg_table);
-	}
+	ide_map_sg(drive, rq);
 
+	i = hwif->sg_nents;
 
 	while(i) {
 		/*
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index a24120ef0c6b4c7a2848a14333343253122f29e1..dc08dcc6e698b852a94698875c643e81f0291637 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -212,33 +212,18 @@ static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
 	ide_hwif_t *hwif = drive->hwif;
 	struct icside_state *state = hwif->hwif_data;
 	struct scatterlist *sg = hwif->sg_table;
-	int nents;
 
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
+	ide_map_sg(drive, rq);
 
-		if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
-			hwif->sg_dma_direction = DMA_TO_DEVICE;
-		else
-			hwif->sg_dma_direction = DMA_FROM_DEVICE;
-
-		sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
-		nents = 1;
-	} else {
-		nents = blk_rq_map_sg(drive->queue, rq, sg);
-
-		if (rq_data_dir(rq) == READ)
-			hwif->sg_dma_direction = DMA_FROM_DEVICE;
-		else
-			hwif->sg_dma_direction = DMA_TO_DEVICE;
-	}
-
-	nents = dma_map_sg(state->dev, sg, nents, hwif->sg_dma_direction);
+	if (rq_data_dir(rq) == READ)
+		hwif->sg_dma_direction = DMA_FROM_DEVICE;
+	else
+		hwif->sg_dma_direction = DMA_TO_DEVICE;
 
-	hwif->sg_nents = nents;
+	hwif->sg_nents = dma_map_sg(state->dev, sg, hwif->sg_nents,
+				    hwif->sg_dma_direction);
 }
 
-
 /*
  * Configure the IOMD to give the appropriate timings for the transfer
  * mode being requested.  We take the advice of the ATA standards, and
@@ -498,14 +483,6 @@ static int icside_dma_test_irq(ide_drive_t *drive)
 			ICS_ARCIN_V6_INTRSTAT_1)) & 1;
 }
 
-static int icside_dma_verbose(ide_drive_t *drive)
-{
-	printk(", %s (peak %dMB/s)",
-		ide_xfer_verbose(drive->current_speed),
-		2000 / drive->drive_data);
-	return 1;
-}
-
 static int icside_dma_timeout(ide_drive_t *drive)
 {
 	printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
@@ -554,7 +531,6 @@ static void icside_dma_init(ide_hwif_t *hwif)
 	hwif->dma_start		= icside_dma_start;
 	hwif->ide_dma_end	= icside_dma_end;
 	hwif->ide_dma_test_irq	= icside_dma_test_irq;
-	hwif->ide_dma_verbose	= icside_dma_verbose;
 	hwif->ide_dma_timeout	= icside_dma_timeout;
 	hwif->ide_dma_lostirq	= icside_dma_lostirq;
 
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index d6397420196271a4add976eaa70540a4f8ac9172..0f8516568457a58e5b766ba5d2474b56c8576748 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3039,10 +3039,9 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
 
 	printk(", %dkB Cache", be16_to_cpu(cap.buffer_size));
 
-#ifdef CONFIG_BLK_DEV_IDEDMA
 	if (drive->using_dma)
-		(void) HWIF(drive)->ide_dma_verbose(drive);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+		ide_dma_verbose(drive);
+
 	printk("\n");
 
 	return nslots;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 2108a97f6e30d5d1e94dddc5107ebd7a34cf852a..9599f8bcf5ab212736a7a20a2a0350541074fa87 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1244,7 +1244,7 @@ static void idedisk_setup (ide_drive_t *drive)
 	printk(", CHS=%d/%d/%d", 
 	       drive->bios_cyl, drive->bios_head, drive->bios_sect);
 	if (drive->using_dma)
-		(void) HWIF(drive)->ide_dma_verbose(drive);
+		ide_dma_verbose(drive);
 	printk("\n");
 
 	drive->mult_count = 0;
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 8157fb812d74b81d3d65632728c1d0a23afb56d2..3ee78ef9b0be69d363236cd758ee14a39c0cede2 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -207,66 +207,22 @@ int ide_build_sglist(ide_drive_t *drive, struct request *rq)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	struct scatterlist *sg = hwif->sg_table;
-	int nents;
 
-	nents = blk_rq_map_sg(drive->queue, rq, hwif->sg_table);
-		
+	if ((rq->flags & REQ_DRIVE_TASKFILE) && rq->nr_sectors > 256)
+		BUG();
+
+	ide_map_sg(drive, rq);
+
 	if (rq_data_dir(rq) == READ)
 		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
 	else
 		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
 
-	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
+	return pci_map_sg(hwif->pci_dev, sg, hwif->sg_nents, hwif->sg_dma_direction);
 }
 
 EXPORT_SYMBOL_GPL(ide_build_sglist);
 
-/**
- *	ide_raw_build_sglist	-	map IDE scatter gather for DMA
- *	@drive: the drive to build the DMA table for
- *	@rq: the request holding the sg list
- *
- *	Perform the PCI mapping magic necessary to access the source or
- *	target buffers of a taskfile request via PCI DMA. The lower layers 
- *	of the  kernel provide the necessary cache management so that we can
- *	operate in a portable fashion
- */
-
-int ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	struct scatterlist *sg = hwif->sg_table;
-	int nents = 0;
-	ide_task_t *args = rq->special;
-	u8 *virt_addr = rq->buffer;
-	int sector_count = rq->nr_sectors;
-
-	if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
-		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
-	else
-		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-
-#if 1
-	if (sector_count > 256)
-		BUG();
-
-	if (sector_count > 128) {
-#else
-	while (sector_count > 128) {
-#endif
-		sg_init_one(&sg[nents], virt_addr, 128 * SECTOR_SIZE);
-		nents++;
-		virt_addr = virt_addr + (128 * SECTOR_SIZE);
-		sector_count -= 128;
-	}
-	sg_init_one(&sg[nents], virt_addr, sector_count * SECTOR_SIZE);
-	nents++;
-
-	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
-}
-
-EXPORT_SYMBOL_GPL(ide_raw_build_sglist);
-
 /**
  *	ide_build_dmatable	-	build IDE DMA table
  *
@@ -288,10 +244,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
 	int i;
 	struct scatterlist *sg;
 
-	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
-		hwif->sg_nents = i = ide_raw_build_sglist(drive, rq);
-	else
-		hwif->sg_nents = i = ide_build_sglist(drive, rq);
+	hwif->sg_nents = i = ide_build_sglist(drive, rq);
 
 	if (!i)
 		return 0;
@@ -728,17 +681,14 @@ int __ide_dma_good_drive (ide_drive_t *drive)
 
 EXPORT_SYMBOL(__ide_dma_good_drive);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
-int __ide_dma_verbose (ide_drive_t *drive)
+void ide_dma_verbose(ide_drive_t *drive)
 {
 	struct hd_driveid *id	= drive->id;
 	ide_hwif_t *hwif	= HWIF(drive);
 
 	if (id->field_valid & 4) {
-		if ((id->dma_ultra >> 8) && (id->dma_mword >> 8)) {
-			printk(", BUG DMA OFF");
-			return hwif->ide_dma_off_quietly(drive);
-		}
+		if ((id->dma_ultra >> 8) && (id->dma_mword >> 8))
+			goto bug_dma_off;
 		if (id->dma_ultra & ((id->dma_ultra >> 8) & hwif->ultra_mask)) {
 			if (((id->dma_ultra >> 11) & 0x1F) &&
 			    eighty_ninty_three(drive)) {
@@ -768,19 +718,22 @@ int __ide_dma_verbose (ide_drive_t *drive)
 			printk(", (U)DMA");	/* Can be BIOS-enabled! */
 		}
 	} else if (id->field_valid & 2) {
-		if ((id->dma_mword >> 8) && (id->dma_1word >> 8)) {
-			printk(", BUG DMA OFF");
-			return hwif->ide_dma_off_quietly(drive);
-		}
+		if ((id->dma_mword >> 8) && (id->dma_1word >> 8))
+			goto bug_dma_off;
 		printk(", DMA");
 	} else if (id->field_valid & 1) {
 		printk(", BUG");
 	}
-	return 1;
+	return;
+bug_dma_off:
+	printk(", BUG DMA OFF");
+	hwif->ide_dma_off_quietly(drive);
+	return;
 }
 
-EXPORT_SYMBOL(__ide_dma_verbose);
+EXPORT_SYMBOL(ide_dma_verbose);
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 int __ide_dma_lostirq (ide_drive_t *drive)
 {
 	printk("%s: DMA interrupt recovery\n", drive->name);
@@ -955,8 +908,6 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
 		hwif->ide_dma_end = &__ide_dma_end;
 	if (!hwif->ide_dma_test_irq)
 		hwif->ide_dma_test_irq = &__ide_dma_test_irq;
-	if (!hwif->ide_dma_verbose)
-		hwif->ide_dma_verbose = &__ide_dma_verbose;
 	if (!hwif->ide_dma_timeout)
 		hwif->ide_dma_timeout = &__ide_dma_timeout;
 	if (!hwif->ide_dma_lostirq)
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index d05160722f7381c087c5eca178ac2723bbdfa3c3..ebb9280daa83abc71036e0ba78780c34cfd99514 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -680,6 +680,9 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq)
 	ide_hwif_t *hwif = drive->hwif;
 	struct scatterlist *sg = hwif->sg_table;
 
+	if (hwif->sg_mapped)	/* needed by ide-scsi */
+		return;
+
 	if ((rq->flags & REQ_DRIVE_TASKFILE) == 0) {
 		hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
 	} else {
@@ -1219,12 +1222,15 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
 	HWGROUP(drive)->rq = NULL;
 
 	rq->errors = 0;
+
+	if (!rq->bio)
+		goto out;
+
 	rq->sector = rq->bio->bi_sector;
 	rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
 	rq->hard_cur_sectors = rq->current_nr_sectors;
-	if (rq->bio)
-		rq->buffer = NULL;
-
+	rq->buffer = NULL;
+out:
 	return ret;
 }
 
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 145c34930adbd54b8439d3e20d4ce5731d56f25c..1dabe2cbc4f28491d46d47c5b1acec2ec847383c 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -8,37 +8,6 @@
 /*
  * This is the /proc/ide/ filesystem implementation.
  *
- * The major reason this exists is to provide sufficient access
- * to driver and config data, such that user-mode programs can
- * be developed to handle chipset tuning for most PCI interfaces.
- * This should provide better utilities, and less kernel bloat.
- *
- * The entire pci config space for a PCI interface chipset can be
- * retrieved by just reading it.  e.g.    "cat /proc/ide3/config"
- *
- * To modify registers *safely*, do something like:
- *   echo "P40:88" >/proc/ide/ide3/config
- * That expression writes 0x88 to pci config register 0x40
- * on the chip which controls ide3.  Multiple tuples can be issued,
- * and the writes will be completed as an atomic set:
- *   echo "P40:88 P41:35 P42:00 P43:00" >/proc/ide/ide3/config
- *
- * All numbers must be specified using pairs of ascii hex digits.
- * It is important to note that these writes will be performed
- * after waiting for the IDE controller (both interfaces)
- * to be completely idle, to ensure no corruption of I/O in progress.
- *
- * Non-PCI registers can also be written, using "R" in place of "P"
- * in the above examples.  The size of the port transfer is determined
- * by the number of pairs of hex digits given for the data.  If a two
- * digit value is given, the write will be a byte operation; if four
- * digits are used, the write will be performed as a 16-bit operation;
- * and if eight digits are specified, a 32-bit "dword" write will be
- * performed.  Odd numbers of digits are not permitted.
- *
- * If there is an error *anywhere* in the string of registers/data
- * then *none* of the writes will be performed.
- *
  * Drive/Driver settings can be retrieved by reading the drive's
  * "settings" files.  e.g.    "cat /proc/ide0/hda/settings"
  * To write a new value "val" into a specific setting "name", use:
@@ -51,10 +20,6 @@
  * returned data as 256 16-bit words.  The "hdparm" utility will
  * be updated someday soon to use this mechanism.
  *
- * Feel free to develop and distribute fancy GUI configuration
- * utilities for your favorite PCI chipsets.  I'll be working on
- * one for the Promise 20246 someday soon.  -ml
- *
  */
 
 #include <linux/config.h>
@@ -74,227 +39,6 @@
 
 #include <asm/io.h>
 
-static int proc_ide_write_config(struct file *file, const char __user *buffer,
-				 unsigned long count, void *data)
-{
-	ide_hwif_t	*hwif = (ide_hwif_t *)data;
-	ide_hwgroup_t *mygroup = (ide_hwgroup_t *)(hwif->hwgroup);
-	ide_hwgroup_t *mategroup = NULL;
-	unsigned long timeout;
-	unsigned long flags;
-	const char *start = NULL, *msg = NULL;
-	struct entry { u32 val; u16 reg; u8 size; u8 pci; } *prog, *q, *r;
-	int want_pci = 0;
-	char *buf, *s;
-	int err;
-
-	if (hwif->mate && hwif->mate->hwgroup)
-		mategroup = (ide_hwgroup_t *)(hwif->mate->hwgroup);
-
-	if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
-		return -EACCES;
-
-	if (count >= PAGE_SIZE)
-		return -EINVAL;
-
-	s = buf = (char *)__get_free_page(GFP_USER);
-	if (!buf)
-		return -ENOMEM;
-
-	err = -ENOMEM;
-	q = prog = (struct entry *)__get_free_page(GFP_USER);
-	if (!prog)
-		goto out;
-
-	err = -EFAULT;
-	if (copy_from_user(buf, buffer, count))
-		goto out1;
-
-	buf[count] = '\0';
-
-	while (isspace(*s))
-		s++;
-
-	while (*s) {
-		char *p;
-		int digits;
-
-		start = s;
-
-		if ((char *)(q + 1) > (char *)prog + PAGE_SIZE) {
-			msg = "too many entries";
-			goto parse_error;
-		}
-
-		switch (*s++) {
-			case 'R':	q->pci = 0;
-					break;
-			case 'P':	q->pci = 1;
-					want_pci = 1;
-					break;
-			default:	msg = "expected 'R' or 'P'";
-					goto parse_error;
-		}
-
-		q->reg = simple_strtoul(s, &p, 16);
-		digits = p - s;
-		if (!digits || digits > 4 || (q->pci && q->reg > 0xff)) {
-			msg = "bad/missing register number";
-			goto parse_error;
-		}
-		if (*p++ != ':') {
-			msg = "missing ':'";
-			goto parse_error;
-		}
-		q->val = simple_strtoul(p, &s, 16);
-		digits = s - p;
-		if (digits != 2 && digits != 4 && digits != 8) {
-			msg = "bad data, 2/4/8 digits required";
-			goto parse_error;
-		}
-		q->size = digits / 2;
-
-		if (q->pci) {
-#ifdef CONFIG_BLK_DEV_IDEPCI
-			if (q->reg & (q->size - 1)) {
-				msg = "misaligned access";
-				goto parse_error;
-			}
-#else
-			msg = "not a PCI device";
-			goto parse_error;
-#endif	/* CONFIG_BLK_DEV_IDEPCI */
-		}
-
-		q++;
-
-		if (*s && !isspace(*s++)) {
-			msg = "expected whitespace after data";
-			goto parse_error;
-		}
-		while (isspace(*s))
-			s++;
-	}
-
-	/*
-	 * What follows below is fucking insane, even for IDE people.
-	 * For now I've dealt with the obvious problems on the parsing
-	 * side, but IMNSHO we should simply remove the write access
-	 * to /proc/ide/.../config, killing that FPOS completely.
-	 */
-
-	err = -EBUSY;
-	timeout = jiffies + (3 * HZ);
-	spin_lock_irqsave(&ide_lock, flags);
-	while (mygroup->busy ||
-	       (mategroup && mategroup->busy)) {
-		spin_unlock_irqrestore(&ide_lock, flags);
-		if (time_after(jiffies, timeout)) {
-			printk("/proc/ide/%s/config: channel(s) busy, cannot write\n", hwif->name);
-			goto out1;
-		}
-		spin_lock_irqsave(&ide_lock, flags);
-	}
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
-	if (want_pci && (!hwif->pci_dev || hwif->pci_dev->vendor)) {
-		spin_unlock_irqrestore(&ide_lock, flags);
-		printk("proc_ide: PCI registers not accessible for %s\n",
-			hwif->name);
-		err = -EINVAL;
-		goto out1;
-	}
-#endif	/* CONFIG_BLK_DEV_IDEPCI */
-
-	for (r = prog; r < q; r++) {
-		unsigned int reg = r->reg, val = r->val;
-		if (r->pci) {
-#ifdef CONFIG_BLK_DEV_IDEPCI
-			int rc = 0;
-			struct pci_dev *dev = hwif->pci_dev;
-			switch (q->size) {
-				case 1:	msg = "byte";
-					rc = pci_write_config_byte(dev, reg, val);
-					break;
-				case 2:	msg = "word";
-					rc = pci_write_config_word(dev, reg, val);
-					break;
-				case 4:	msg = "dword";
-					rc = pci_write_config_dword(dev, reg, val);
-					break;
-			}
-			if (rc) {
-				spin_unlock_irqrestore(&ide_lock, flags);
-				printk("proc_ide_write_config: error writing %s at bus %02x dev %02x reg 0x%x value 0x%x\n",
-					msg, dev->bus->number, dev->devfn, reg, val);
-				printk("proc_ide_write_config: error %d\n", rc);
-				err = -EIO;
-				goto out1;
-			}
-#endif	/* CONFIG_BLK_DEV_IDEPCI */
-		} else {	/* not pci */
-			switch (r->size) {
-				case 1:	hwif->OUTB(val, reg);
-					break;
-				case 2:	hwif->OUTW(val, reg);
-					break;
-				case 4:	hwif->OUTL(val, reg);
-					break;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&ide_lock, flags);
-	err = count;
-out1:
-	free_page((unsigned long)prog);
-out:
-	free_page((unsigned long)buf);
-	return err;
-
-parse_error:
-	printk("parse error\n");
-	printk("proc_ide: error: %s: '%s'\n", msg, start);
-	err = -EINVAL;
-	goto out1;
-}
-
-static int proc_ide_read_config
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
-	char		*out = page;
-	int		len;
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
-	ide_hwif_t	*hwif = (ide_hwif_t *)data;
-	struct pci_dev	*dev = hwif->pci_dev;
-	if ((hwif->pci_dev && hwif->pci_dev->vendor) && dev && dev->bus) {
-		int reg = 0;
-
-		out += sprintf(out, "pci bus %02x device %02x vendor %04x "
-				"device %04x channel %d\n",
-			dev->bus->number, dev->devfn,
-			hwif->pci_dev->vendor, hwif->pci_dev->device,
-			hwif->channel);
-		do {
-			u8 val;
-			int rc = pci_read_config_byte(dev, reg, &val);
-			if (rc) {
-				printk("proc_ide_read_config: error %d reading"
-					" bus %02x dev %02x reg 0x%02x\n",
-					rc, dev->bus->number, dev->devfn, reg);
-				out += sprintf(out, "??%c",
-					(++reg & 0xf) ? ' ' : '\n');
-			} else
-				out += sprintf(out, "%02x%c",
-					val, (++reg & 0xf) ? ' ' : '\n');
-		} while (reg < 0x100);
-	} else
-#endif	/* CONFIG_BLK_DEV_IDEPCI */
-		out += sprintf(out, "(none)\n");
-	len = out - page;
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
-}
-
 static int proc_ide_read_imodel
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
@@ -687,7 +431,6 @@ void destroy_proc_ide_drives(ide_hwif_t *hwif)
 
 static ide_proc_entry_t hwif_entries[] = {
 	{ "channel",	S_IFREG|S_IRUGO,	proc_ide_read_channel,	NULL },
-	{ "config",	S_IFREG|S_IRUGO|S_IWUSR,proc_ide_read_config,	proc_ide_write_config },
 	{ "mate",	S_IFREG|S_IRUGO,	proc_ide_read_mate,	NULL },
 	{ "model",	S_IFREG|S_IRUGO,	proc_ide_read_imodel,	NULL },
 	{ NULL,	0, NULL, NULL }
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index fc8f056a31fd5f00f2aa81a8937c3adaa5570510..34ef6769162bc692812ea6613bd6c192311c8937 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -694,7 +694,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 	hwif->ide_dma_test_irq		= tmp_hwif->ide_dma_test_irq;
 	hwif->ide_dma_host_on		= tmp_hwif->ide_dma_host_on;
 	hwif->ide_dma_host_off		= tmp_hwif->ide_dma_host_off;
-	hwif->ide_dma_verbose		= tmp_hwif->ide_dma_verbose;
 	hwif->ide_dma_lostirq		= tmp_hwif->ide_dma_lostirq;
 	hwif->ide_dma_timeout		= tmp_hwif->ide_dma_timeout;
 
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 88ca26a2c2453fce8043eb8395861359ed9640a4..ed1ea5b7545b7981fc763f87158229b3fb3daa9f 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -331,17 +331,6 @@ sgiioc4_ide_dma_host_off(ide_drive_t * drive)
 	return 0;
 }
 
-static int
-sgiioc4_ide_dma_verbose(ide_drive_t * drive)
-{
-	if (drive->using_dma == 1)
-		printk(", UDMA(16)");
-	else
-		printk(", PIO");
-
-	return 1;
-}
-
 static int
 sgiioc4_ide_dma_lostirq(ide_drive_t * drive)
 {
@@ -501,10 +490,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
 	unsigned int count = 0, i = 1;
 	struct scatterlist *sg;
 
-	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
-		hwif->sg_nents = i = ide_raw_build_sglist(drive, rq);
-	else
-		hwif->sg_nents = i = ide_build_sglist(drive, rq);
+	hwif->sg_nents = i = ide_build_sglist(drive, rq);
 
 	if (!i)
 		return 0;	/* sglist of length Zero */
@@ -623,7 +609,6 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
 	hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
 	hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
 	hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
-	hwif->ide_dma_verbose = &sgiioc4_ide_dma_verbose;
 	hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
 	hwif->ide_dma_timeout = &__ide_dma_timeout;
 	hwif->INB = &sgiioc4_INB;
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 6c874989bb616ce6b4c974ee56264ace9bf4fd16..bdf18d67e481022a94d11abd2f44b4264048695a 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -554,12 +554,6 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
 	return 0;
 }
 
-static int siimage_mmio_ide_dma_verbose (ide_drive_t *drive)
-{
-	int temp = __ide_dma_verbose(drive);
-	return temp;
-}
-
 /**
  *	siimage_busproc		-	bus isolation ioctl
  *	@drive: drive to isolate/restore
@@ -1077,7 +1071,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
 
 	if (hwif->mmio) {
 		hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq;
-		hwif->ide_dma_verbose = &siimage_mmio_ide_dma_verbose;
 	} else {
 		hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq;
 	}
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 33a1690417706a34101a712ea914f04803413e47..1387f90575500ee1a404af5bed5109ea264b1b8e 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1559,56 +1559,6 @@ pmac_ide_probe(void)
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 
-/*
- * We build & map the sglist for a given request.
- */
-static int __pmac
-pmac_ide_build_sglist(ide_drive_t *drive, struct request *rq)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	struct scatterlist *sg = hwif->sg_table;
-	int nents;
-
-	nents = blk_rq_map_sg(drive->queue, rq, sg);
-		
-	if (rq_data_dir(rq) == READ)
-		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-	else
-		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
-
-	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
-}
-
-/*
- * Same as above but for a "raw" taskfile request
- */
-static int __pmac
-pmac_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	struct scatterlist *sg = hwif->sg_table;
-	int nents = 0;
-	ide_task_t *args = rq->special;
-	unsigned char *virt_addr = rq->buffer;
-	int sector_count = rq->nr_sectors;
-
-	if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
-		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
-	else
-		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-
-	if (sector_count > 128) {
-		sg_init_one(&sg[nents], virt_addr, 128 * SECTOR_SIZE);
-		nents++;
-		virt_addr = virt_addr + (128 * SECTOR_SIZE);
-		sector_count -= 128;
-	}
-	sg_init_one(&sg[nents], virt_addr, sector_count * SECTOR_SIZE);
-	nents++;
-
-	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
-}
-
 /*
  * pmac_ide_build_dmatable builds the DBDMA command list
  * for a transfer and sets the DBDMA channel to point to it.
@@ -1632,11 +1582,8 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
 	while (readl(&dma->status) & RUN)
 		udelay(1);
 
-	/* Build sglist */
-	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
-		hwif->sg_nents = i = pmac_ide_raw_build_sglist(drive, rq);
-	else
-		hwif->sg_nents = i = pmac_ide_build_sglist(drive, rq);
+	hwif->sg_nents = i = ide_build_sglist(drive, rq);
+
 	if (!i)
 		return 0;
 
@@ -2078,7 +2025,6 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
 	hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
 	hwif->ide_dma_host_off = &pmac_ide_dma_host_off;
 	hwif->ide_dma_host_on = &pmac_ide_dma_host_on;
-	hwif->ide_dma_verbose = &__ide_dma_verbose;
 	hwif->ide_dma_timeout = &__ide_dma_timeout;
 	hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
 
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index ea0527e9837e7f2596f30b53cd3a4cfc81f0e8c6..18e091a0e587c449c3fd9be968a6054b51533df9 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -45,6 +45,7 @@
 #include <linux/hdreg.h>
 #include <linux/slab.h>
 #include <linux/ide.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/bitops.h>
@@ -253,17 +254,6 @@ static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc)
 		kfree(atapi_buf);
 }
 
-static inline void idescsi_free_bio (struct bio *bio)
-{
-	struct bio *bhp;
-
-	while (bio) {
-		bhp = bio;
-		bio = bio->bi_next;
-		bio_put(bhp);
-	}
-}
-
 static void hexdump(u8 *x, int len)
 {
 	int i;
@@ -421,7 +411,6 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
 	spin_lock_irqsave(host->host_lock, flags);
 	pc->done(pc->scsi_cmd);
 	spin_unlock_irqrestore(host->host_lock, flags);
-	idescsi_free_bio(rq->bio);
 	kfree(pc);
 	kfree(rq);
 	scsi->pc = NULL;
@@ -585,6 +574,50 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
 	return ide_started;
 }
 
+static inline int idescsi_set_direction(idescsi_pc_t *pc)
+{
+	switch (pc->c[0]) {
+		case READ_6: case READ_10: case READ_12:
+			clear_bit(PC_WRITING, &pc->flags);
+			return 0;
+		case WRITE_6: case WRITE_10: case WRITE_12:
+			set_bit(PC_WRITING, &pc->flags);
+			return 0;
+		default:
+			return 1;
+	}
+}
+
+static int idescsi_map_sg(ide_drive_t *drive, idescsi_pc_t *pc)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct scatterlist *sg, *scsi_sg;
+	int segments;
+
+	if (!pc->request_transfer || pc->request_transfer % 1024)
+		return 1;
+
+	if (idescsi_set_direction(pc))
+		return 1;
+
+	sg = hwif->sg_table;
+	scsi_sg = pc->scsi_cmd->request_buffer;
+	segments = pc->scsi_cmd->use_sg;
+
+	if (segments > hwif->sg_max_nents)
+		return 1;
+
+	if (!segments) {
+		hwif->sg_nents = 1;
+		sg_init_one(sg, pc->scsi_cmd->request_buffer, pc->request_transfer);
+	} else {
+		hwif->sg_nents = segments;
+		memcpy(sg, scsi_sg, sizeof(*sg) * segments);
+	}
+
+	return 0;
+}
+
 /*
  *	Issue a packet command
  */
@@ -594,7 +627,6 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
 	ide_hwif_t *hwif = drive->hwif;
 	atapi_feature_t feature;
 	atapi_bcount_t bcount;
-	struct request *rq = pc->rq;
 
 	scsi->pc=pc;							/* Set the current packet command */
 	pc->actually_transferred=0;					/* We haven't transferred any data yet */
@@ -602,8 +634,11 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
 	bcount.all = min(pc->request_transfer, 63 * 1024);		/* Request to transfer the entire buffer at once */
 
 	feature.all = 0;
-	if (drive->using_dma && rq->bio)
+	if (drive->using_dma && !idescsi_map_sg(drive, pc)) {
+		hwif->sg_mapped = 1;
 		feature.b.dma = !hwif->dma_setup(drive);
+		hwif->sg_mapped = 0;
+	}
 
 	SELECT_DRIVE(drive);
 	if (IDE_CONTROL_REG)
@@ -775,81 +810,6 @@ static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg)
 	return -EINVAL;
 }
 
-static inline struct bio *idescsi_kmalloc_bio (int count)
-{
-	struct bio *bh, *bhp, *first_bh;
-
-	if ((first_bh = bhp = bh = bio_alloc(GFP_ATOMIC, 1)) == NULL)
-		goto abort;
-	bio_init(bh);
-	bh->bi_vcnt = 1;
-	while (--count) {
-		if ((bh = bio_alloc(GFP_ATOMIC, 1)) == NULL)
-			goto abort;
-		bio_init(bh);
-		bh->bi_vcnt = 1;
-		bhp->bi_next = bh;
-		bhp = bh;
-		bh->bi_next = NULL;
-	}
-	return first_bh;
-abort:
-	idescsi_free_bio (first_bh);
-	return NULL;
-}
-
-static inline int idescsi_set_direction (idescsi_pc_t *pc)
-{
-	switch (pc->c[0]) {
-		case READ_6: case READ_10: case READ_12:
-			clear_bit (PC_WRITING, &pc->flags);
-			return 0;
-		case WRITE_6: case WRITE_10: case WRITE_12:
-			set_bit (PC_WRITING, &pc->flags);
-			return 0;
-		default:
-			return 1;
-	}
-}
-
-static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc)
-{
-	struct bio *bh = NULL, *first_bh = NULL;
-	int segments = pc->scsi_cmd->use_sg;
-	struct scatterlist *sg = pc->scsi_cmd->request_buffer;
-
-	if (!drive->using_dma || !pc->request_transfer || pc->request_transfer % 1024)
-		return NULL;
-	if (idescsi_set_direction(pc))
-		return NULL;
-	if (segments) {
-		if ((first_bh = bh = idescsi_kmalloc_bio (segments)) == NULL)
-			return NULL;
-#if IDESCSI_DEBUG_LOG
-		printk ("ide-scsi: %s: building DMA table, %d segments, %dkB total\n", drive->name, segments, pc->request_transfer >> 10);
-#endif /* IDESCSI_DEBUG_LOG */
-		while (segments--) {
-			bh->bi_io_vec[0].bv_page = sg->page;
-			bh->bi_io_vec[0].bv_len = sg->length;
-			bh->bi_io_vec[0].bv_offset = sg->offset;
-			bh->bi_size = sg->length;
-			bh = bh->bi_next;
-			sg++;
-		}
-	} else {
-		if ((first_bh = bh = idescsi_kmalloc_bio (1)) == NULL)
-			return NULL;
-#if IDESCSI_DEBUG_LOG
-		printk ("ide-scsi: %s: building DMA table for a single buffer (%dkB)\n", drive->name, pc->request_transfer >> 10);
-#endif /* IDESCSI_DEBUG_LOG */
-		bh->bi_io_vec[0].bv_page = virt_to_page(pc->scsi_cmd->request_buffer);
-		bh->bi_io_vec[0].bv_offset = offset_in_page(pc->scsi_cmd->request_buffer);
-		bh->bi_io_vec[0].bv_len = pc->request_transfer;
-		bh->bi_size = pc->request_transfer;
-	}
-	return first_bh;
-}
-
 static inline int should_transform(ide_drive_t *drive, struct scsi_cmnd *cmd)
 {
 	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
@@ -921,7 +881,6 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
 
 	ide_init_drive_cmd (rq);
 	rq->special = (char *) pc;
-	rq->bio = idescsi_dma_bio (drive, pc);
 	rq->flags = REQ_SPECIAL;
 	spin_unlock_irq(host->host_lock);
 	(void) ide_do_drive_cmd (drive, rq, ide_end);
@@ -975,7 +934,6 @@ static int idescsi_eh_abort (struct scsi_cmnd *cmd)
 		 */
 		printk (KERN_ERR "ide-scsi: cmd aborted!\n");
 
-		idescsi_free_bio(scsi->pc->rq->bio);
 		if (scsi->pc->rq->flags & REQ_SENSE)
 			kfree(scsi->pc->buffer);
 		kfree(scsi->pc->rq);
@@ -1024,7 +982,6 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
 	/* kill current request */
 	blkdev_dequeue_request(req);
 	end_that_request_last(req);
-	idescsi_free_bio(req->bio);
 	if (req->flags & REQ_SENSE)
 		kfree(scsi->pc->buffer);
 	kfree(scsi->pc);
diff --git a/include/linux/ide.h b/include/linux/ide.h
index f4bafe0cd0fb73796f21b1362a97c8f831a1e95e..284e9ab25aa14c16e939de5581b0c3ebec8d82de 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -874,7 +874,6 @@ typedef struct hwif_s {
 	int (*ide_dma_test_irq)(ide_drive_t *drive);
 	int (*ide_dma_host_on)(ide_drive_t *drive);
 	int (*ide_dma_host_off)(ide_drive_t *drive);
-	int (*ide_dma_verbose)(ide_drive_t *drive);
 	int (*ide_dma_lostirq)(ide_drive_t *drive);
 	int (*ide_dma_timeout)(ide_drive_t *drive);
 
@@ -938,6 +937,7 @@ typedef struct hwif_s {
 	unsigned	no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
 	unsigned	no_dsc     : 1;	/* 0 default, 1 dsc_overlap disabled */
 	unsigned	auto_poll  : 1; /* supports nop auto-poll */
+	unsigned	sg_mapped  : 1;	/* sg_table and sg_nents are ready */
 
 	struct device	gendev;
 	struct semaphore gendev_rel_sem; /* To deal with device release() */
@@ -1492,10 +1492,10 @@ void ide_init_sg_cmd(ide_drive_t *, struct request *);
 int __ide_dma_bad_drive(ide_drive_t *);
 int __ide_dma_good_drive(ide_drive_t *);
 int __ide_dma_off(ide_drive_t *);
+void ide_dma_verbose(ide_drive_t *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 extern int ide_build_sglist(ide_drive_t *, struct request *);
-extern int ide_raw_build_sglist(ide_drive_t *, struct request *);
 extern int ide_build_dmatable(ide_drive_t *, struct request *);
 extern void ide_destroy_dmatable(ide_drive_t *);
 extern ide_startstop_t ide_dma_intr(ide_drive_t *);
@@ -1511,13 +1511,13 @@ extern int ide_dma_setup(ide_drive_t *);
 extern void ide_dma_start(ide_drive_t *);
 extern int __ide_dma_end(ide_drive_t *);
 extern int __ide_dma_test_irq(ide_drive_t *);
-extern int __ide_dma_verbose(ide_drive_t *);
 extern int __ide_dma_lostirq(ide_drive_t *);
 extern int __ide_dma_timeout(ide_drive_t *);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 #else
 static inline int __ide_dma_off(ide_drive_t *drive) { return 0; }
+static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
 #ifndef CONFIG_BLK_DEV_IDEDMA_PCI