LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [git patches] IDE updates part #2
@ 2008-01-26 19:43 Bartlomiej Zolnierkiewicz
  2008-01-26 20:31 ` From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> (linux.* mail to news gateway) Frans Pop
  0 siblings, 1 reply; 7+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-01-26 19:43 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-ide, linux-kernel


IDE updates continued:

* make remaining built-in only IDE host drivers modular and cleanup ide.c
  #ifdef hell (me)

* "resurrected" fixes for HDIO_DRIVE_TASKFILE ioctl (Tejun Heo)

* unify handling of REQ_TYPE_ATA_CMD and REQ_TYPE_ATA_TASKFILE requests
  (me, heavily based on the earlier patches from Tejun Heo)

* host driver specific fixes: sl82c105, cs5520, cy82c693, atiixp and others

* the usual cleanups/fixups all over the place

All patches included in this update have been in IDE tree since at least 12th
December, got testing in -mm and (almost all) have been reviewed by Sergei
(IOW it is just another "boring" IDE update ;).


Linus, please pull from:

master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6.git/

to receive the following updates:

 Documentation/ide.txt             |   13 +--
 drivers/ide/Kconfig               |   50 +++++-----
 drivers/ide/Makefile              |   58 +++++++-----
 drivers/ide/arm/Makefile          |    4 +
 drivers/ide/arm/bast-ide.c        |    2 +-
 drivers/ide/arm/icside.c          |   23 +----
 drivers/ide/arm/ide_arm.c         |   17 +++-
 drivers/ide/arm/rapide.c          |   33 +++---
 drivers/ide/cris/Makefile         |    2 +-
 drivers/ide/cris/ide-cris.c       |   29 +++---
 drivers/ide/h8300/Makefile        |    2 +
 drivers/ide/h8300/ide-h8300.c     |   27 ++++--
 drivers/ide/ide-acpi.c            |    2 +-
 drivers/ide/ide-disk.c            |   57 +++++------
 drivers/ide/ide-dma.c             |   98 +++++++-----------
 drivers/ide/ide-generic.c         |    8 ++-
 drivers/ide/ide-io.c              |  116 +++-------------------
 drivers/ide/ide-iops.c            |   31 +++---
 drivers/ide/ide-lib.c             |   25 ++----
 drivers/ide/ide-pnp.c             |   24 +++--
 drivers/ide/ide-probe.c           |  175 +++++++++++++++------------------
 drivers/ide/ide-proc.c            |   12 ++-
 drivers/ide/ide-scan-pci.c        |  121 +++++++++++++++++++++++
 drivers/ide/ide-tape.c            |    5 +
 drivers/ide/ide-taskfile.c        |  155 +++++++++++++----------------
 drivers/ide/ide.c                 |  197 +++++++------------------------------
 drivers/ide/legacy/Makefile       |   19 +++-
 drivers/ide/legacy/ali14xx.c      |    5 +-
 drivers/ide/legacy/buddha.c       |   44 +++++----
 drivers/ide/legacy/dtc2278.c      |    5 +-
 drivers/ide/legacy/falconide.c    |   22 +++-
 drivers/ide/legacy/gayle.c        |   43 +++++---
 drivers/ide/legacy/ht6560b.c      |    5 +-
 drivers/ide/legacy/ide-cs.c       |    2 +-
 drivers/ide/legacy/ide_platform.c |   55 +++++-----
 drivers/ide/legacy/macide.c       |   52 +++++-----
 drivers/ide/legacy/q40ide.c       |   24 ++++-
 drivers/ide/legacy/qd65xx.c       |    5 +-
 drivers/ide/legacy/umc8672.c      |    5 +-
 drivers/ide/mips/au1xxx-ide.c     |   36 ++-----
 drivers/ide/mips/swarm.c          |    1 +
 drivers/ide/pci/Makefile          |    4 +
 drivers/ide/pci/atiixp.c          |   71 ++++----------
 drivers/ide/pci/cmd640.c          |   16 +++-
 drivers/ide/pci/cmd64x.c          |  114 +---------------------
 drivers/ide/pci/cs5520.c          |   19 ++---
 drivers/ide/pci/cy82c693.c        |   64 ++----------
 drivers/ide/pci/delkin_cb.c       |    2 +-
 drivers/ide/pci/hpt366.c          |   11 ++-
 drivers/ide/pci/it821x.c          |   37 +++-----
 drivers/ide/pci/pdc202xx_new.c    |   11 ++-
 drivers/ide/pci/pdc202xx_old.c    |   11 ++-
 drivers/ide/pci/sc1200.c          |    6 +-
 drivers/ide/pci/serverworks.c     |   25 +----
 drivers/ide/pci/sgiioc4.c         |   49 +++-------
 drivers/ide/pci/siimage.c         |   15 ++--
 drivers/ide/pci/sl82c105.c        |   89 ++++-------------
 drivers/ide/pci/trm290.c          |    9 +--
 drivers/ide/ppc/Makefile          |    3 +
 drivers/ide/ppc/mpc8xx.c          |   18 ++++
 drivers/ide/ppc/pmac.c            |   46 +++++----
 drivers/ide/setup-pci.c           |  151 +++++------------------------
 drivers/macintosh/mediabay.c      |    3 +-
 include/linux/blkdev.h            |    1 -
 include/linux/ide.h               |   61 +++++++-----
 65 files changed, 999 insertions(+), 1446 deletions(-)
 create mode 100644 drivers/ide/h8300/Makefile
 create mode 100644 drivers/ide/ide-scan-pci.c
 create mode 100644 drivers/ide/ppc/Makefile


Bartlomiej Zolnierkiewicz (60):
      sl82c105: program DMA/PIO timings in ->dma_start/->ide_dma_end
      sl82c105: remove no longer needed ->selectproc method
      serverworks: cleanup ->set_dma_mode method
      ide-disk: add idedisk_set_doorlock() helper
      ide: (hopefully) fix VDMA for CS5520
      cy82c693: correct DMA modes clipping
      cy82c693: add ->set_dma_mode method
      sgiioc4: add ide_toggle_bounce() calls
      icside: add ide_toggle_bounce() calls
      au1xxx-ide: add ide_toggle_bounce() calls
      ide: remove ->ide_dma_on and ->dma_off_quietly methods from ide_hwif_t
      ide-cris: fix DMA methods
      atiixp: remove ->dma_host_on and ->dma_host_off methods
      ide: move drive->using_dma check to callers of ->dma_host_on method
      ide: merge ->dma_host_{on,off} methods into ->dma_host_set method
      ide: dump taskfile HOB registers in ide_tf_load() (if DEBUG is defined)
      ide: merge ->fixup and ->quirkproc methods
      ide: don't try to unregister interfaces if 'initializing' in ide_register_hw()
      ide: kill probe_hwif_init()
      ide: fix probing for hosts with serialized or IRQ sharing interfaces
      rapide: set hwif->chipset
      swarm: set hwif->chipset
      ide: add hwif->chipset fixup to ide_device_add()
      ide: remove ideprobe_init()
      sgiioc4: always init hwif->io_ports
      ide: add ide_init_port_hw() helper
      ide: drop 'initializing' argument from ide_register_hw()
      ide: move ide_arm_init() call from init_ide_data() to ide_init()
      cmd640: fix dependency on IDE_GENERIC
      ide: fix host drivers depending on ide_generic to probe for interfaces (take 2)
      ide: make remaining built-in only IDE host drivers modular (take 2)
      au1xxx-ide: au_ide_probe() fixes
      au1xxx-ide: use ide_init_port_hw()
      ide: always use ide_std_init_ports() in setup-pci.c
      ide: use ide_init_port_hw() in setup-pci.c
      rapide: remove write-only hwif->hwif_data
      ide-pmac: use custom hwif->sg_max_nents only if DMA support is enabled
      ide: add ide_set_irq() inline helper
      ide: print banner message once per controller in m68k host drivers
      ide: move CONFIG_IDEPCI_PCIBUS_ORDER code to ide-scan-pci.c
      ide: make CONFIG_IDEPCI_PCIBUS_ORDER visible and deprecate it
      ide: add ide_busy_sleep() helper
      ide: remove broken disk byte-swapping support
      cmd64x: remove /proc/ide/cmd64x
      ide: clear HOB bit for REQ_TYPE_ATA_CMD requests in ide_end_drive_cmd()
      ide: fix final status check in task_in_intr()
      ide-tape: fix handling of non-special requests in ->end_request method
      ide: set IDE_TFLAG_IN_* flags before queuing/executing command
      ide: remove needless ->cursg clearing from task_end_request()
      ide: use rq->nr_sectors in task_end_request()
      ide: kill DATA_READY define
      ide: use wait_drive_not_busy() in drive_cmd_intr() (take 2)
      ide: initialize rq->cmd_type in ide_init_drive_cmd() callers
      ide: convert "empty" REQ_TYPE_ATA_CMD requests to use REQ_TYPE_ATA_TASKFILE
      ide: don't enable local IRQs for PIO-in in driver_cmd_intr() (take 2)
      ide: check BUSY and ERROR status bits before reading data in drive_cmd_intr()
      ide: fix final status check in drive_cmd_intr()
      ide: switch set_xfer_rate() to use REQ_TYPE_ATA_TASKFILE requests
      ide: switch ide_cmd_ioctl() to use REQ_TYPE_ATA_TASKFILE requests
      ide: remove REQ_TYPE_ATA_CMD

Olof Johansson (1):
      ide: Fix build break caused by "ide: remove ideprobe_init()"

Tejun Heo (2):
      ide: fix ->io_32bit race in ide_taskfile_ioctl()
      ide: task_end_request() fix


diff --git a/Documentation/ide.txt b/Documentation/ide.txt
index 1d50f23..94e2e3b 100644
--- a/Documentation/ide.txt
+++ b/Documentation/ide.txt
@@ -30,7 +30,7 @@
 ***
 ***  The CMD640 is also used on some Vesa Local Bus (VLB) cards, and is *NOT*
 ***  automatically detected by Linux.  For safe, reliable operation with such
-***  interfaces, one *MUST* use the "ide0=cmd640_vlb" kernel option.
+***  interfaces, one *MUST* use the "cmd640.probe_vlb" kernel option.
 ***
 ***  Use of the "serialize" option is no longer necessary.
 
@@ -244,10 +244,6 @@ Summary of ide driver parameters for kernel command line
 
  "hdx=nodma"		: disallow DMA
 
- "hdx=swapdata"		: when the drive is a disk, byte swap all data
-
- "hdx=bswap"		: same as above..........
-
  "hdx=scsi"		: the return of the ide-scsi flag, this is useful for
  			  allowing ide-floppy, ide-tape, and ide-cdrom|writers
  			  to use ide-scsi emulation on a device specific option.
@@ -292,9 +288,6 @@ The following are valid ONLY on ide0, which usually corresponds
 to the first ATA interface found on the particular host, and the defaults for
 the base,ctl ports must not be altered.
 
- "ide0=cmd640_vlb"	: *REQUIRED* for VLB cards with the CMD640 chip
-			  (not for PCI -- automatically detected)
-
  "ide=doubler"		: probe/support IDE doublers on Amiga
 
 There may be more options than shown -- use the source, Luke!
@@ -310,6 +303,10 @@ i.e. to enable probing for ALI M14xx chipsets (ali14xx host driver) use:
 * "probe" module parameter when ali14xx driver is compiled as module
   ("modprobe ali14xx probe")
 
+Also for legacy CMD640 host driver (cmd640) you need to use "probe_vlb"
+kernel paremeter to enable probing for VLB version of the chipset (PCI ones
+are detected automatically).
+
 ================================================================================
 
 IDE ATAPI streaming tape driver
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index ee01e27..64df55e 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -325,7 +325,7 @@ config BLK_DEV_PLATFORM
 	  If unsure, say N.
 
 config BLK_DEV_CMD640
-	bool "CMD640 chipset bugfix/support"
+	tristate "CMD640 chipset bugfix/support"
 	depends on X86
 	---help---
 	  The CMD-Technologies CMD640 IDE chip is used on many common 486 and
@@ -359,9 +359,8 @@ config BLK_DEV_CMD640_ENHANCED
 	  Otherwise say N.
 
 config BLK_DEV_IDEPNP
-	bool "PNP EIDE support"
+	tristate "PNP EIDE support"
 	depends on PNP
-	select IDE_GENERIC
 	help
 	  If you have a PnP (Plug and Play) compatible EIDE card and
 	  would like the kernel to automatically detect and activate
@@ -375,7 +374,19 @@ config BLK_DEV_IDEPCI
 	bool
 
 config IDEPCI_PCIBUS_ORDER
-	def_bool BLK_DEV_IDE=y && BLK_DEV_IDEPCI
+	bool "Probe IDE PCI devices in the PCI bus order (DEPRECATED)"
+	depends on BLK_DEV_IDE=y && BLK_DEV_IDEPCI
+	default y
+	help
+	  Probe IDE PCI devices in the order in which they appear on the
+	  PCI bus (i.e. 00:1f.1 PCI device before 02:01.0 PCI device)
+	  instead of the order in which IDE PCI host drivers are loaded.
+
+	  Please note that this method of assuring stable naming of
+	  IDE devices is unreliable and use other means for achieving
+	  it (i.e. udev).
+
+	  If in doubt, say N.
 
 # TODO: split it on per host driver config options (or module parameters)
 config BLK_DEV_OFFBOARD
@@ -789,7 +800,7 @@ config BLK_DEV_CELLEB
 endif
 
 config BLK_DEV_IDE_PMAC
-	bool "Builtin PowerMac IDE support"
+	tristate "Builtin PowerMac IDE support"
 	depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y
 	help
 	  This driver provides support for the built-in IDE controller on
@@ -843,8 +854,9 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
        depends on BLK_DEV_IDE_AU1XXX
 
 config IDE_ARM
-	def_bool ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
-	select IDE_GENERIC
+	tristate "ARM IDE support"
+	depends on ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
+	default y
 
 config BLK_DEV_IDE_ICSIDE
 	tristate "ICS IDE interface support"
@@ -876,10 +888,9 @@ config BLK_DEV_IDE_BAST
 	  Simtec BAST or the Thorcom VR1000
 
 config ETRAX_IDE
-	bool "ETRAX IDE support"
+	tristate "ETRAX IDE support"
 	depends on CRIS && BROKEN
 	select BLK_DEV_IDEDMA
-	select IDE_GENERIC
 	help
 	  Enables the ETRAX IDE driver.
 
@@ -911,17 +922,15 @@ config ETRAX_IDE_G27_RESET
 endchoice
 
 config IDE_H8300
-	bool "H8300 IDE support"
+	tristate "H8300 IDE support"
 	depends on H8300
-	select IDE_GENERIC
 	default y
 	help
 	  Enables the H8300 IDE driver.
 
 config BLK_DEV_GAYLE
-	bool "Amiga Gayle IDE interface support"
+	tristate "Amiga Gayle IDE interface support"
 	depends on AMIGA
-	select IDE_GENERIC
 	help
 	  This is the IDE driver for the Amiga Gayle IDE interface. It supports
 	  both the `A1200 style' and `A4000 style' of the Gayle IDE interface,
@@ -951,9 +960,8 @@ config BLK_DEV_IDEDOUBLER
 	  runtime using the "ide=doubler" kernel boot parameter.
 
 config BLK_DEV_BUDDHA
-	bool "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
+	tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
 	depends on ZORRO && EXPERIMENTAL
-	select IDE_GENERIC
 	help
 	  This is the IDE driver for the IDE interfaces on the Buddha, 
 	  Catweasel and X-Surf expansion boards.  It supports up to two interfaces 
@@ -964,9 +972,8 @@ config BLK_DEV_BUDDHA
 	  to one of its IDE interfaces.
 
 config BLK_DEV_FALCON_IDE
-	bool "Falcon IDE interface support"
+	tristate "Falcon IDE interface support"
 	depends on ATARI
-	select IDE_GENERIC
 	help
 	  This is the IDE driver for the builtin IDE interface on the Atari
 	  Falcon. Say Y if you have a Falcon and want to use IDE devices (hard
@@ -974,9 +981,8 @@ config BLK_DEV_FALCON_IDE
 	  interface.
 
 config BLK_DEV_MAC_IDE
-	bool "Macintosh Quadra/Powerbook IDE interface support"
+	tristate "Macintosh Quadra/Powerbook IDE interface support"
 	depends on MAC
-	select IDE_GENERIC
 	help
 	  This is the IDE driver for the builtin IDE interface on some m68k
 	  Macintosh models. It supports both the `Quadra style' (used in
@@ -988,18 +994,16 @@ config BLK_DEV_MAC_IDE
 	  builtin IDE interface.
 
 config BLK_DEV_Q40IDE
-	bool "Q40/Q60 IDE interface support"
+	tristate "Q40/Q60 IDE interface support"
 	depends on Q40
-	select IDE_GENERIC
 	help
 	  Enable the on-board IDE controller in the Q40/Q60.  This should
 	  normally be on; disable it only if you are running a custom hard
 	  drive subsystem through an expansion card.
 
 config BLK_DEV_MPC8xx_IDE
-	bool "MPC8xx IDE support"
+	tristate "MPC8xx IDE support"
 	depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE
-	select IDE_GENERIC
 	help
 	  This option provides support for IDE on Motorola MPC8xx Systems.
 	  Please see 'Type of MPC8xx IDE interface' for details.
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index b181fc6..0d2da89 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -7,41 +7,37 @@
 # Note : at this point, these files are compiled on all systems.
 # In the future, some of these should be built conditionally.
 #
-# First come modules that register themselves with the core
+# link order is important here
 
 EXTRA_CFLAGS				+= -Idrivers/ide
 
-obj-$(CONFIG_BLK_DEV_IDE)		+= pci/
-
 ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o
 
-ide-core-$(CONFIG_BLK_DEV_CMD640)	+= pci/cmd640.o
-
-# Core IDE code - must come before legacy
+# core IDE code
 ide-core-$(CONFIG_BLK_DEV_IDEPCI)	+= setup-pci.o
 ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
 ide-core-$(CONFIG_IDE_PROC_FS)		+= ide-proc.o
-ide-core-$(CONFIG_BLK_DEV_IDEPNP)	+= ide-pnp.o
 ide-core-$(CONFIG_BLK_DEV_IDEACPI)	+= ide-acpi.o
 
-# built-in only drivers from arm/
-ide-core-$(CONFIG_IDE_ARM)		+= arm/ide_arm.o
+obj-$(CONFIG_BLK_DEV_IDE)		+= ide-core.o
 
-# built-in only drivers from legacy/
-ide-core-$(CONFIG_BLK_DEV_BUDDHA)	+= legacy/buddha.o
-ide-core-$(CONFIG_BLK_DEV_FALCON_IDE)	+= legacy/falconide.o
-ide-core-$(CONFIG_BLK_DEV_GAYLE)	+= legacy/gayle.o
-ide-core-$(CONFIG_BLK_DEV_MAC_IDE)	+= legacy/macide.o
-ide-core-$(CONFIG_BLK_DEV_Q40IDE)	+= legacy/q40ide.o
+ifeq ($(CONFIG_IDE_ARM), y)
+	ide-arm-core-y += arm/ide_arm.o
+	obj-y += ide-arm-core.o
+endif
 
-# built-in only drivers from ppc/
-ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= ppc/mpc8xx.o
-ide-core-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ppc/pmac.o
+obj-$(CONFIG_BLK_DEV_IDE)		+= legacy/ pci/
 
-# built-in only drivers from h8300/
-ide-core-$(CONFIG_IDE_H8300)		+= h8300/ide-h8300.o
+obj-$(CONFIG_IDEPCI_PCIBUS_ORDER)	+= ide-scan-pci.o
 
-obj-$(CONFIG_BLK_DEV_IDE)		+= ide-core.o
+ifeq ($(CONFIG_BLK_DEV_CMD640), y)
+	cmd640-core-y += pci/cmd640.o
+	obj-y += cmd640-core.o
+endif
+
+obj-$(CONFIG_BLK_DEV_IDE)		+= cris/ ppc/
+obj-$(CONFIG_BLK_DEV_IDEPNP)		+= ide-pnp.o
+obj-$(CONFIG_IDE_H8300)			+= h8300/
 obj-$(CONFIG_IDE_GENERIC)		+= ide-generic.o
 
 obj-$(CONFIG_BLK_DEV_IDEDISK)		+= ide-disk.o
@@ -49,6 +45,20 @@ obj-$(CONFIG_BLK_DEV_IDECD)		+= ide-cd.o
 obj-$(CONFIG_BLK_DEV_IDETAPE)		+= ide-tape.o
 obj-$(CONFIG_BLK_DEV_IDEFLOPPY)		+= ide-floppy.o
 
-obj-$(CONFIG_BLK_DEV_IDE)		+= legacy/ arm/ mips/
-obj-$(CONFIG_BLK_DEV_HD)		+= legacy/
-obj-$(CONFIG_ETRAX_IDE)		+= cris/
+ifeq ($(CONFIG_BLK_DEV_IDECS), y)
+	ide-cs-core-y += legacy/ide-cs.o
+	obj-y += ide-cs-core.o
+endif
+
+ifeq ($(CONFIG_BLK_DEV_PLATFORM), y)
+	ide-platform-core-y += legacy/ide_platform.o
+	obj-y += ide-platform-core.o
+endif
+
+obj-$(CONFIG_BLK_DEV_IDE)		+= arm/ mips/
+
+# old hd driver must be last
+ifeq ($(CONFIG_BLK_DEV_HD), y)
+	hd-core-y += legacy/hd.o
+	obj-y += hd-core.o
+endif
diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile
index 6a78f07..5f63ad2 100644
--- a/drivers/ide/arm/Makefile
+++ b/drivers/ide/arm/Makefile
@@ -3,4 +3,8 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)	+= icside.o
 obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)	+= rapide.o
 obj-$(CONFIG_BLK_DEV_IDE_BAST)		+= bast-ide.o
 
+ifeq ($(CONFIG_IDE_ARM), m)
+	obj-m += ide_arm.o
+endif
+
 EXTRA_CFLAGS	:= -Idrivers/ide
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
index 48db616..45bf9c8 100644
--- a/drivers/ide/arm/bast-ide.c
+++ b/drivers/ide/arm/bast-ide.c
@@ -45,7 +45,7 @@ bastide_register(unsigned int base, unsigned int aux, int irq,
 	hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
 	hw.irq = irq;
 
-	ide_register_hw(&hw, NULL, 0, hwif);
+	ide_register_hw(&hw, NULL, hwif);
 
 	return 0;
 }
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index 673402f..8a5c720 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -287,26 +287,10 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
 		ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
 }
 
-static void icside_dma_host_off(ide_drive_t *drive)
+static void icside_dma_host_set(ide_drive_t *drive, int on)
 {
 }
 
-static void icside_dma_off_quietly(ide_drive_t *drive)
-{
-	drive->using_dma = 0;
-}
-
-static void icside_dma_host_on(ide_drive_t *drive)
-{
-}
-
-static int icside_dma_on(ide_drive_t *drive)
-{
-	drive->using_dma = 1;
-
-	return 0;
-}
-
 static int icside_dma_end(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
@@ -422,10 +406,7 @@ static void icside_dma_init(ide_hwif_t *hwif)
 	hwif->dmatable_dma	= 0;
 	hwif->set_dma_mode	= icside_set_dma_mode;
 
-	hwif->dma_host_off	= icside_dma_host_off;
-	hwif->dma_off_quietly	= icside_dma_off_quietly;
-	hwif->dma_host_on	= icside_dma_host_on;
-	hwif->ide_dma_on	= icside_dma_on;
+	hwif->dma_host_set	= icside_dma_host_set;
 	hwif->dma_setup		= icside_dma_setup;
 	hwif->dma_exec_cmd	= icside_dma_exec_cmd;
 	hwif->dma_start		= icside_dma_start;
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
index 8957cba..60f2497 100644
--- a/drivers/ide/arm/ide_arm.c
+++ b/drivers/ide/arm/ide_arm.c
@@ -24,12 +24,25 @@
 # define IDE_ARM_IRQ	IRQ_HARDDISK
 #endif
 
-void __init ide_arm_init(void)
+static int __init ide_arm_init(void)
 {
+	ide_hwif_t *hwif;
 	hw_regs_t hw;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	memset(&hw, 0, sizeof(hw));
 	ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206);
 	hw.irq = IDE_ARM_IRQ;
-	ide_register_hw(&hw, NULL, 1, NULL);
+
+	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	if (hwif) {
+		ide_init_port_hw(hwif, &hw);
+		idx[0] = hwif->index;
+
+		ide_device_add(idx);
+	}
+
+	return 0;
 }
+
+module_init(ide_arm_init);
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index 0775a3a..e6b56d1 100644
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -13,26 +13,18 @@
 
 #include <asm/ecard.h>
 
-static ide_hwif_t *
-rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq)
+static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base,
+			       void __iomem *ctrl, unsigned int sz, int irq)
 {
 	unsigned long port = (unsigned long)base;
-	ide_hwif_t *hwif = ide_find_port(port);
 	int i;
 
-	if (hwif == NULL)
-		goto out;
-
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hwif->io_ports[i] = port;
+		hw->io_ports[i] = port;
 		port += sz;
 	}
-	hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
-	hwif->irq = irq;
-	hwif->mmio = 1;
-	default_hwif_mmiops(hwif);
-out:
-	return hwif;
+	hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+	hw->irq = irq;
 }
 
 static int __devinit
@@ -42,6 +34,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
 	void __iomem *base;
 	int ret;
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+	hw_regs_t hw;
 
 	ret = ecard_request_resources(ec);
 	if (ret)
@@ -53,11 +46,17 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
 		goto release;
 	}
 
-	hwif = rapide_locate_hwif(base, base + 0x818, 1 << 6, ec->irq);
+	hwif = ide_find_port((unsigned long)base);
 	if (hwif) {
-		hwif->hwif_data = base;
-		hwif->gendev.parent = &ec->dev;
-		hwif->noprobe = 0;
+		memset(&hw, 0, sizeof(hw));
+		rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq);
+		hw.chipset = ide_generic;
+		hw.dev = &ec->dev;
+
+		ide_init_port_hw(hwif, &hw);
+
+		hwif->mmio = 1;
+		default_hwif_mmiops(hwif);
 
 		idx[0] = hwif->index;
 
diff --git a/drivers/ide/cris/Makefile b/drivers/ide/cris/Makefile
index 6176e8d..20b9596 100644
--- a/drivers/ide/cris/Makefile
+++ b/drivers/ide/cris/Makefile
@@ -1,3 +1,3 @@
 EXTRA_CFLAGS				+= -Idrivers/ide
 
-obj-y					+= ide-cris.o
+obj-$(CONFIG_IDE_ETRAX)			+= ide-cris.o
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 325e608..8c3294c 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -673,9 +673,8 @@ static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int);
 static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
 static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
 static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
-static int cris_dma_on (ide_drive_t *drive);
 
-static void cris_dma_off(ide_drive_t *drive)
+static void cris_dma_host_set(ide_drive_t *drive, int on)
 {
 }
 
@@ -755,13 +754,11 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
 		cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
 }
 
-void __init
-init_e100_ide (void)
+static int __init init_e100_ide(void)
 {
 	hw_regs_t hw;
-	int ide_offsets[IDE_NR_PORTS];
-	int h;
-	int i;
+	int ide_offsets[IDE_NR_PORTS], h, i;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	printk("ide: ETRAX FS built-in ATA DMA controller\n");
 
@@ -778,9 +775,11 @@ init_e100_ide (void)
 		                ide_offsets,
 		                0, 0, cris_ide_ack_intr,
 		                ide_default_irq(0));
-		ide_register_hw(&hw, NULL, 1, &hwif);
+		hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
 		if (hwif == NULL)
 			continue;
+		ide_init_port_data(hwif, hwif->index);
+		ide_init_port_hw(hwif, &hw);
 		hwif->mmio = 1;
 		hwif->chipset = ide_etrax100;
 		hwif->set_pio_mode = &cris_set_pio_mode;
@@ -789,6 +788,7 @@ init_e100_ide (void)
 		hwif->ata_output_data = &cris_ide_output_data;
 		hwif->atapi_input_bytes = &cris_atapi_input_bytes;
 		hwif->atapi_output_bytes = &cris_atapi_output_bytes;
+		hwif->dma_host_set = &cris_dma_host_set;
 		hwif->ide_dma_end = &cris_dma_end;
 		hwif->dma_setup = &cris_dma_setup;
 		hwif->dma_exec_cmd = &cris_dma_exec_cmd;
@@ -799,9 +799,6 @@ init_e100_ide (void)
 		hwif->OUTBSYNC = &cris_ide_outbsync;
 		hwif->INB = &cris_ide_inb;
 		hwif->INW = &cris_ide_inw;
-		hwif->dma_host_off = &cris_dma_off;
-		hwif->dma_host_on = &cris_dma_on;
-		hwif->dma_off_quietly = &cris_dma_off;
 		hwif->cbl = ATA_CBL_PATA40;
 		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
 		hwif->pio_mask = ATA_PIO4,
@@ -809,6 +806,8 @@ init_e100_ide (void)
 		hwif->drives[1].autotune = 1;
 		hwif->ultra_mask = cris_ultra_mask;
 		hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
+
+		idx[h] = hwif->index;
 	}
 
 	/* Reset pulse */
@@ -821,14 +820,12 @@ init_e100_ide (void)
 	cris_ide_set_speed(TYPE_PIO, ATA_PIO4_SETUP, ATA_PIO4_STROBE, ATA_PIO4_HOLD);
 	cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD);
 	cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
-}
 
-static int cris_dma_on (ide_drive_t *drive)
-{
+	ide_device_add(idx);
+
 	return 0;
 }
 
-
 static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16)));
 
 /*
@@ -1060,3 +1057,5 @@ static void cris_dma_start(ide_drive_t *drive)
 		LED_DISK_READ(1);
 	}
 }
+
+module_init(init_e100_ide);
diff --git a/drivers/ide/h8300/Makefile b/drivers/ide/h8300/Makefile
new file mode 100644
index 0000000..5eba16f
--- /dev/null
+++ b/drivers/ide/h8300/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_IDE_H8300)			+= ide-h8300.o
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index 4a49b5c..4f6d019 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -84,11 +84,12 @@ static inline void hwif_setup(ide_hwif_t *hwif)
 	hwif->INSL  = NULL;
 }
 
-void __init h8300_ide_init(void)
+static int __init h8300_ide_init(void)
 {
 	hw_regs_t hw;
 	ide_hwif_t *hwif;
-	int idx;
+	int index;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300"))
 		goto out_busy;
@@ -100,16 +101,28 @@ void __init h8300_ide_init(void)
 	hw_setup(&hw);
 
 	/* register if */
-	idx = ide_register_hw(&hw, NULL, 1, &hwif);
-	if (idx == -1) {
+	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	if (hwif == NULL) {
 		printk(KERN_ERR "ide-h8300: IDE I/F register failed\n");
-		return;
+		return -ENOENT;
 	}
 
+	index = hwif->index;
+	ide_init_port_data(hwif, index);
+	ide_init_port_hw(hwif, &hw);
 	hwif_setup(hwif);
-	printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", idx);
-	return;
+	printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", index);
+
+	idx[0] = index;
+
+	ide_device_add(idx);
+
+	return 0;
 
 out_busy:
 	printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n");
+
+	return -EBUSY;
 }
+
+module_init(h8300_ide_init);
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index e0bb0cf..e888fc3 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -386,7 +386,7 @@ static int taskfile_load_raw(ide_drive_t *drive,
 
 	/* convert gtf to IDE Taskfile */
 	memcpy(&args.tf_array[7], &gtf->tfa, 7);
-	args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 
 	if (ide_noacpitfs) {
 		DEBPRINT("_GTF execution disabled\n");
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index d8fdd86..717e114 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -201,7 +201,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
 
 	memset(&task, 0, sizeof(task));
 	task.tf_flags = IDE_TFLAG_NO_SELECT_MASK;  /* FIXME? */
-	task.tf_flags |= (IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE);
+	task.tf_flags |= (IDE_TFLAG_TF | IDE_TFLAG_DEVICE);
 
 	if (drive->select.b.lba) {
 		if (lba48) {
@@ -219,13 +219,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
 			tf->lbal   = (u8) block;
 			tf->lbam   = (u8)(block >>  8);
 			tf->lbah   = (u8)(block >> 16);
-#ifdef DEBUG
-			printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n",
-				drive->name, tf->hob_nsect, tf->nsect,
-				tf->hob_lbah, tf->hob_lbam, tf->hob_lbal,
-				tf->lbah, tf->lbam, tf->lbal);
-#endif
-			task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB);
+
+			task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
 		} else {
 			tf->nsect  = nsectors & 0xff;
 			tf->lbal   = block;
@@ -319,9 +314,9 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
 	else
 		tf->command = WIN_READ_NATIVE_MAX;
 	tf->device  = ATA_LBA;
-	args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 	if (lba48)
-		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB);
+		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
 	/* submit command request */
 	ide_no_data_taskfile(drive, &args);
 
@@ -358,9 +353,9 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
 		tf->command  = WIN_SET_MAX;
 	}
 	tf->device |= ATA_LBA;
-	args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 	if (lba48)
-		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB);
+		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
 	/* submit command request */
 	ide_no_data_taskfile(drive, &args);
 	/* if OK, compute maximum address value */
@@ -500,7 +495,7 @@ static int smart_enable(ide_drive_t *drive)
 	tf->lbam    = SMART_LCYL_PASS;
 	tf->lbah    = SMART_HCYL_PASS;
 	tf->command = WIN_SMART;
-	args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 	return ide_no_data_taskfile(drive, &args);
 }
 
@@ -515,7 +510,7 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
 	tf->lbam    = SMART_LCYL_PASS;
 	tf->lbah    = SMART_HCYL_PASS;
 	tf->command = WIN_SMART;
-	args.tf_flags	= IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	args.tf_flags	= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 	args.data_phase	= TASKFILE_IN;
 	(void) smart_enable(drive);
 	return ide_raw_taskfile(drive, &args, buf, 1);
@@ -625,8 +620,10 @@ static int set_multcount(ide_drive_t *drive, int arg)
 
 	if (drive->special.b.set_multmode)
 		return -EBUSY;
+
 	ide_init_drive_cmd (&rq);
-	rq.cmd_type = REQ_TYPE_ATA_CMD;
+	rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
+
 	drive->mult_req = arg;
 	drive->special.b.set_multmode = 1;
 	(void) ide_do_drive_cmd (drive, &rq, ide_wait);
@@ -694,7 +691,7 @@ static int write_cache(ide_drive_t *drive, int arg)
 		args.tf.feature = arg ?
 			SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
 		args.tf.command = WIN_SETFEATURES;
-		args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+		args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 		err = ide_no_data_taskfile(drive, &args);
 		if (err == 0)
 			drive->wcache = arg;
@@ -714,7 +711,7 @@ static int do_idedisk_flushcache (ide_drive_t *drive)
 		args.tf.command = WIN_FLUSH_CACHE_EXT;
 	else
 		args.tf.command = WIN_FLUSH_CACHE;
-	args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 	return ide_no_data_taskfile(drive, &args);
 }
 
@@ -729,7 +726,7 @@ static int set_acoustic (ide_drive_t *drive, int arg)
 	args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM;
 	args.tf.nsect   = arg;
 	args.tf.command = WIN_SETFEATURES;
-	args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 	ide_no_data_taskfile(drive, &args);
 	drive->acoustic = arg;
 	return 0;
@@ -766,7 +763,6 @@ static void idedisk_add_settings(ide_drive_t *drive)
 	ide_add_setting(drive,	"bios_head",	SETTING_RW,	TYPE_BYTE,	0,	255,			1,	1,	&drive->bios_head,	NULL);
 	ide_add_setting(drive,	"bios_sect",	SETTING_RW,	TYPE_BYTE,	0,	63,			1,	1,	&drive->bios_sect,	NULL);
 	ide_add_setting(drive,	"address",	SETTING_RW,	TYPE_BYTE,	0,	2,			1,	1,	&drive->addressing,	set_lba_addressing);
-	ide_add_setting(drive,	"bswap",	SETTING_READ,	TYPE_BYTE,	0,	1,			1,	1,	&drive->bswap,		NULL);
 	ide_add_setting(drive,	"multcount",	SETTING_RW,	TYPE_BYTE,	0,	id->max_multsect,	1,	1,	&drive->mult_count,	set_multcount);
 	ide_add_setting(drive,	"nowerr",	SETTING_RW,	TYPE_BYTE,	0,	1,			1,	1,	&drive->nowerr,		set_nowerr);
 	ide_add_setting(drive,	"lun",		SETTING_RW,	TYPE_INT,	0,	7,			1,	1,	&drive->lun,		NULL);
@@ -975,6 +971,17 @@ static ide_driver_t idedisk_driver = {
 #endif
 };
 
+static int idedisk_set_doorlock(ide_drive_t *drive, int on)
+{
+	ide_task_t task;
+
+	memset(&task, 0, sizeof(task));
+	task.tf.command = on ? WIN_DOORLOCK : WIN_DOORUNLOCK;
+	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+	return ide_no_data_taskfile(drive, &task);
+}
+
 static int idedisk_open(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
@@ -989,17 +996,13 @@ static int idedisk_open(struct inode *inode, struct file *filp)
 	idkp->openers++;
 
 	if (drive->removable && idkp->openers == 1) {
-		ide_task_t args;
-		memset(&args, 0, sizeof(ide_task_t));
-		args.tf.command = WIN_DOORLOCK;
-		args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
 		check_disk_change(inode->i_bdev);
 		/*
 		 * Ignore the return code from door_lock,
 		 * since the open() has already succeeded,
 		 * and the door_lock is irrelevant at this point.
 		 */
-		if (drive->doorlocking && ide_no_data_taskfile(drive, &args))
+		if (drive->doorlocking && idedisk_set_doorlock(drive, 1))
 			drive->doorlocking = 0;
 	}
 	return 0;
@@ -1015,11 +1018,7 @@ static int idedisk_release(struct inode *inode, struct file *filp)
 		ide_cacheflush_p(drive);
 
 	if (drive->removable && idkp->openers == 1) {
-		ide_task_t args;
-		memset(&args, 0, sizeof(ide_task_t));
-		args.tf.command = WIN_DOORUNLOCK;
-		args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
-		if (drive->doorlocking && ide_no_data_taskfile(drive, &args))
+		if (drive->doorlocking && idedisk_set_doorlock(drive, 0))
 			drive->doorlocking = 0;
 	}
 
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 18c78ad..5bf3203 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -153,13 +153,7 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
 		if (!dma_stat) {
 			struct request *rq = HWGROUP(drive)->rq;
 
-			if (rq->rq_disk) {
-				ide_driver_t *drv;
-
-				drv = *(ide_driver_t **)rq->rq_disk->private_data;
-				drv->end_request(drive, 1, rq->nr_sectors);
-			} else
-				ide_end_request(drive, 1, rq->nr_sectors);
+			task_end_request(drive, rq, stat);
 			return ide_stopped;
 		}
 		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", 
@@ -408,23 +402,29 @@ static int dma_timer_expiry (ide_drive_t *drive)
 }
 
 /**
- *	ide_dma_host_off	-	Generic DMA kill
+ *	ide_dma_host_set	-	Enable/disable DMA on a host
  *	@drive: drive to control
  *
- *	Perform the generic IDE controller DMA off operation. This
- *	works for most IDE bus mastering controllers
+ *	Enable/disable DMA on an IDE controller following generic
+ *	bus-mastering IDE controller behaviour.
  */
 
-void ide_dma_host_off(ide_drive_t *drive)
+void ide_dma_host_set(ide_drive_t *drive, int on)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 unit			= (drive->select.b.unit & 0x01);
 	u8 dma_stat		= hwif->INB(hwif->dma_status);
 
-	hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status);
+	if (on)
+		dma_stat |= (1 << (5 + unit));
+	else
+		dma_stat &= ~(1 << (5 + unit));
+
+	hwif->OUTB(dma_stat, hwif->dma_status);
 }
 
-EXPORT_SYMBOL(ide_dma_host_off);
+EXPORT_SYMBOL_GPL(ide_dma_host_set);
+#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 /**
  *	ide_dma_off_quietly	-	Generic DMA kill
@@ -438,11 +438,10 @@ void ide_dma_off_quietly(ide_drive_t *drive)
 	drive->using_dma = 0;
 	ide_toggle_bounce(drive, 0);
 
-	drive->hwif->dma_host_off(drive);
+	drive->hwif->dma_host_set(drive, 0);
 }
 
 EXPORT_SYMBOL(ide_dma_off_quietly);
-#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 /**
  *	ide_dma_off	-	disable DMA on a device
@@ -455,52 +454,29 @@ EXPORT_SYMBOL(ide_dma_off_quietly);
 void ide_dma_off(ide_drive_t *drive)
 {
 	printk(KERN_INFO "%s: DMA disabled\n", drive->name);
-	drive->hwif->dma_off_quietly(drive);
+	ide_dma_off_quietly(drive);
 }
 
 EXPORT_SYMBOL(ide_dma_off);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
-/**
- *	ide_dma_host_on	-	Enable DMA on a host
- *	@drive: drive to enable for DMA
- *
- *	Enable DMA on an IDE controller following generic bus mastering
- *	IDE controller behaviour
- */
-
-void ide_dma_host_on(ide_drive_t *drive)
-{
-	if (drive->using_dma) {
-		ide_hwif_t *hwif	= HWIF(drive);
-		u8 unit			= (drive->select.b.unit & 0x01);
-		u8 dma_stat		= hwif->INB(hwif->dma_status);
-
-		hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status);
-	}
-}
-
-EXPORT_SYMBOL(ide_dma_host_on);
-
 /**
- *	__ide_dma_on		-	Enable DMA on a device
+ *	ide_dma_on		-	Enable DMA on a device
  *	@drive: drive to enable DMA on
  *
  *	Enable IDE DMA for a device on this IDE controller.
  */
- 
-int __ide_dma_on (ide_drive_t *drive)
+
+void ide_dma_on(ide_drive_t *drive)
 {
 	drive->using_dma = 1;
 	ide_toggle_bounce(drive, 1);
 
-	drive->hwif->dma_host_on(drive);
-
-	return 0;
+	drive->hwif->dma_host_set(drive, 1);
 }
 
-EXPORT_SYMBOL(__ide_dma_on);
+EXPORT_SYMBOL(ide_dma_on);
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *	ide_dma_setup	-	begin a DMA phase
  *	@drive: target device
@@ -755,6 +731,7 @@ EXPORT_SYMBOL_GPL(ide_find_dma_mode);
 
 static int ide_tune_dma(ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	u8 speed;
 
 	if (noautodma || drive->nodma || (drive->id->capability & 1) == 0)
@@ -767,15 +744,21 @@ static int ide_tune_dma(ide_drive_t *drive)
 	if (ide_id_dma_bug(drive))
 		return 0;
 
-	if (drive->hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
+	if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
 		return config_drive_for_dma(drive);
 
 	speed = ide_max_dma_mode(drive);
 
-	if (!speed)
-		return 0;
+	if (!speed) {
+		 /* is this really correct/needed? */
+		if ((hwif->host_flags & IDE_HFLAG_CY82C693) &&
+		    ide_dma_good_drive(drive))
+			return 1;
+		else
+			return 0;
+	}
 
-	if (drive->hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+	if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
 		return 0;
 
 	if (ide_set_dma_mode(drive, speed))
@@ -820,7 +803,6 @@ err_out:
 
 int ide_set_dma(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = drive->hwif;
 	int rc;
 
 	/*
@@ -829,13 +811,15 @@ int ide_set_dma(ide_drive_t *drive)
 	 * things, if not checked and cleared.
 	 *   PARANOIA!!!
 	 */
-	hwif->dma_off_quietly(drive);
+	ide_dma_off_quietly(drive);
 
 	rc = ide_dma_check(drive);
 	if (rc)
 		return rc;
 
-	return hwif->ide_dma_on(drive);
+	ide_dma_on(drive);
+
+	return 0;
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
@@ -972,14 +956,8 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
 	if (!(hwif->dma_prdtable))
 		hwif->dma_prdtable	= (hwif->dma_base + 4);
 
-	if (!hwif->dma_off_quietly)
-		hwif->dma_off_quietly = &ide_dma_off_quietly;
-	if (!hwif->dma_host_off)
-		hwif->dma_host_off = &ide_dma_host_off;
-	if (!hwif->ide_dma_on)
-		hwif->ide_dma_on = &__ide_dma_on;
-	if (!hwif->dma_host_on)
-		hwif->dma_host_on = &ide_dma_host_on;
+	if (!hwif->dma_host_set)
+		hwif->dma_host_set = &ide_dma_host_set;
 	if (!hwif->dma_setup)
 		hwif->dma_setup = &ide_dma_setup;
 	if (!hwif->dma_exec_cmd)
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 0f72b98..bb30c29 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -14,10 +14,16 @@
 
 static int __init ide_generic_init(void)
 {
+	u8 idx[MAX_HWIFS];
+	int i;
+
 	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
 		ide_get_lock(NULL, NULL); /* for atari only */
 
-	(void)ideprobe_init();
+	for (i = 0; i < MAX_HWIFS; i++)
+		idx[i] = ide_hwifs[i].present ? 0xff : i;
+
+	ide_device_add_all(idx);
 
 	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
 		ide_release_lock();	/* for atari only */
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 2711b5a..6f8f544 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -75,7 +75,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
 	 */
 	if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
 		drive->state = 0;
-		HWGROUP(drive)->hwif->ide_dma_on(drive);
+		ide_dma_on(drive);
 	}
 
 	if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
@@ -219,7 +219,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
 		 * we could be smarter and check for current xfer_speed
 		 * in struct drive etc...
 		 */
-		if (drive->hwif->ide_dma_on == NULL)
+		if (drive->hwif->dma_host_set == NULL)
 			break;
 		/*
 		 * TODO: respect ->using_dma setting
@@ -231,7 +231,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
 	return ide_stopped;
 
 out_do_tf:
-	args->tf_flags	 = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	args->tf_flags	 = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 	args->data_phase = TASKFILE_NO_DATA;
 	return do_rw_taskfile(drive, args);
 }
@@ -354,7 +354,6 @@ void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
  
 void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
 {
-	ide_hwif_t *hwif = HWIF(drive);
 	unsigned long flags;
 	struct request *rq;
 
@@ -362,17 +361,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
 	rq = HWGROUP(drive)->rq;
 	spin_unlock_irqrestore(&ide_lock, flags);
 
-	if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
-		u8 *args = (u8 *) rq->buffer;
-		if (rq->errors == 0)
-			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-
-		if (args) {
-			args[0] = stat;
-			args[1] = err;
-			args[2] = hwif->INB(IDE_NSECTOR_REG);
-		}
-	} else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
 		ide_task_t *args = (ide_task_t *) rq->special;
 		if (rq->errors == 0)
 			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
@@ -383,10 +372,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
 			tf->error = err;
 			tf->status = stat;
 
-			args->tf_flags |= (IDE_TFLAG_IN_TF|IDE_TFLAG_IN_DEVICE);
-			if (args->tf_flags & IDE_TFLAG_LBA48)
-				args->tf_flags |= IDE_TFLAG_IN_HOB;
-
 			ide_tf_read(drive, args);
 		}
 	} else if (blk_pm_request(rq)) {
@@ -626,42 +611,6 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
 		return __ide_abort(drive, rq);
 }
 
-/**
- *	drive_cmd_intr		- 	drive command completion interrupt
- *	@drive: drive the completion interrupt occurred on
- *
- *	drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
- *	We do any necessary data reading and then wait for the drive to
- *	go non busy. At that point we may read the error data and complete
- *	the request
- */
- 
-static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
-{
-	struct request *rq = HWGROUP(drive)->rq;
-	ide_hwif_t *hwif = HWIF(drive);
-	u8 *args = (u8 *) rq->buffer;
-	u8 stat = hwif->INB(IDE_STATUS_REG);
-	int retries = 10;
-
-	local_irq_enable_in_hardirq();
-	if (rq->cmd_type == REQ_TYPE_ATA_CMD &&
-	    (stat & DRQ_STAT) && args && args[3]) {
-		u8 io_32bit = drive->io_32bit;
-		drive->io_32bit = 0;
-		hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
-		drive->io_32bit = io_32bit;
-		while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
-			udelay(100);
-	}
-
-	if (!OK_STAT(stat, READY_STAT, BAD_STAT))
-		return ide_error(drive, "drive_cmd", stat);
-		/* calls ide_end_drive_cmd */
-	ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
-	return ide_stopped;
-}
-
 static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
 {
 	tf->nsect   = drive->sect;
@@ -710,7 +659,7 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
 		return ide_stopped;
 	}
 
-	args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
+	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
 			IDE_TFLAG_CUSTOM_HANDLER;
 
 	do_rw_taskfile(drive, &args);
@@ -787,7 +736,7 @@ static ide_startstop_t do_special (ide_drive_t *drive)
 
 			if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
 				if (keep_dma)
-					hwif->ide_dma_on(drive);
+					ide_dma_on(drive);
 			}
 		}
 
@@ -847,16 +796,9 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
 		struct request *rq)
 {
 	ide_hwif_t *hwif = HWIF(drive);
-	u8 *args = rq->buffer;
-	ide_task_t ltask;
-	struct ide_taskfile *tf = &ltask.tf;
-
-	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
-		ide_task_t *task = rq->special;
- 
-		if (task == NULL)
-			goto done;
+	ide_task_t *task = rq->special;
 
+	if (task) {
 		hwif->data_phase = task->data_phase;
 
 		switch (hwif->data_phase) {
@@ -873,33 +815,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
 		return do_rw_taskfile(drive, task);
 	}
 
-	if (args == NULL)
-		goto done;
-
-	memset(&ltask, 0, sizeof(ltask));
-	if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
-#ifdef DEBUG
-		printk("%s: DRIVE_CMD\n", drive->name);
-#endif
-		tf->feature = args[2];
-		if (args[0] == WIN_SMART) {
-			tf->nsect = args[3];
-			tf->lbal  = args[1];
-			tf->lbam  = 0x4f;
-			tf->lbah  = 0xc2;
-			ltask.tf_flags = IDE_TFLAG_OUT_TF;
-		} else {
-			tf->nsect = args[1];
-			ltask.tf_flags = IDE_TFLAG_OUT_FEATURE |
-					 IDE_TFLAG_OUT_NSECT;
-		}
- 	}
-	tf->command = args[0];
-	ide_tf_load(drive, &ltask);
-	ide_execute_command(drive, args[0], &drive_cmd_intr, WAIT_WORSTCASE, NULL);
-	return ide_started;
-
-done:
  	/*
  	 * NULL is actually a valid way of waiting for
  	 * all current requests to be flushed from the queue.
@@ -939,8 +854,7 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
 		if (rc)
 			printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
 		SELECT_DRIVE(drive);
-		if (IDE_CONTROL_REG)
-			HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
+		ide_set_irq(drive, 1);
 		rc = ide_wait_not_busy(HWIF(drive), 100000);
 		if (rc)
 			printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
@@ -1004,8 +918,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
 		if (drive->current_speed == 0xff)
 			ide_config_drive_speed(drive, drive->desired_speed);
 
-		if (rq->cmd_type == REQ_TYPE_ATA_CMD ||
-		    rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
+		if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
 			return execute_drive_cmd(drive, rq);
 		else if (blk_pm_request(rq)) {
 			struct request_pm_state *pm = rq->data;
@@ -1213,15 +1126,13 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
 		}
 	again:
 		hwif = HWIF(drive);
-		if (hwgroup->hwif->sharing_irq &&
-		    hwif != hwgroup->hwif &&
-		    hwif->io_ports[IDE_CONTROL_OFFSET]) {
+		if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif) {
 			/*
 			 * set nIEN for previous hwif, drives in the
 			 * quirk_list may not like intr setups/cleanups
 			 */
 			if (drive->quirk_list != 1)
-				hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
+				ide_set_irq(drive, 0);
 		}
 		hwgroup->hwif = hwif;
 		hwgroup->drive = drive;
@@ -1334,7 +1245,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
 	 */
 	drive->retry_pio++;
 	drive->state = DMA_PIO_RETRY;
-	hwif->dma_off_quietly(drive);
+	ide_dma_off_quietly(drive);
 
 	/*
 	 * un-busy drive etc (hwgroup->busy is cleared on return) and
@@ -1679,7 +1590,6 @@ irqreturn_t ide_intr (int irq, void *dev_id)
 void ide_init_drive_cmd (struct request *rq)
 {
 	memset(rq, 0, sizeof(*rq));
-	rq->cmd_type = REQ_TYPE_ATA_CMD;
 	rq->ref_count = 1;
 }
 
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index c97c071..e2a7e95 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -619,7 +619,7 @@ no_80w:
 int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
 {
 	if (args->tf.command == WIN_SETFEATURES &&
-	    args->tf.lbal > XFER_UDMA_2 &&
+	    args->tf.nsect > XFER_UDMA_2 &&
 	    args->tf.feature == SETFEATURES_XFER) {
 		if (eighty_ninty_three(drive) == 0) {
 			printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
@@ -639,7 +639,7 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
 int set_transfer (ide_drive_t *drive, ide_task_t *args)
 {
 	if (args->tf.command == WIN_SETFEATURES &&
-	    args->tf.lbal >= XFER_SW_DMA_0 &&
+	    args->tf.nsect >= XFER_SW_DMA_0 &&
 	    args->tf.feature == SETFEATURES_XFER &&
 	    (drive->id->dma_ultra ||
 	     drive->id->dma_mword ||
@@ -688,8 +688,7 @@ int ide_driveid_update(ide_drive_t *drive)
 	 */
 
 	SELECT_MASK(drive, 1);
-	if (IDE_CONTROL_REG)
-		hwif->OUTB(drive->ctl,IDE_CONTROL_REG);
+	ide_set_irq(drive, 1);
 	msleep(50);
 	hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG);
 	timeout = jiffies + WAIT_WORSTCASE;
@@ -742,8 +741,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 //		msleep(50);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	if (hwif->ide_dma_on)	/* check if host supports DMA */
-		hwif->dma_host_off(drive);
+	if (hwif->dma_host_set)	/* check if host supports DMA */
+		hwif->dma_host_set(drive, 0);
 #endif
 
 	/* Skip setting PIO flow-control modes on pre-EIDE drives */
@@ -772,13 +771,12 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 	SELECT_DRIVE(drive);
 	SELECT_MASK(drive, 0);
 	udelay(1);
-	if (IDE_CONTROL_REG)
-		hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
+	ide_set_irq(drive, 0);
 	hwif->OUTB(speed, IDE_NSECTOR_REG);
 	hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG);
 	hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG);
-	if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
-		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
+	if (drive->quirk_list == 2)
+		ide_set_irq(drive, 1);
 
 	error = __ide_wait_stat(drive, drive->ready_stat,
 				BUSY_STAT|DRQ_STAT|ERR_STAT,
@@ -799,10 +797,11 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 
  skip:
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	if (speed >= XFER_SW_DMA_0)
-		hwif->dma_host_on(drive);
-	else if (hwif->ide_dma_on)	/* check if host supports DMA */
-		hwif->dma_off_quietly(drive);
+	if ((speed >= XFER_SW_DMA_0 || (hwif->host_flags & IDE_HFLAG_VDMA)) &&
+	    drive->using_dma)
+		hwif->dma_host_set(drive, 1);
+	else if (hwif->dma_host_set)	/* check if host supports DMA */
+		ide_dma_off_quietly(drive);
 #endif
 
 	switch(speed) {
@@ -1012,10 +1011,10 @@ static void check_dma_crc(ide_drive_t *drive)
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (drive->crc_count) {
-		drive->hwif->dma_off_quietly(drive);
+		ide_dma_off_quietly(drive);
 		ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
 		if (drive->current_speed >= XFER_SW_DMA_0)
-			(void) HWIF(drive)->ide_dma_on(drive);
+			ide_dma_on(drive);
 	} else
 		ide_dma_off(drive);
 #endif
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index a3bd8e8..9b44fbd 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -454,8 +454,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
 static void ide_dump_opcode(ide_drive_t *drive)
 {
 	struct request *rq;
-	u8 opcode = 0;
-	int found = 0;
+	ide_task_t *task = NULL;
 
 	spin_lock(&ide_lock);
 	rq = NULL;
@@ -464,25 +463,15 @@ static void ide_dump_opcode(ide_drive_t *drive)
 	spin_unlock(&ide_lock);
 	if (!rq)
 		return;
-	if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
-		char *args = rq->buffer;
-		if (args) {
-			opcode = args[0];
-			found = 1;
-		}
-	} else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
-		ide_task_t *args = rq->special;
-		if (args) {
-			opcode = args->tf.command;
-			found = 1;
-		}
-	}
+
+	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
+		task = rq->special;
 
 	printk("ide: failed opcode was: ");
-	if (!found)
-		printk("unknown\n");
+	if (task == NULL)
+		printk(KERN_CONT "unknown\n");
 	else
-		printk("0x%02x\n", opcode);
+		printk(KERN_CONT "0x%02x\n", task->tf.command);
 }
 
 u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index e245521..cbbb0f7 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -31,7 +31,6 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
 {
 	hw_regs_t hw;
 	ide_hwif_t *hwif;
-	int index;
 
 	if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0)))
 		return -1;
@@ -41,11 +40,19 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
 				pnp_port_start(dev, 1));
 	hw.irq = pnp_irq(dev, 0);
 
-	index = ide_register_hw(&hw, NULL, 1, &hwif);
+	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	if (hwif) {
+		u8 index = hwif->index;
+		u8 idx[4] = { index, 0xff, 0xff, 0xff };
+
+		ide_init_port_data(hwif, index);
+		ide_init_port_hw(hwif, &hw);
 
-	if (index != -1) {
-	    	printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
+		printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
 		pnp_set_drvdata(dev,hwif);
+
+		ide_device_add(idx);
+
 		return 0;
 	}
 
@@ -68,12 +75,15 @@ static struct pnp_driver idepnp_driver = {
 	.remove		= idepnp_remove,
 };
 
-void __init pnpide_init(void)
+static int __init pnpide_init(void)
 {
-	pnp_register_driver(&idepnp_driver);
+	return pnp_register_driver(&idepnp_driver);
 }
 
-void __exit pnpide_exit(void)
+static void __exit pnpide_exit(void)
 {
 	pnp_unregister_driver(&idepnp_driver);
 }
+
+module_init(pnpide_init);
+module_exit(pnpide_exit);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 0379d1f..edf650b 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -235,9 +235,6 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
 	drive->media = ide_disk;
 	printk("%s DISK drive\n", (id->config == 0x848a) ? "CFA" : "ATA" );
 
-	if (hwif->quirkproc)
-		drive->quirk_list = hwif->quirkproc(drive);
-
 	return;
 
 err_misc:
@@ -353,22 +350,19 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
 	 * the irq handler isn't expecting.
 	 */
 	if (IDE_CONTROL_REG) {
-		u8 ctl = drive->ctl | 2;
 		if (!hwif->irq) {
 			autoprobe = 1;
 			cookie = probe_irq_on();
-			/* enable device irq */
-			ctl &= ~2;
 		}
-		hwif->OUTB(ctl, IDE_CONTROL_REG);
+		ide_set_irq(drive, autoprobe);
 	}
 
 	retval = actual_try_to_identify(drive, cmd);
 
 	if (autoprobe) {
 		int irq;
-		/* mask device irq */
-		hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG);
+
+		ide_set_irq(drive, 0);
 		/* clear drive IRQ */
 		(void) hwif->INB(IDE_STATUS_REG);
 		udelay(5);
@@ -388,6 +382,20 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
 	return retval;
 }
 
+static int ide_busy_sleep(ide_hwif_t *hwif)
+{
+	unsigned long timeout = jiffies + WAIT_WORSTCASE;
+	u8 stat;
+
+	do {
+		msleep(50);
+		stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+		if ((stat & BUSY_STAT) == 0)
+			return 0;
+	} while (time_before(jiffies, timeout));
+
+	return 1;
+}
 
 /**
  *	do_probe		-	probe an IDE device
@@ -456,7 +464,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
 		if ((rc == 1 && cmd == WIN_PIDENTIFY) &&
 			((drive->autotune == IDE_TUNE_DEFAULT) ||
 			(drive->autotune == IDE_TUNE_AUTO))) {
-			unsigned long timeout;
 			printk("%s: no response (status = 0x%02x), "
 				"resetting drive\n", drive->name,
 				hwif->INB(IDE_STATUS_REG));
@@ -464,10 +471,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
 			hwif->OUTB(drive->select.all, IDE_SELECT_REG);
 			msleep(50);
 			hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
-			timeout = jiffies;
-			while (((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) &&
-			       time_before(jiffies, timeout + WAIT_WORSTCASE))
-				msleep(50);
+			(void)ide_busy_sleep(hwif);
 			rc = try_to_identify(drive, cmd);
 		}
 		if (rc == 1)
@@ -495,20 +499,16 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
 static void enable_nest (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
-	unsigned long timeout;
 
 	printk("%s: enabling %s -- ", hwif->name, drive->id->model);
 	SELECT_DRIVE(drive);
 	msleep(50);
 	hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
-	timeout = jiffies + WAIT_WORSTCASE;
-	do {
-		if (time_after(jiffies, timeout)) {
-			printk("failed (timeout)\n");
-			return;
-		}
-		msleep(50);
-	} while ((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT);
+
+	if (ide_busy_sleep(hwif)) {
+		printk(KERN_CONT "failed (timeout)\n");
+		return;
+	}
 
 	msleep(50);
 
@@ -656,8 +656,7 @@ static int wait_hwif_ready(ide_hwif_t *hwif)
 		/* Ignore disks that we will not probe for later. */
 		if (!drive->noprobe || drive->present) {
 			SELECT_DRIVE(drive);
-			if (IDE_CONTROL_REG)
-				hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
+			ide_set_irq(drive, 1);
 			mdelay(2);
 			rc = ide_wait_not_busy(hwif, 35000);
 			if (rc)
@@ -676,19 +675,18 @@ out:
 
 /**
  *	ide_undecoded_slave	-	look for bad CF adapters
- *	@hwif: interface
+ *	@drive1: drive
  *
  *	Analyse the drives on the interface and attempt to decide if we
  *	have the same drive viewed twice. This occurs with crap CF adapters
  *	and PCMCIA sometimes.
  */
 
-void ide_undecoded_slave(ide_hwif_t *hwif)
+void ide_undecoded_slave(ide_drive_t *drive1)
 {
-	ide_drive_t *drive0 = &hwif->drives[0];
-	ide_drive_t *drive1 = &hwif->drives[1];
+	ide_drive_t *drive0 = &drive1->hwif->drives[0];
 
-	if (drive0->present == 0 || drive1->present == 0)
+	if ((drive1->dn & 1) == 0 || drive0->present == 0)
 		return;
 
 	/* If the models don't match they are not the same product */
@@ -791,18 +789,11 @@ static void probe_hwif(ide_hwif_t *hwif)
 		}
 	}
 	if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) {
-		unsigned long timeout = jiffies + WAIT_WORSTCASE;
-		u8 stat;
-
 		printk(KERN_WARNING "%s: reset\n", hwif->name);
 		hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
 		udelay(10);
 		hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
-		do {
-			msleep(50);
-			stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
-		} while ((stat & BUSY_STAT) && time_after(timeout, jiffies));
-
+		(void)ide_busy_sleep(hwif);
 	}
 	local_irq_restore(flags);
 	/*
@@ -817,8 +808,12 @@ static void probe_hwif(ide_hwif_t *hwif)
 		return;
 	}
 
-	if (hwif->fixup)
-		hwif->fixup(hwif);
+	for (unit = 0; unit < MAX_DRIVES; unit++) {
+		ide_drive_t *drive = &hwif->drives[unit];
+
+		if (drive->present && hwif->quirkproc)
+			hwif->quirkproc(drive);
+	}
 
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		ide_drive_t *drive = &hwif->drives[unit];
@@ -833,7 +828,7 @@ static void probe_hwif(ide_hwif_t *hwif)
 
 			drive->nice1 = 1;
 
-			if (hwif->ide_dma_on)
+			if (hwif->dma_host_set)
 				ide_set_dma(drive);
 		}
 	}
@@ -848,25 +843,6 @@ static void probe_hwif(ide_hwif_t *hwif)
 	}
 }
 
-static int hwif_init(ide_hwif_t *hwif);
-static void hwif_register_devices(ide_hwif_t *hwif);
-
-static int probe_hwif_init(ide_hwif_t *hwif)
-{
-	probe_hwif(hwif);
-
-	if (!hwif_init(hwif)) {
-		printk(KERN_INFO "%s: failed to initialize IDE interface\n",
-				 hwif->name);
-		return -1;
-	}
-
-	if (hwif->present)
-		hwif_register_devices(hwif);
-
-	return 0;
-}
-
 #if MAX_HWIFS > 1
 /*
  * save_match() is used to simplify logic in init_irq() below.
@@ -1359,54 +1335,63 @@ static void hwif_register_devices(ide_hwif_t *hwif)
 	}
 }
 
-int ideprobe_init (void)
+int ide_device_add_all(u8 *idx)
 {
-	unsigned int index;
-	int probe[MAX_HWIFS];
-
-	memset(probe, 0, MAX_HWIFS * sizeof(int));
-	for (index = 0; index < MAX_HWIFS; ++index)
-		probe[index] = !ide_hwifs[index].present;
-
-	for (index = 0; index < MAX_HWIFS; ++index)
-		if (probe[index])
-			probe_hwif(&ide_hwifs[index]);
-	for (index = 0; index < MAX_HWIFS; ++index)
-		if (probe[index])
-			hwif_init(&ide_hwifs[index]);
-	for (index = 0; index < MAX_HWIFS; ++index) {
-		if (probe[index]) {
-			ide_hwif_t *hwif = &ide_hwifs[index];
-			if (!hwif->present)
-				continue;
-			if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced)
-				hwif->chipset = ide_generic;
-			hwif_register_devices(hwif);
+	ide_hwif_t *hwif;
+	int i, rc = 0;
+
+	for (i = 0; i < MAX_HWIFS; i++) {
+		if (idx[i] == 0xff)
+			continue;
+
+		probe_hwif(&ide_hwifs[idx[i]]);
+	}
+
+	for (i = 0; i < MAX_HWIFS; i++) {
+		if (idx[i] == 0xff)
+			continue;
+
+		hwif = &ide_hwifs[idx[i]];
+
+		if (hwif_init(hwif) == 0) {
+			printk(KERN_INFO "%s: failed to initialize IDE "
+					 "interface\n", hwif->name);
+			rc = -1;
+			continue;
 		}
 	}
-	for (index = 0; index < MAX_HWIFS; ++index)
-		if (probe[index])
-			ide_proc_register_port(&ide_hwifs[index]);
-	return 0;
-}
 
-EXPORT_SYMBOL_GPL(ideprobe_init);
+	for (i = 0; i < MAX_HWIFS; i++) {
+		if (idx[i] == 0xff)
+			continue;
 
-int ide_device_add(u8 idx[4])
-{
-	int i, rc = 0;
+		hwif = &ide_hwifs[idx[i]];
 
-	for (i = 0; i < 4; i++) {
-		if (idx[i] != 0xff)
-			rc |= probe_hwif_init(&ide_hwifs[idx[i]]);
+		if (hwif->present) {
+			if (hwif->chipset == ide_unknown ||
+			    hwif->chipset == ide_forced)
+				hwif->chipset = ide_generic;
+			hwif_register_devices(hwif);
+		}
 	}
 
-	for (i = 0; i < 4; i++) {
+	for (i = 0; i < MAX_HWIFS; i++) {
 		if (idx[i] != 0xff)
 			ide_proc_register_port(&ide_hwifs[idx[i]]);
 	}
 
 	return rc;
 }
+EXPORT_SYMBOL_GPL(ide_device_add_all);
+
+int ide_device_add(u8 idx[4])
+{
+	u8 idx_all[MAX_HWIFS];
+	int i;
 
+	for (i = 0; i < MAX_HWIFS; i++)
+		idx_all[i] = (i < 4) ? idx[i] : 0xff;
+
+	return ide_device_add_all(idx_all);
+}
 EXPORT_SYMBOL_GPL(ide_device_add);
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index a4007d3..aa663e7 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -346,14 +346,20 @@ static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int va
 
 static int set_xfer_rate (ide_drive_t *drive, int arg)
 {
+	ide_task_t task;
 	int err;
 
 	if (arg < 0 || arg > 70)
 		return -EINVAL;
 
-	err = ide_wait_cmd(drive,
-			WIN_SETFEATURES, (u8) arg,
-			SETFEATURES_XFER, 0, NULL);
+	memset(&task, 0, sizeof(task));
+	task.tf.command = WIN_SETFEATURES;
+	task.tf.feature = SETFEATURES_XFER;
+	task.tf.nsect   = (u8)arg;
+	task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
+			IDE_TFLAG_IN_NSECT;
+
+	err = ide_no_data_taskfile(drive, &task);
 
 	if (!err && arg) {
 		ide_set_xfer_rate(drive, (u8) arg);
diff --git a/drivers/ide/ide-scan-pci.c b/drivers/ide/ide-scan-pci.c
new file mode 100644
index 0000000..7ffa332
--- /dev/null
+++ b/drivers/ide/ide-scan-pci.c
@@ -0,0 +1,121 @@
+/*
+ * support for probing IDE PCI devices in the PCI bus order
+ *
+ * Copyright (c) 1998-2000  Andre Hedrick <andre@linux-ide.org>
+ * Copyright (c) 1995-1998  Mark Lord
+ *
+ * May be copied or modified under the terms of the GNU General Public License
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ide.h>
+
+/*
+ *	Module interfaces
+ */
+
+static int pre_init = 1;		/* Before first ordered IDE scan */
+static LIST_HEAD(ide_pci_drivers);
+
+/*
+ *	__ide_pci_register_driver	-	attach IDE driver
+ *	@driver: pci driver
+ *	@module: owner module of the driver
+ *
+ *	Registers a driver with the IDE layer. The IDE layer arranges that
+ *	boot time setup is done in the expected device order and then
+ *	hands the controllers off to the core PCI code to do the rest of
+ *	the work.
+ *
+ *	Returns are the same as for pci_register_driver
+ */
+
+int __ide_pci_register_driver(struct pci_driver *driver, struct module *module,
+			      const char *mod_name)
+{
+	if (!pre_init)
+		return __pci_register_driver(driver, module, mod_name);
+	driver->driver.owner = module;
+	list_add_tail(&driver->node, &ide_pci_drivers);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
+
+/**
+ *	ide_scan_pcidev		-	find an IDE driver for a device
+ *	@dev: PCI device to check
+ *
+ *	Look for an IDE driver to handle the device we are considering.
+ *	This is only used during boot up to get the ordering correct. After
+ *	boot up the pci layer takes over the job.
+ */
+
+static int __init ide_scan_pcidev(struct pci_dev *dev)
+{
+	struct list_head *l;
+	struct pci_driver *d;
+
+	list_for_each(l, &ide_pci_drivers) {
+		d = list_entry(l, struct pci_driver, node);
+		if (d->id_table) {
+			const struct pci_device_id *id =
+				pci_match_id(d->id_table, dev);
+
+			if (id != NULL && d->probe(dev, id) >= 0) {
+				dev->driver = d;
+				pci_dev_get(dev);
+				return 1;
+			}
+		}
+	}
+	return 0;
+}
+
+/**
+ *	ide_scan_pcibus		-	perform the initial IDE driver scan
+ *
+ *	Perform the initial bus rather than driver ordered scan of the
+ *	PCI drivers. After this all IDE pci handling becomes standard
+ *	module ordering not traditionally ordered.
+ */
+
+int __init ide_scan_pcibus(void)
+{
+	struct pci_dev *dev = NULL;
+	struct pci_driver *d;
+	struct list_head *l, *n;
+
+	pre_init = 0;
+	if (!ide_scan_direction)
+		while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
+			ide_scan_pcidev(dev);
+	else
+		while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID,
+						     dev)))
+			ide_scan_pcidev(dev);
+
+	/*
+	 *	Hand the drivers over to the PCI layer now we
+	 *	are post init.
+	 */
+
+	list_for_each_safe(l, n, &ide_pci_drivers) {
+		list_del(l);
+		d = list_entry(l, struct pci_driver, node);
+		if (__pci_register_driver(d, d->driver.owner,
+					  d->driver.mod_name))
+			printk(KERN_ERR "%s: failed to register %s driver\n",
+					__FUNCTION__, d->driver.mod_name);
+	}
+
+	return 0;
+}
+
+static int __init ide_scan_pci(void)
+{
+	return ide_scan_pcibus();
+}
+
+module_init(ide_scan_pci);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 3cbca3f..d71a584 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1690,6 +1690,11 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
 	if (error)
 		tape->failed_pc = NULL;
 
+	if (!blk_special_request(rq)) {
+		ide_end_request(drive, uptodate, nr_sects);
+		return 0;
+	}
+
 	spin_lock_irqsave(&tape->spinlock, flags);
 
 	/* The request was a pipelined data transfer request */
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 2d63ea9..5eb6fa1 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -35,34 +35,6 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-static void ata_bswap_data (void *buffer, int wcount)
-{
-	u16 *p = buffer;
-
-	while (wcount--) {
-		*p = *p << 8 | *p >> 8; p++;
-		*p = *p << 8 | *p >> 8; p++;
-	}
-}
-
-static void taskfile_input_data(ide_drive_t *drive, void *buffer, u32 wcount)
-{
-	HWIF(drive)->ata_input_data(drive, buffer, wcount);
-	if (drive->bswap)
-		ata_bswap_data(buffer, wcount);
-}
-
-static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount)
-{
-	if (drive->bswap) {
-		ata_bswap_data(buffer, wcount);
-		HWIF(drive)->ata_output_data(drive, buffer, wcount);
-		ata_bswap_data(buffer, wcount);
-	} else {
-		HWIF(drive)->ata_output_data(drive, buffer, wcount);
-	}
-}
-
 void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
 {
 	ide_hwif_t *hwif = drive->hwif;
@@ -77,10 +49,13 @@ void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
 		"lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n",
 		drive->name, tf->feature, tf->nsect, tf->lbal,
 		tf->lbam, tf->lbah, tf->device, tf->command);
+	printk("%s: hob: nsect 0x%02x lbal 0x%02x "
+		"lbam 0x%02x lbah 0x%02x\n",
+		drive->name, tf->hob_nsect, tf->hob_lbal,
+		tf->hob_lbam, tf->hob_lbah);
 #endif
 
-	if (IDE_CONTROL_REG)
-		hwif->OUTB(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
+	ide_set_irq(drive, 1);
 
 	if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0)
 		SELECT_MASK(drive, 0);
@@ -124,7 +99,7 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
 		args.tf.command = WIN_IDENTIFY;
 	else
 		args.tf.command = WIN_PIDENTIFY;
-	args.tf_flags	= IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	args.tf_flags	= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 	args.data_phase	= TASKFILE_IN;
 	return ide_raw_taskfile(drive, &args, buf, 1);
 }
@@ -285,7 +260,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 	return ide_stopped;
 }
 
-static u8 wait_drive_not_busy(ide_drive_t *drive)
+u8 wait_drive_not_busy(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	int retries;
@@ -293,8 +268,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
 
 	/*
 	 * Last sector was transfered, wait until drive is ready.
-	 * This can take up to 10 usec, but we will wait max 1 ms
-	 * (drive_cmd_intr() waits that long).
+	 * This can take up to 10 usec, but we will wait max 1 ms.
 	 */
 	for (retries = 0; retries < 100; retries++) {
 		if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT)
@@ -349,9 +323,9 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 
 	/* do the actual data transfer */
 	if (write)
-		taskfile_output_data(drive, buf, SECTOR_WORDS);
+		hwif->ata_output_data(drive, buf, SECTOR_WORDS);
 	else
-		taskfile_input_data(drive, buf, SECTOR_WORDS);
+		hwif->ata_input_data(drive, buf, SECTOR_WORDS);
 
 	kunmap_atomic(buf, KM_BIO_SRC_IRQ);
 #ifdef CONFIG_HIGHMEM
@@ -371,9 +345,18 @@ static void ide_pio_multi(ide_drive_t *drive, unsigned int write)
 static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
 				     unsigned int write)
 {
+	u8 saved_io_32bit = drive->io_32bit;
+
 	if (rq->bio)	/* fs request */
 		rq->errors = 0;
 
+	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+		ide_task_t *task = rq->special;
+
+		if (task->tf_flags & IDE_TFLAG_IO_16BIT)
+			drive->io_32bit = 0;
+	}
+
 	touch_softlockup_watchdog();
 
 	switch (drive->hwif->data_phase) {
@@ -385,6 +368,8 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
 		ide_pio_sector(drive, write);
 		break;
 	}
+
+	drive->io_32bit = saved_io_32bit;
 }
 
 static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
@@ -422,27 +407,22 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
 	return ide_error(drive, s, stat);
 }
 
-static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
+void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
 {
-	HWIF(drive)->cursg = NULL;
-
 	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
-		ide_task_t *task = rq->special;
+		u8 err = drive->hwif->INB(IDE_ERROR_REG);
 
-		if (task->tf_flags & IDE_TFLAG_FLAGGED) {
-			u8 err = drive->hwif->INB(IDE_ERROR_REG);
-			ide_end_drive_cmd(drive, stat, err);
-			return;
-		}
+		ide_end_drive_cmd(drive, stat, err);
+		return;
 	}
 
 	if (rq->rq_disk) {
 		ide_driver_t *drv;
 
 		drv = *(ide_driver_t **)rq->rq_disk->private_data;;
-		drv->end_request(drive, 1, rq->hard_nr_sectors);
+		drv->end_request(drive, 1, rq->nr_sectors);
 	} else
-		ide_end_request(drive, 1, rq->hard_nr_sectors);
+		ide_end_request(drive, 1, rq->nr_sectors);
 }
 
 /*
@@ -455,7 +435,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
 	u8 stat = hwif->INB(IDE_STATUS_REG);
 
 	/* new way for dealing with premature shared PCI interrupts */
-	if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
+	if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
 		if (stat & (ERR_STAT | DRQ_STAT))
 			return task_error(drive, rq, __FUNCTION__, stat);
 		/* No data yet, so wait for another IRQ. */
@@ -468,7 +448,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
 	/* If it was the last datablock check status and finish transfer. */
 	if (!hwif->nleft) {
 		stat = wait_drive_not_busy(drive);
-		if (!OK_STAT(stat, 0, BAD_R_STAT))
+		if (!OK_STAT(stat, 0, BAD_STAT))
 			return task_error(drive, rq, __FUNCTION__, stat);
 		task_end_request(drive, rq, stat);
 		return ide_stopped;
@@ -512,7 +492,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
 {
 	ide_startstop_t startstop;
 
-	if (ide_wait_stat(&startstop, drive, DATA_READY,
+	if (ide_wait_stat(&startstop, drive, DRQ_STAT,
 			  drive->bad_wstat, WAIT_DRQ)) {
 		printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
 				drive->name,
@@ -580,7 +560,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 	unsigned int taskin	= 0;
 	unsigned int taskout	= 0;
 	u16 nsect		= 0;
-	u8 io_32bit		= drive->io_32bit;
 	char __user *buf = (char __user *)arg;
 
 //	printk("IDE Taskfile ...\n");
@@ -633,9 +612,10 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
 	args.data_phase = req_task->data_phase;
 
-	args.tf_flags = IDE_TFLAG_OUT_DEVICE;
+	args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
+			IDE_TFLAG_IN_TF;
 	if (drive->addressing == 1)
-		args.tf_flags |= IDE_TFLAG_LBA48;
+		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
 
 	if (req_task->out_flags.all) {
 		args.tf_flags |= IDE_TFLAG_FLAGGED;
@@ -671,7 +651,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 	if (req_task->in_flags.b.data)
 		args.tf_flags |= IDE_TFLAG_IN_DATA;
 
-	drive->io_32bit = 0;
 	switch(req_task->data_phase) {
 		case TASKFILE_MULTI_OUT:
 			if (!drive->mult_count) {
@@ -767,41 +746,24 @@ abort:
 
 //	printk("IDE Taskfile ioctl ended. rc = %i\n", err);
 
-	drive->io_32bit = io_32bit;
-
 	return err;
 }
 #endif
 
-int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
-{
-	struct request rq;
-	u8 buffer[4];
-
-	if (!buf)
-		buf = buffer;
-	memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors);
-	ide_init_drive_cmd(&rq);
-	rq.buffer = buf;
-	*buf++ = cmd;
-	*buf++ = nsect;
-	*buf++ = feature;
-	*buf++ = sectors;
-	return ide_do_drive_cmd(drive, &rq, ide_wait);
-}
-
 int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
-	int err = 0;
-	u8 args[4], *argbuf = args;
-	u8 xfer_rate = 0;
-	int argsize = 4;
+	u8 *buf = NULL;
+	int bufsize = 0, err = 0;
+	u8 args[4], xfer_rate = 0;
 	ide_task_t tfargs;
 	struct ide_taskfile *tf = &tfargs.tf;
 
 	if (NULL == (void *) arg) {
 		struct request rq;
+
 		ide_init_drive_cmd(&rq);
+		rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
+
 		return ide_do_drive_cmd(drive, &rq, ide_wait);
 	}
 
@@ -810,23 +772,39 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
 	memset(&tfargs, 0, sizeof(ide_task_t));
 	tf->feature = args[2];
-	tf->nsect   = args[3];
-	tf->lbal    = args[1];
+	if (args[0] == WIN_SMART) {
+		tf->nsect = args[3];
+		tf->lbal  = args[1];
+		tf->lbam  = 0x4f;
+		tf->lbah  = 0xc2;
+		tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
+	} else {
+		tf->nsect = args[1];
+		tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE |
+				  IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT;
+	}
 	tf->command = args[0];
+	tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA;
 
 	if (args[3]) {
-		argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
-		argbuf = kzalloc(argsize, GFP_KERNEL);
-		if (argbuf == NULL)
+		tfargs.tf_flags |= IDE_TFLAG_IO_16BIT;
+		bufsize = SECTOR_WORDS * 4 * args[3];
+		buf = kzalloc(bufsize, GFP_KERNEL);
+		if (buf == NULL)
 			return -ENOMEM;
 	}
+
 	if (set_transfer(drive, &tfargs)) {
 		xfer_rate = args[1];
 		if (ide_ata66_check(drive, &tfargs))
 			goto abort;
 	}
 
-	err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
+	err = ide_raw_taskfile(drive, &tfargs, buf, args[3]);
+
+	args[0] = tf->status;
+	args[1] = tf->error;
+	args[2] = tf->nsect;
 
 	if (!err && xfer_rate) {
 		/* active-retuning-calls future */
@@ -834,10 +812,13 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 		ide_driveid_update(drive);
 	}
 abort:
-	if (copy_to_user((void __user *)arg, argbuf, argsize))
+	if (copy_to_user((void __user *)arg, &args, 4))
 		err = -EFAULT;
-	if (argsize > 4)
-		kfree(argbuf);
+	if (buf) {
+		if (copy_to_user((void __user *)(arg + 4), buf, bufsize))
+			err = -EFAULT;
+		kfree(buf);
+	}
 	return err;
 }
 
@@ -854,7 +835,7 @@ int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 	memset(&task, 0, sizeof(task));
 	memcpy(&task.tf_array[7], &args[1], 6);
 	task.tf.command = args[0];
-	task.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 
 	err = ide_no_data_taskfile(drive, &task);
 
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index c6d4f63..97894ab 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -95,7 +95,7 @@ DEFINE_MUTEX(ide_cfg_mtx);
  __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
 
 #ifdef CONFIG_IDEPCI_PCIBUS_ORDER
-static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
+int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
 #endif
 
 int noautodma = 0;
@@ -116,7 +116,7 @@ EXPORT_SYMBOL(ide_hwifs);
 /*
  * Do not even *think* about calling this!
  */
-static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
+void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
 {
 	unsigned int unit;
 
@@ -159,6 +159,7 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
 		init_completion(&drive->gendev_rel_comp);
 	}
 }
+EXPORT_SYMBOL_GPL(ide_init_port_data);
 
 static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
 {
@@ -177,8 +178,6 @@ static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
 #endif
 }
 
-extern void ide_arm_init(void);
-
 /*
  * init_ide_data() sets reasonable default values into all fields
  * of all instances of the hwifs and drives, but only on the first call.
@@ -210,16 +209,13 @@ static void __init init_ide_data (void)
 	/* Initialise all interface structures */
 	for (index = 0; index < MAX_HWIFS; ++index) {
 		hwif = &ide_hwifs[index];
-		init_hwif_data(hwif, index);
+		ide_init_port_data(hwif, index);
 		init_hwif_default(hwif, index);
 #if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI)
 		hwif->irq =
 			ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);
 #endif
 	}
-#ifdef CONFIG_IDE_ARM
-	ide_arm_init();
-#endif
 }
 
 /**
@@ -414,8 +410,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 	hwif->cds			= tmp_hwif->cds;
 #endif
 
-	hwif->fixup			= tmp_hwif->fixup;
-
 	hwif->set_pio_mode		= tmp_hwif->set_pio_mode;
 	hwif->set_dma_mode		= tmp_hwif->set_dma_mode;
 	hwif->mdma_filter		= tmp_hwif->mdma_filter;
@@ -433,16 +427,13 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 	hwif->atapi_input_bytes		= tmp_hwif->atapi_input_bytes;
 	hwif->atapi_output_bytes	= tmp_hwif->atapi_output_bytes;
 
+	hwif->dma_host_set		= tmp_hwif->dma_host_set;
 	hwif->dma_setup			= tmp_hwif->dma_setup;
 	hwif->dma_exec_cmd		= tmp_hwif->dma_exec_cmd;
 	hwif->dma_start			= tmp_hwif->dma_start;
 	hwif->ide_dma_end		= tmp_hwif->ide_dma_end;
-	hwif->ide_dma_on		= tmp_hwif->ide_dma_on;
-	hwif->dma_off_quietly		= tmp_hwif->dma_off_quietly;
 	hwif->ide_dma_test_irq		= tmp_hwif->ide_dma_test_irq;
 	hwif->ide_dma_clear_irq		= tmp_hwif->ide_dma_clear_irq;
-	hwif->dma_host_on		= tmp_hwif->dma_host_on;
-	hwif->dma_host_off		= tmp_hwif->dma_host_off;
 	hwif->dma_lost_irq		= tmp_hwif->dma_lost_irq;
 	hwif->dma_timeout		= tmp_hwif->dma_timeout;
 
@@ -614,7 +605,7 @@ void ide_unregister(unsigned int index)
 	tmp_hwif = *hwif;
 
 	/* restore hwif data to pristine status */
-	init_hwif_data(hwif, index);
+	ide_init_port_data(hwif, index);
 	init_hwif_default(hwif, index);
 
 	ide_hwif_restore(hwif, &tmp_hwif);
@@ -680,24 +671,34 @@ void ide_setup_ports (	hw_regs_t *hw,
  */
 }
 
+void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
+{
+	memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
+	hwif->irq = hw->irq;
+	hwif->noprobe = 0;
+	hwif->chipset = hw->chipset;
+	hwif->gendev.parent = hw->dev;
+	hwif->ack_intr = hw->ack_intr;
+}
+EXPORT_SYMBOL_GPL(ide_init_port_hw);
+
 /**
  *	ide_register_hw		-	register IDE interface
  *	@hw: hardware registers
- *	@fixup: fixup function
- *	@initializing: set while initializing built-in drivers
+ *	@quirkproc: quirkproc function
  *	@hwifp: pointer to returned hwif
  *
  *	Register an IDE interface, specifying exactly the registers etc.
- *	Set init=1 iff calling before probes have taken place.
  *
  *	Returns -1 on error.
  */
 
-int ide_register_hw(hw_regs_t *hw, void (*fixup)(ide_hwif_t *),
-		    int initializing, ide_hwif_t **hwifp)
+int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
+		    ide_hwif_t **hwifp)
 {
 	int index, retry = 1;
 	ide_hwif_t *hwif;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	do {
 		for (index = 0; index < MAX_HWIFS; ++index) {
@@ -709,8 +710,7 @@ int ide_register_hw(hw_regs_t *hw, void (*fixup)(ide_hwif_t *),
 			hwif = &ide_hwifs[index];
 			if (hwif->hold)
 				continue;
-			if ((!hwif->present && !hwif->mate && !initializing) ||
-			    (!hwif->io_ports[IDE_DATA_OFFSET] && initializing))
+			if (!hwif->present && hwif->mate == NULL)
 				goto found;
 		}
 		for (index = 0; index < MAX_HWIFS; index++)
@@ -721,29 +721,23 @@ found:
 	if (hwif->present)
 		ide_unregister(index);
 	else if (!hwif->hold) {
-		init_hwif_data(hwif, index);
+		ide_init_port_data(hwif, index);
 		init_hwif_default(hwif, index);
 	}
 	if (hwif->present)
 		return -1;
-	memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
-	hwif->irq = hw->irq;
-	hwif->noprobe = 0;
-	hwif->fixup = fixup;
-	hwif->chipset = hw->chipset;
-	hwif->gendev.parent = hw->dev;
-	hwif->ack_intr = hw->ack_intr;
 
-	if (initializing == 0) {
-		u8 idx[4] = { index, 0xff, 0xff, 0xff };
+	ide_init_port_hw(hwif, hw);
+	hwif->quirkproc = quirkproc;
 
-		ide_device_add(idx);
-	}
+	idx[0] = index;
+
+	ide_device_add(idx);
 
 	if (hwifp)
 		*hwifp = hwif;
 
-	return (initializing || hwif->present) ? index : -1;
+	return hwif->present ? index : -1;
 }
 
 EXPORT_SYMBOL(ide_register_hw);
@@ -836,7 +830,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
 	if (!drive->id || !(drive->id->capability & 1))
 		goto out;
 
-	if (hwif->ide_dma_on == NULL)
+	if (hwif->dma_host_set == NULL)
 		goto out;
 
 	err = -EBUSY;
@@ -884,7 +878,10 @@ int set_pio_mode(ide_drive_t *drive, int arg)
 
 	if (drive->special.b.set_tune)
 		return -EBUSY;
+
 	ide_init_drive_cmd(&rq);
+	rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
+
 	drive->tune_req = (u8) arg;
 	drive->special.b.set_tune = 1;
 	(void) ide_do_drive_cmd(drive, &rq, ide_wait);
@@ -1066,7 +1063,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
 			ide_init_hwif_ports(&hw, (unsigned long) args[0],
 					    (unsigned long) args[1], NULL);
 			hw.irq = args[2];
-			if (ide_register_hw(&hw, NULL, 0, NULL) == -1)
+			if (ide_register_hw(&hw, NULL, NULL) == -1)
 				return -EIO;
 			return 0;
 		}
@@ -1227,26 +1224,12 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
 	return 0;	/* zero = nothing matched */
 }
 
-#ifdef CONFIG_BLK_DEV_ALI14XX
 extern int probe_ali14xx;
-extern int ali14xx_init(void);
-#endif
-#ifdef CONFIG_BLK_DEV_UMC8672
 extern int probe_umc8672;
-extern int umc8672_init(void);
-#endif
-#ifdef CONFIG_BLK_DEV_DTC2278
 extern int probe_dtc2278;
-extern int dtc2278_init(void);
-#endif
-#ifdef CONFIG_BLK_DEV_HT6560B
 extern int probe_ht6560b;
-extern int ht6560b_init(void);
-#endif
-#ifdef CONFIG_BLK_DEV_QD65XX
 extern int probe_qd65xx;
-extern int qd65xx_init(void);
-#endif
+extern int cmd640_vlb;
 
 static int __initdata is_chipset_set[MAX_HWIFS];
 
@@ -1323,7 +1306,7 @@ static int __init ide_setup(char *s)
 	if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
 		const char *hd_words[] = {
 			"none", "noprobe", "nowerr", "cdrom", "nodma",
-			"autotune", "noautotune", "minus8", "swapdata", "bswap",
+			"autotune", "noautotune", "-8", "-9", "-10",
 			"noflush", "remap", "remap63", "scsi", NULL };
 		unit = s[2] - 'a';
 		hw   = unit / MAX_DRIVES;
@@ -1359,10 +1342,6 @@ static int __init ide_setup(char *s)
 			case -7: /* "noautotune" */
 				drive->autotune = IDE_TUNE_NOAUTO;
 				goto obsolete_option;
-			case -9: /* "swapdata" */
-			case -10: /* "bswap" */
-				drive->bswap = 1;
-				goto done;
 			case -11: /* noflush */
 				drive->noflush = 1;
 				goto done;
@@ -1462,11 +1441,8 @@ static int __init ide_setup(char *s)
 #endif
 #ifdef CONFIG_BLK_DEV_CMD640
 			case -14: /* "cmd640_vlb" */
-			{
-				extern int cmd640_vlb; /* flag for cmd640.c */
 				cmd640_vlb = 1;
 				goto done;
-			}
 #endif
 #ifdef CONFIG_BLK_DEV_HT6560B
 			case -13: /* "ht6560b" */
@@ -1556,79 +1532,6 @@ done:
 	return 1;
 }
 
-extern void __init pnpide_init(void);
-extern void __exit pnpide_exit(void);
-extern void __init h8300_ide_init(void);
-
-/*
- * probe_for_hwifs() finds/initializes "known" IDE interfaces
- */
-static void __init probe_for_hwifs (void)
-{
-#ifdef CONFIG_IDEPCI_PCIBUS_ORDER
-	ide_scan_pcibus(ide_scan_direction);
-#endif
-
-#ifdef CONFIG_ETRAX_IDE
-	{
-		extern void init_e100_ide(void);
-		init_e100_ide();
-	}
-#endif /* CONFIG_ETRAX_IDE */
-#ifdef CONFIG_BLK_DEV_CMD640
-	{
-		extern void ide_probe_for_cmd640x(void);
-		ide_probe_for_cmd640x();
-	}
-#endif /* CONFIG_BLK_DEV_CMD640 */
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
-	{
-		extern int pmac_ide_probe(void);
-		(void)pmac_ide_probe();
-	}
-#endif /* CONFIG_BLK_DEV_IDE_PMAC */
-#ifdef CONFIG_BLK_DEV_GAYLE
-	{
-		extern void gayle_init(void);
-		gayle_init();
-	}
-#endif /* CONFIG_BLK_DEV_GAYLE */
-#ifdef CONFIG_BLK_DEV_FALCON_IDE
-	{
-		extern void falconide_init(void);
-		falconide_init();
-	}
-#endif /* CONFIG_BLK_DEV_FALCON_IDE */
-#ifdef CONFIG_BLK_DEV_MAC_IDE
-	{
-		extern void macide_init(void);
-		macide_init();
-	}
-#endif /* CONFIG_BLK_DEV_MAC_IDE */
-#ifdef CONFIG_BLK_DEV_Q40IDE
-	{
-		extern void q40ide_init(void);
-		q40ide_init();
-	}
-#endif /* CONFIG_BLK_DEV_Q40IDE */
-#ifdef CONFIG_BLK_DEV_BUDDHA
-	{
-		extern void buddha_init(void);
-		buddha_init();
-	}
-#endif /* CONFIG_BLK_DEV_BUDDHA */
-#ifdef CONFIG_BLK_DEV_IDEPNP
-	pnpide_init();
-#endif
-#ifdef CONFIG_H8300
-	h8300_ide_init();
-#endif
-}
-
-/*
- * Probe module
- */
-
 EXPORT_SYMBOL(ide_lock);
 
 static int ide_bus_match(struct device *dev, struct device_driver *drv)
@@ -1775,30 +1678,6 @@ static int __init ide_init(void)
 
 	proc_ide_create();
 
-#ifdef CONFIG_BLK_DEV_ALI14XX
-	if (probe_ali14xx)
-		(void)ali14xx_init();
-#endif
-#ifdef CONFIG_BLK_DEV_UMC8672
-	if (probe_umc8672)
-		(void)umc8672_init();
-#endif
-#ifdef CONFIG_BLK_DEV_DTC2278
-	if (probe_dtc2278)
-		(void)dtc2278_init();
-#endif
-#ifdef CONFIG_BLK_DEV_HT6560B
-	if (probe_ht6560b)
-		(void)ht6560b_init();
-#endif
-#ifdef CONFIG_BLK_DEV_QD65XX
-	if (probe_qd65xx)
-		(void)qd65xx_init();
-#endif
-
-	/* Probe for special PCI and other "known" interface chipsets. */
-	probe_for_hwifs();
-
 	return 0;
 }
 
@@ -1834,10 +1713,6 @@ void __exit cleanup_module (void)
 	for (index = 0; index < MAX_HWIFS; ++index)
 		ide_unregister(index);
 
-#ifdef CONFIG_BLK_DEV_IDEPNP
-	pnpide_exit();
-#endif
-
 	proc_ide_destroy();
 
 	bus_unregister(&ide_bus_type);
diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile
index 4098223..7043ec7 100644
--- a/drivers/ide/legacy/Makefile
+++ b/drivers/ide/legacy/Makefile
@@ -1,15 +1,24 @@
 
+# link order is important here
+
 obj-$(CONFIG_BLK_DEV_ALI14XX)		+= ali14xx.o
+obj-$(CONFIG_BLK_DEV_UMC8672)		+= umc8672.o
 obj-$(CONFIG_BLK_DEV_DTC2278)		+= dtc2278.o
 obj-$(CONFIG_BLK_DEV_HT6560B)		+= ht6560b.o
 obj-$(CONFIG_BLK_DEV_QD65XX)		+= qd65xx.o
-obj-$(CONFIG_BLK_DEV_UMC8672)		+= umc8672.o
 
-obj-$(CONFIG_BLK_DEV_IDECS)		+= ide-cs.o
+obj-$(CONFIG_BLK_DEV_GAYLE)		+= gayle.o
+obj-$(CONFIG_BLK_DEV_FALCON_IDE)	+= falconide.o
+obj-$(CONFIG_BLK_DEV_MAC_IDE)		+= macide.o
+obj-$(CONFIG_BLK_DEV_Q40IDE)		+= q40ide.o
+obj-$(CONFIG_BLK_DEV_BUDDHA)		+= buddha.o
 
-obj-$(CONFIG_BLK_DEV_PLATFORM)		+= ide_platform.o
+ifeq ($(CONFIG_BLK_DEV_IDECS), m)
+	obj-m += ide-cs.o
+endif
 
-# Last of all
-obj-$(CONFIG_BLK_DEV_HD)		+= hd.o
+ifeq ($(CONFIG_BLK_DEV_PLATFORM), m)
+	obj-m += ide_platform.o
+endif
 
 EXTRA_CFLAGS	:= -Idrivers/ide
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
index 38c3a6d..5ec0be4 100644
--- a/drivers/ide/legacy/ali14xx.c
+++ b/drivers/ide/legacy/ali14xx.c
@@ -231,8 +231,7 @@ int probe_ali14xx = 0;
 module_param_named(probe, probe_ali14xx, bool, 0);
 MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets");
 
-/* Can be called directly from ide.c. */
-int __init ali14xx_init(void)
+static int __init ali14xx_init(void)
 {
 	if (probe_ali14xx == 0)
 		goto out;
@@ -248,9 +247,7 @@ out:
 	return -ENODEV;
 }
 
-#ifdef MODULE
 module_init(ali14xx_init);
-#endif
 
 MODULE_AUTHOR("see local file");
 MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets");
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index 4a0be25..74d28e0 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -112,6 +112,7 @@ typedef enum BuddhaType_Enum {
     BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF
 } BuddhaType;
 
+static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" };
 
     /*
      *  Check and acknowledge the interrupt status
@@ -143,11 +144,11 @@ static int xsurf_ack_intr(ide_hwif_t *hwif)
      *  Probe for a Buddha or Catweasel IDE interface
      */
 
-void __init buddha_init(void)
+static int __init buddha_init(void)
 {
 	hw_regs_t hw;
 	ide_hwif_t *hwif;
-	int i, index;
+	int i;
 
 	struct zorro_dev *z = NULL;
 	u_long buddha_board = 0;
@@ -156,6 +157,8 @@ void __init buddha_init(void)
 
 	while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
 		unsigned long board;
+		u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+
 		if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
 			buddha_num_hwifs = BUDDHA_NUM_HWIFS;
 			type=BOARD_BUDDHA;
@@ -195,7 +198,10 @@ fail_base2:
 		/* X-Surf doesn't have this.  IRQs are always on */
 		if (type != BOARD_XSURF)
 			z_writeb(0, buddha_board+BUDDHA_IRQ_MR);
-		
+
+		printk(KERN_INFO "ide: %s IDE controller\n",
+				 buddha_board_name[type]);
+
 		for(i=0;i<buddha_num_hwifs;i++) {
 			if(type != BOARD_XSURF) {
 				ide_setup_ports(&hw, (buddha_board+buddha_bases[i]),
@@ -213,23 +219,23 @@ fail_base2:
 						IRQ_AMIGA_PORTS);
 			}	
 
-			index = ide_register_hw(&hw, NULL, 1, &hwif);
-			if (index != -1) {
+			hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+			if (hwif) {
+				u8 index = hwif->index;
+
+				ide_init_port_data(hwif, index);
+				ide_init_port_hw(hwif, &hw);
+
 				hwif->mmio = 1;
-				printk("ide%d: ", index);
-				switch(type) {
-				case BOARD_BUDDHA:
-					printk("Buddha");
-					break;
-				case BOARD_CATWEASEL:
-					printk("Catweasel");
-					break;
-				case BOARD_XSURF:
-					printk("X-Surf");
-					break;
-				}
-				printk(" IDE interface\n");	    
-			}		      
+
+				idx[i] = index;
+			}
 		}
+
+		ide_device_add(idx);
 	}
+
+	return 0;
 }
+
+module_init(buddha_init);
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c
index 24a845d..13eee6d 100644
--- a/drivers/ide/legacy/dtc2278.c
+++ b/drivers/ide/legacy/dtc2278.c
@@ -150,8 +150,7 @@ int probe_dtc2278 = 0;
 module_param_named(probe, probe_dtc2278, bool, 0);
 MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets");
 
-/* Can be called directly from ide.c. */
-int __init dtc2278_init(void)
+static int __init dtc2278_init(void)
 {
 	if (probe_dtc2278 == 0)
 		return -ENODEV;
@@ -163,9 +162,7 @@ int __init dtc2278_init(void)
 	return 0;
 }
 
-#ifdef MODULE
 module_init(dtc2278_init);
-#endif
 
 MODULE_AUTHOR("See Local File");
 MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets");
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
index 7d7936f..2860956 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -62,19 +62,31 @@ EXPORT_SYMBOL(falconide_intr_lock);
      *  Probe for a Falcon IDE interface
      */
 
-void __init falconide_init(void)
+static int __init falconide_init(void)
 {
     if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) {
 	hw_regs_t hw;
-	int index;
+
+	printk(KERN_INFO "ide: Falcon IDE controller\n");
 
 	ide_setup_ports(&hw, ATA_HD_BASE, falconide_offsets,
 			0, 0, NULL,
 //			falconide_iops,
 			IRQ_MFP_IDE);
-	index = ide_register_hw(&hw, NULL, 1, NULL);
 
-	if (index != -1)
-	    printk("ide%d: Falcon IDE interface\n", index);
+	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	if (hwif) {
+		u8 index = hwif->index;
+		u8 idx[4] = { index, 0xff, 0xff, 0xff };
+
+		ide_init_port_data(hwif, index);
+		ide_init_port_hw(hwif, &hw);
+
+		ide_device_add(idx);
+	}
     }
+
+    return 0;
 }
+
+module_init(falconide_init);
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index 53331ee..492fa04 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -110,12 +110,13 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
      *  Probe for a Gayle IDE interface (and optionally for an IDE doubler)
      */
 
-void __init gayle_init(void)
+static int __init gayle_init(void)
 {
     int a4000, i;
+    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
     if (!MACH_IS_AMIGA)
-	return;
+	return -ENODEV;
 
     if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE))
 	goto found;
@@ -125,15 +126,21 @@ void __init gayle_init(void)
 			  NULL))
 	goto found;
 #endif
-    return;
+    return -ENODEV;
 
 found:
+	printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n",
+			 a4000 ? 4000 : 1200,
+#ifdef CONFIG_BLK_DEV_IDEDOUBLER
+			 ide_doubler ? ", IDE doubler" :
+#endif
+			 "");
+
     for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
 	unsigned long base, ctrlport, irqport;
 	ide_ack_intr_t *ack_intr;
 	hw_regs_t hw;
 	ide_hwif_t *hwif;
-	int index;
 	unsigned long phys_base, res_start, res_n;
 
 	if (a4000) {
@@ -165,21 +172,23 @@ found:
 //			&gayle_iops,
 			IRQ_AMIGA_PORTS);
 
-	index = ide_register_hw(&hw, NULL, 1, &hwif);
-	if (index != -1) {
+	hwif = ide_find_port(base);
+	if (hwif) {
+	    u8 index = hwif->index;
+
+	    ide_init_port_data(hwif, index);
+	    ide_init_port_hw(hwif, &hw);
+
 	    hwif->mmio = 1;
-	    switch (i) {
-		case 0:
-		    printk("ide%d: Gayle IDE interface (A%d style)\n", index,
-			   a4000 ? 4000 : 1200);
-		    break;
-#ifdef CONFIG_BLK_DEV_IDEDOUBLER
-		case 1:
-		    printk("ide%d: IDE doubler\n", index);
-		    break;
-#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
-	    }
+
+	    idx[i] = index;
 	} else
 	    release_mem_region(res_start, res_n);
     }
+
+    ide_device_add(idx);
+
+    return 0;
 }
+
+module_init(gayle_init);
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index a4245d1..8da5031 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -307,8 +307,7 @@ int probe_ht6560b = 0;
 module_param_named(probe, probe_ht6560b, bool, 0);
 MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
 
-/* Can be called directly from ide.c. */
-int __init ht6560b_init(void)
+static int __init ht6560b_init(void)
 {
 	ide_hwif_t *hwif, *mate;
 	static u8 idx[4] = { 0, 1, 0xff, 0xff };
@@ -369,9 +368,7 @@ release_region:
 	return -ENODEV;
 }
 
-#ifdef MODULE
 module_init(ht6560b_init);
-#endif
 
 MODULE_AUTHOR("See Local File");
 MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 03715c0..f4ea15b 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -153,7 +153,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq
     hw.irq = irq;
     hw.chipset = ide_pci;
     hw.dev = &handle->dev;
-    return ide_register_hw(&hw, &ide_undecoded_slave, 0, NULL);
+    return ide_register_hw(&hw, &ide_undecoded_slave, NULL);
 }
 
 /*======================================================================
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
index 7bb79f5..69a0fb0 100644
--- a/drivers/ide/legacy/ide_platform.c
+++ b/drivers/ide/legacy/ide_platform.c
@@ -28,39 +28,27 @@ static struct {
 	int index;
 } hwif_prop;
 
-static ide_hwif_t *__devinit plat_ide_locate_hwif(void __iomem *base,
-	    void __iomem *ctrl, struct pata_platform_info *pdata, int irq,
-	    int mmio)
+static void __devinit plat_ide_setup_ports(hw_regs_t *hw,
+					   void __iomem *base,
+					   void __iomem *ctrl,
+					   struct pata_platform_info *pdata,
+					   int irq)
 {
 	unsigned long port = (unsigned long)base;
-	ide_hwif_t *hwif = ide_find_port(port);
 	int i;
 
-	if (hwif == NULL)
-		goto out;
-
-	hwif->io_ports[IDE_DATA_OFFSET] = port;
+	hw->io_ports[IDE_DATA_OFFSET] = port;
 
 	port += (1 << pdata->ioport_shift);
 	for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET;
 	     i++, port += (1 << pdata->ioport_shift))
-		hwif->io_ports[i] = port;
-
-	hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+		hw->io_ports[i] = port;
 
-	hwif->irq = irq;
+	hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
 
-	hwif->chipset = ide_generic;
+	hw->irq = irq;
 
-	if (mmio) {
-		hwif->mmio = 1;
-		default_hwif_mmiops(hwif);
-	}
-
-	hwif_prop.hwif = hwif;
-	hwif_prop.index = hwif->index;
-out:
-	return hwif;
+	hw->chipset = ide_generic;
 }
 
 static int __devinit plat_ide_probe(struct platform_device *pdev)
@@ -71,6 +59,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	int ret = 0;
 	int mmio = 0;
+	hw_regs_t hw;
 
 	pdata = pdev->dev.platform_data;
 
@@ -106,15 +95,27 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
 			res_alt->start, res_alt->end - res_alt->start + 1);
 	}
 
-	hwif = plat_ide_locate_hwif(hwif_prop.plat_ide_mapbase,
-	         hwif_prop.plat_ide_alt_mapbase, pdata, res_irq->start, mmio);
-
+	hwif = ide_find_port((unsigned long)hwif_prop.plat_ide_mapbase);
 	if (!hwif) {
 		ret = -ENODEV;
 		goto out;
 	}
-	hwif->gendev.parent = &pdev->dev;
-	hwif->noprobe = 0;
+
+	memset(&hw, 0, sizeof(hw));
+	plat_ide_setup_ports(&hw, hwif_prop.plat_ide_mapbase,
+			     hwif_prop.plat_ide_alt_mapbase,
+			     pdata, res_irq->start);
+	hw.dev = &pdev->dev;
+
+	ide_init_port_hw(hwif, &hw);
+
+	if (mmio) {
+		hwif->mmio = 1;
+		default_hwif_mmiops(hwif);
+	}
+
+	hwif_prop.hwif = hwif;
+	hwif_prop.index = hwif->index;
 
 	idx[0] = hwif->index;
 
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index 5c6aa77..782d4c7 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -77,15 +77,17 @@ int macide_ack_intr(ide_hwif_t* hwif)
 	return 0;
 }
 
+static const char *mac_ide_name[] =
+	{ "Quadra", "Powerbook", "Powerbook Baboon" };
+
 /*
  * Probe for a Macintosh IDE interface
  */
 
-void __init macide_init(void)
+static int __init macide_init(void)
 {
 	hw_regs_t hw;
 	ide_hwif_t *hwif;
-	int index = -1;
 
 	switch (macintosh_config->ide_type) {
 	case MAC_IDE_QUADRA:
@@ -93,48 +95,50 @@ void __init macide_init(void)
 				0, 0, macide_ack_intr,
 //				quadra_ide_iops,
 				IRQ_NUBUS_F);
-		index = ide_register_hw(&hw, NULL, 1, &hwif);
 		break;
 	case MAC_IDE_PB:
 		ide_setup_ports(&hw, IDE_BASE, macide_offsets,
 				0, 0, macide_ack_intr,
 //				macide_pb_iops,
 				IRQ_NUBUS_C);
-		index = ide_register_hw(&hw, NULL, 1, &hwif);
 		break;
 	case MAC_IDE_BABOON:
 		ide_setup_ports(&hw, BABOON_BASE, macide_offsets,
 				0, 0, NULL,
 //				macide_baboon_iops,
 				IRQ_BABOON_1);
-		index = ide_register_hw(&hw, NULL, 1, &hwif);
-		if (index == -1) break;
-		if (macintosh_config->ident == MAC_MODEL_PB190) {
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "ide: Macintosh %s IDE controller\n",
+			 mac_ide_name[macintosh_config->ide_type - 1]);
 
+	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	if (hwif) {
+		u8 index = hwif->index;
+		u8 idx[4] = { index, 0xff, 0xff, 0xff };
+
+		ide_init_port_data(hwif, index);
+		ide_init_port_hw(hwif, &hw);
+
+		if (macintosh_config->ide_type == MAC_IDE_BABOON &&
+		    macintosh_config->ident == MAC_MODEL_PB190) {
 			/* Fix breakage in ide-disk.c: drive capacity	*/
 			/* is not initialized for drives without a 	*/
 			/* hardware ID, and we can't get that without	*/
 			/* probing the drive which freezes a 190.	*/
-
-			ide_drive_t *drive = &ide_hwifs[index].drives[0];
+			ide_drive_t *drive = &hwif->drives[0];
 			drive->capacity64 = drive->cyl*drive->head*drive->sect;
-
 		}
-		break;
-
-	default:
-	    return;
-	}
 
-        if (index != -1) {
 		hwif->mmio = 1;
-		if (macintosh_config->ide_type == MAC_IDE_QUADRA)
-			printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index);
-		else if (macintosh_config->ide_type == MAC_IDE_PB)
-			printk(KERN_INFO "ide%d: Macintosh Powerbook IDE interface\n", index);
-		else if (macintosh_config->ide_type == MAC_IDE_BABOON)
-			printk(KERN_INFO "ide%d: Macintosh Powerbook Baboon IDE interface\n", index);
-		else
-			printk(KERN_INFO "ide%d: Unknown Macintosh IDE interface\n", index);
+
+		ide_device_add(idx);
 	}
+
+	return 0;
 }
+
+module_init(macide_init);
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index 6ea46a6..f532973 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -111,15 +111,17 @@ static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
  *  Probe for Q40 IDE interfaces
  */
 
-void __init q40ide_init(void)
+static int __init q40ide_init(void)
 {
     int i;
     ide_hwif_t *hwif;
-    int index;
     const char *name;
+    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
     if (!MACH_IS_Q40)
-      return ;
+      return -ENODEV;
+
+    printk(KERN_INFO "ide: Q40 IDE controller\n");
 
     for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
 	hw_regs_t hw;
@@ -141,10 +143,20 @@ void __init q40ide_init(void)
 			0, NULL,
 //			m68kide_iops,
 			q40ide_default_irq(pcide_bases[i]));
-	index = ide_register_hw(&hw, NULL, 1, &hwif);
-	// **FIXME**
-	if (index != -1)
+
+	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	if (hwif) {
+		ide_init_port_data(hwif, hwif->index);
+		ide_init_port_hw(hwif, &hw);
 		hwif->mmio = 1;
+
+		idx[i] = hwif->index;
+	}
     }
+
+    ide_device_add(idx);
+
+    return 0;
 }
 
+module_init(q40ide_init);
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
index 912e738..2bac4c1 100644
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -478,8 +478,7 @@ int probe_qd65xx = 0;
 module_param_named(probe, probe_qd65xx, bool, 0);
 MODULE_PARM_DESC(probe, "probe for QD65xx chipsets");
 
-/* Can be called directly from ide.c. */
-int __init qd65xx_init(void)
+static int __init qd65xx_init(void)
 {
 	if (probe_qd65xx == 0)
 		return -ENODEV;
@@ -492,9 +491,7 @@ int __init qd65xx_init(void)
 	return 0;
 }
 
-#ifdef MODULE
 module_init(qd65xx_init);
-#endif
 
 MODULE_AUTHOR("Samuel Thibault");
 MODULE_DESCRIPTION("support of qd65xx vlb ide chipset");
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
index 79577b9..a1ae1ae 100644
--- a/drivers/ide/legacy/umc8672.c
+++ b/drivers/ide/legacy/umc8672.c
@@ -169,8 +169,7 @@ int probe_umc8672 = 0;
 module_param_named(probe, probe_umc8672, bool, 0);
 MODULE_PARM_DESC(probe, "probe for UMC8672 chipset");
 
-/* Can be called directly from ide.c. */
-int __init umc8672_init(void)
+static int __init umc8672_init(void)
 {
 	if (probe_umc8672 == 0)
 		goto out;
@@ -181,9 +180,7 @@ out:
 	return -ENODEV;;
 }
 
-#ifdef MODULE
 module_init(umc8672_init);
-#endif
 
 MODULE_AUTHOR("Wolfram Podien");
 MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset");
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index a4d0d4c..2d3e511 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -395,26 +395,10 @@ static int auide_dma_test_irq(ide_drive_t *drive)
 	return 0;
 }
 
-static void auide_dma_host_on(ide_drive_t *drive)
+static void auide_dma_host_set(ide_drive_t *drive, int on)
 {
 }
 
-static int auide_dma_on(ide_drive_t *drive)
-{
-	drive->using_dma = 1;
-
-	return 0;
-}
-
-static void auide_dma_host_off(ide_drive_t *drive)
-{
-}
-
-static void auide_dma_off_quietly(ide_drive_t *drive)
-{
-	drive->using_dma = 0;
-}
-
 static void auide_dma_lost_irq(ide_drive_t *drive)
 {
 	printk(KERN_ERR "%s: IRQ lost\n", drive->name);
@@ -641,12 +625,13 @@ static int au_ide_probe(struct device *dev)
 	/* FIXME:  This might possibly break PCMCIA IDE devices */
 
 	hwif                            = &ide_hwifs[pdev->id];
-	hwif->irq			= ahwif->irq;
-	hwif->chipset                   = ide_au1xxx;
 
 	memset(&hw, 0, sizeof(hw));
 	auide_setup_ports(&hw, ahwif);
-	memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
+	hw.irq = ahwif->irq;
+	hw.chipset = ide_au1xxx;
+
+	ide_init_port_hw(hwif, &hw);
 
 	hwif->ultra_mask                = 0x0;  /* Disable Ultra DMA */
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
@@ -660,7 +645,6 @@ static int au_ide_probe(struct device *dev)
 	hwif->pio_mask = ATA_PIO4;
 	hwif->host_flags = IDE_HFLAG_POST_SET_MODE;
 
-	hwif->noprobe = 0;
 	hwif->drives[0].unmask          = 1;
 	hwif->drives[1].unmask          = 1;
 
@@ -682,29 +666,25 @@ static int au_ide_probe(struct device *dev)
 	hwif->set_dma_mode		= &auide_set_dma_mode;
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-	hwif->dma_off_quietly		= &auide_dma_off_quietly;
 	hwif->dma_timeout		= &auide_dma_timeout;
 
 	hwif->mdma_filter		= &auide_mdma_filter;
 
+	hwif->dma_host_set		= &auide_dma_host_set;
 	hwif->dma_exec_cmd              = &auide_dma_exec_cmd;
 	hwif->dma_start                 = &auide_dma_start;
 	hwif->ide_dma_end               = &auide_dma_end;
 	hwif->dma_setup                 = &auide_dma_setup;
 	hwif->ide_dma_test_irq          = &auide_dma_test_irq;
-	hwif->dma_host_off		= &auide_dma_host_off;
-	hwif->dma_host_on		= &auide_dma_host_on;
 	hwif->dma_lost_irq		= &auide_dma_lost_irq;
-	hwif->ide_dma_on                = &auide_dma_on;
-#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+#endif
 	hwif->channel                   = 0;
-	hwif->hold                      = 1;
 	hwif->select_data               = 0;    /* no chipset-specific code */
 	hwif->config_data               = 0;    /* no chipset-specific code */
 
 	hwif->drives[0].autotune        = 1;    /* 1=autotune, 2=noautotune, 0=default */
 	hwif->drives[1].autotune	= 1;
-#endif
+
 	hwif->drives[0].no_io_32bit	= 1;
 	hwif->drives[1].no_io_32bit	= 1;
 
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index 521edd4..8b3959d 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -117,6 +117,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
 	default_hwif_mmiops(hwif);
 	/* Prevent resource map manipulation.  */
 	hwif->mmio = 1;
+	hwif->chipset = ide_generic;
 	hwif->noprobe = 0;
 
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index 95d1ea8..9480325 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -36,4 +36,8 @@ obj-$(CONFIG_BLK_DEV_VIA82CXXX)		+= via82cxxx.o
 # Must appear at the end of the block
 obj-$(CONFIG_BLK_DEV_GENERIC)          += generic.o
 
+ifeq ($(CONFIG_BLK_DEV_CMD640), m)
+	obj-m += cmd640.o
+endif
+
 EXTRA_CFLAGS	:= -Idrivers/ide
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 5ae2656..4918719 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/atiixp.c	Version 0.03	Aug 3 2007
+ *  linux/drivers/ide/pci/atiixp.c	Version 0.05	Nov 9 2007
  *
  *  Copyright (C) 2003 ATI Inc. <hyu@ati.com>
  *  Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz
@@ -43,47 +43,8 @@ static atiixp_ide_timing mdma_timing[] = {
 	{ 0x02, 0x00 },
 };
 
-static int save_mdma_mode[4];
-
 static DEFINE_SPINLOCK(atiixp_lock);
 
-static void atiixp_dma_host_on(ide_drive_t *drive)
-{
-	struct pci_dev *dev = drive->hwif->pci_dev;
-	unsigned long flags;
-	u16 tmp16;
-
-	spin_lock_irqsave(&atiixp_lock, flags);
-
-	pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
-	if (save_mdma_mode[drive->dn])
-		tmp16 &= ~(1 << drive->dn);
-	else
-		tmp16 |= (1 << drive->dn);
-	pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
-
-	spin_unlock_irqrestore(&atiixp_lock, flags);
-
-	ide_dma_host_on(drive);
-}
-
-static void atiixp_dma_host_off(ide_drive_t *drive)
-{
-	struct pci_dev *dev = drive->hwif->pci_dev;
-	unsigned long flags;
-	u16 tmp16;
-
-	spin_lock_irqsave(&atiixp_lock, flags);
-
-	pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
-	tmp16 &= ~(1 << drive->dn);
-	pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
-
-	spin_unlock_irqrestore(&atiixp_lock, flags);
-
-	ide_dma_host_off(drive);
-}
-
 /**
  *	atiixp_set_pio_mode	-	set host controller for PIO mode
  *	@drive: drive
@@ -132,26 +93,33 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
 	int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
 	u32 tmp32;
 	u16 tmp16;
+	u16 udma_ctl = 0;
 
 	spin_lock_irqsave(&atiixp_lock, flags);
 
-	save_mdma_mode[drive->dn] = 0;
+	pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &udma_ctl);
+
 	if (speed >= XFER_UDMA_0) {
 		pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16);
 		tmp16 &= ~(0x07 << (drive->dn * 4));
 		tmp16 |= ((speed & 0x07) << (drive->dn * 4));
 		pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16);
-	} else {
-		if ((speed >= XFER_MW_DMA_0) && (speed <= XFER_MW_DMA_2)) {
-			save_mdma_mode[drive->dn] = speed;
-			pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32);
-			tmp32 &= ~(0xff << timing_shift);
-			tmp32 |= (mdma_timing[speed & 0x03].recover_width << timing_shift) |
-				(mdma_timing[speed & 0x03].command_width << (timing_shift + 4));
-			pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32);
-		}
+
+		udma_ctl |= (1 << drive->dn);
+	} else if (speed >= XFER_MW_DMA_0) {
+		u8 i = speed & 0x03;
+
+		pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32);
+		tmp32 &= ~(0xff << timing_shift);
+		tmp32 |= (mdma_timing[i].recover_width << timing_shift) |
+			 (mdma_timing[i].command_width << (timing_shift + 4));
+		pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32);
+
+		udma_ctl &= ~(1 << drive->dn);
 	}
 
+	pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, udma_ctl);
+
 	spin_unlock_irqrestore(&atiixp_lock, flags);
 }
 
@@ -181,9 +149,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
 		hwif->cbl = ATA_CBL_PATA80;
 	else
 		hwif->cbl = ATA_CBL_PATA40;
-
-	hwif->dma_host_on = &atiixp_dma_host_on;
-	hwif->dma_host_off = &atiixp_dma_host_off;
 }
 
 static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index 4aa4810..da3565e 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -706,9 +706,9 @@ static int pci_conf2(void)
 }
 
 /*
- * Probe for a cmd640 chipset, and initialize it if found.  Called from ide.c
+ * Probe for a cmd640 chipset, and initialize it if found.
  */
-int __init ide_probe_for_cmd640x (void)
+static int __init cmd640x_init(void)
 {
 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 	int second_port_toggled = 0;
@@ -717,6 +717,7 @@ int __init ide_probe_for_cmd640x (void)
 	const char *bus_type, *port2;
 	unsigned int index;
 	u8 b, cfr;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	if (cmd640_vlb && probe_for_cmd640_vlb()) {
 		bus_type = "VLB";
@@ -769,6 +770,8 @@ int __init ide_probe_for_cmd640x (void)
 	cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode;
 #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 
+	idx[0] = cmd_hwif0->index;
+
 	/*
 	 * Ensure compatibility by always using the slowest timings
 	 * for access to the drive's command register block,
@@ -826,6 +829,8 @@ int __init ide_probe_for_cmd640x (void)
 		cmd_hwif1->pio_mask = ATA_PIO5;
 		cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode;
 #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
+
+		idx[1] = cmd_hwif1->index;
 	}
 	printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name,
 		cmd_hwif0->serialized ? "" : "not ", port2);
@@ -872,6 +877,13 @@ int __init ide_probe_for_cmd640x (void)
 #ifdef CMD640_DUMP_REGS
 	cmd640_dump_regs();
 #endif
+
+	ide_device_add(idx);
+
 	return 1;
 }
 
+module_param_named(probe_vlb, cmd640_vlb, bool, 0);
+MODULE_PARM_DESC(probe_vlb, "probe for VLB version of CMD640 chipset");
+
+module_init(cmd640x_init);
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 0b1e947..cd4eb9d 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/cmd64x.c		Version 1.52	Dec 24, 2007
+ * linux/drivers/ide/pci/cmd64x.c		Version 1.53	Dec 24, 2007
  *
  * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
  *           Due to massive hardware bugs, UltraDMA is only supported
@@ -22,8 +22,6 @@
 
 #include <asm/io.h>
 
-#define DISPLAY_CMD64X_TIMINGS
-
 #define CMD_DEBUG 0
 
 #if CMD_DEBUG
@@ -37,11 +35,6 @@
  */
 #define CFR		0x50
 #define   CFR_INTR_CH0		0x04
-#define CNTRL		0x51
-#define   CNTRL_ENA_1ST 	0x04
-#define   CNTRL_ENA_2ND 	0x08
-#define   CNTRL_DIS_RA0 	0x40
-#define   CNTRL_DIS_RA1 	0x80
 
 #define	CMDTIM		0x52
 #define	ARTTIM0		0x53
@@ -60,108 +53,13 @@
 #define MRDMODE		0x71
 #define   MRDMODE_INTR_CH0	0x04
 #define   MRDMODE_INTR_CH1	0x08
-#define   MRDMODE_BLK_CH0	0x10
-#define   MRDMODE_BLK_CH1	0x20
-#define BMIDESR0	0x72
 #define UDIDETCR0	0x73
 #define DTPR0		0x74
 #define BMIDECR1	0x78
 #define BMIDECSR	0x79
-#define BMIDESR1	0x7A
 #define UDIDETCR1	0x7B
 #define DTPR1		0x7C
 
-#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 cmd64x_proc = 0;
-
-#define CMD_MAX_DEVS		5
-
-static struct pci_dev *cmd_devs[CMD_MAX_DEVS];
-static int n_cmd_devs;
-
-static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
-{
-	char *p = buf;
-	u8 reg72 = 0, reg73 = 0;			/* primary */
-	u8 reg7a = 0, reg7b = 0;			/* secondary */
-	u8 reg50 = 1, reg51 = 1, reg57 = 0, reg71 = 0;	/* extra */
-
-	p += sprintf(p, "\nController: %d\n", index);
-	p += sprintf(p, "PCI-%x Chipset.\n", dev->device);
-
-	(void) pci_read_config_byte(dev, CFR,       &reg50);
-	(void) pci_read_config_byte(dev, CNTRL,     &reg51);
-	(void) pci_read_config_byte(dev, ARTTIM23,  &reg57);
-	(void) pci_read_config_byte(dev, MRDMODE,   &reg71);
-	(void) pci_read_config_byte(dev, BMIDESR0,  &reg72);
-	(void) pci_read_config_byte(dev, UDIDETCR0, &reg73);
-	(void) pci_read_config_byte(dev, BMIDESR1,  &reg7a);
-	(void) pci_read_config_byte(dev, UDIDETCR1, &reg7b);
-
-	/* PCI0643/6 originally didn't have the primary channel enable bit */
-	if ((dev->device == PCI_DEVICE_ID_CMD_643) ||
-	    (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 3))
-		reg51 |= CNTRL_ENA_1ST;
-
-	p += sprintf(p, "---------------- Primary Channel "
-			"---------------- Secondary Channel ------------\n");
-	p += sprintf(p, "                 %s                         %s\n",
-		 (reg51 & CNTRL_ENA_1ST) ? "enabled " : "disabled",
-		 (reg51 & CNTRL_ENA_2ND) ? "enabled " : "disabled");
-	p += sprintf(p, "---------------- drive0 --------- drive1 "
-			"-------- drive0 --------- drive1 ------\n");
-	p += sprintf(p, "DMA enabled:     %s              %s"
-			"             %s              %s\n",
-		(reg72 & 0x20) ? "yes" : "no ", (reg72 & 0x40) ? "yes" : "no ",
-		(reg7a & 0x20) ? "yes" : "no ", (reg7a & 0x40) ? "yes" : "no ");
-	p += sprintf(p, "UltraDMA mode:   %s (%c)          %s (%c)",
-		( reg73 & 0x01) ? " on" : "off",
-		((reg73 & 0x30) == 0x30) ? ((reg73 & 0x04) ? '3' : '0') :
-		((reg73 & 0x30) == 0x20) ? ((reg73 & 0x04) ? '3' : '1') :
-		((reg73 & 0x30) == 0x10) ? ((reg73 & 0x04) ? '4' : '2') :
-		((reg73 & 0x30) == 0x00) ? ((reg73 & 0x04) ? '5' : '2') : '?',
-		( reg73 & 0x02) ? " on" : "off",
-		((reg73 & 0xC0) == 0xC0) ? ((reg73 & 0x08) ? '3' : '0') :
-		((reg73 & 0xC0) == 0x80) ? ((reg73 & 0x08) ? '3' : '1') :
-		((reg73 & 0xC0) == 0x40) ? ((reg73 & 0x08) ? '4' : '2') :
-		((reg73 & 0xC0) == 0x00) ? ((reg73 & 0x08) ? '5' : '2') : '?');
-	p += sprintf(p, "         %s (%c)          %s (%c)\n",
-		( reg7b & 0x01) ? " on" : "off",
-		((reg7b & 0x30) == 0x30) ? ((reg7b & 0x04) ? '3' : '0') :
-		((reg7b & 0x30) == 0x20) ? ((reg7b & 0x04) ? '3' : '1') :
-		((reg7b & 0x30) == 0x10) ? ((reg7b & 0x04) ? '4' : '2') :
-		((reg7b & 0x30) == 0x00) ? ((reg7b & 0x04) ? '5' : '2') : '?',
-		( reg7b & 0x02) ? " on" : "off",
-		((reg7b & 0xC0) == 0xC0) ? ((reg7b & 0x08) ? '3' : '0') :
-		((reg7b & 0xC0) == 0x80) ? ((reg7b & 0x08) ? '3' : '1') :
-		((reg7b & 0xC0) == 0x40) ? ((reg7b & 0x08) ? '4' : '2') :
-		((reg7b & 0xC0) == 0x00) ? ((reg7b & 0x08) ? '5' : '2') : '?');
-	p += sprintf(p, "Interrupt:       %s, %s                 %s, %s\n",
-		(reg71 & MRDMODE_BLK_CH0  ) ? "blocked" : "enabled",
-		(reg50 & CFR_INTR_CH0	  ) ? "pending" : "clear  ",
-		(reg71 & MRDMODE_BLK_CH1  ) ? "blocked" : "enabled",
-		(reg57 & ARTTIM23_INTR_CH1) ? "pending" : "clear  ");
-
-	return (char *)p;
-}
-
-static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
-{
-	char *p = buffer;
-	int i;
-
-	for (i = 0; i < n_cmd_devs; i++) {
-		struct pci_dev *dev	= cmd_devs[i];
-		p = print_cmd64x_get_info(p, dev, i);
-	}
-	return p-buffer;	/* => must be less than 4k! */
-}
-
-#endif	/* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */
-
 static u8 quantize_timing(int timing, int quant)
 {
 	return (timing + quant - 1) / quant;
@@ -472,16 +370,6 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
 	mrdmode &= ~0x30;
 	(void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02));
 
-#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
-
-	cmd_devs[n_cmd_devs++] = dev;
-
-	if (!cmd64x_proc) {
-		cmd64x_proc = 1;
-		ide_pci_create_host_proc("cmd64x", cmd64x_get_info);
-	}
-#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_IDE_PROC_FS */
-
 	return 0;
 }
 
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index d1a91bc..6ec00b8 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -71,7 +71,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	ide_hwif_t *hwif = HWIF(drive);
 	struct pci_dev *pdev = hwif->pci_dev;
 	int controller = drive->dn > 1 ? 1 : 0;
-	u8 reg;
 
 	/* FIXME: if DMA = 1 do we need to set the DMA bit here ? */
 
@@ -91,11 +90,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1),
 		(cs5520_pio_clocks[pio].recovery << 4) |
 		(cs5520_pio_clocks[pio].assert));
-		
-	/* Set the DMA enable/disable flag */
-	reg = inb(hwif->dma_base + 0x02 + 8*controller);
-	reg |= 1<<((drive->dn&1)+5);
-	outb(reg, hwif->dma_base + 0x02 + 8*controller);
 }
 
 static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
@@ -109,13 +103,14 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
  *	We wrap the DMA activate to set the vdma flag. This is needed
  *	so that the IDE DMA layer issues PIO not DMA commands over the
  *	DMA channel
+ *
+ *	ATAPI is harder so disable it for now using IDE_HFLAG_NO_ATAPI_DMA
  */
- 
-static int cs5520_dma_on(ide_drive_t *drive)
+
+static void cs5520_dma_host_set(ide_drive_t *drive, int on)
 {
-	/* ATAPI is harder so leave it for now */
-	drive->vdma = 1;
-	return 0;
+	drive->vdma = on;
+	ide_dma_host_set(drive, on);
 }
 
 static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
@@ -126,7 +121,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->ide_dma_on = &cs5520_dma_on;
+	hwif->dma_host_set = &cs5520_dma_host_set;
 }
 
 #define DECLARE_CS_DEV(name_str)				\
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 1cd4e9c..3ec4c65 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/cy82c693.c		Version 0.42	Oct 23, 2007
+ * linux/drivers/ide/pci/cy82c693.c		Version 0.44	Nov 8, 2007
  *
  *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
  *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
@@ -176,17 +176,12 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
  * set DMA mode a specific channel for CY82C693
  */
 
-static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
+static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
 {
-	u8 index = 0, data = 0;
+	ide_hwif_t *hwif = drive->hwif;
+	u8 single = (mode & 0x10) >> 4, index = 0, data = 0;
 
-	if (mode>2)	/* make sure we set a valid mode */
-		mode = 2;
-			   
-	if (mode > drive->id->tDMA)  /* to be absolutly sure we have a valid mode */
-		mode = drive->id->tDMA;
-	
-	index = (HWIF(drive)->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1;
+	index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0;
 
 #if CY82C693_DEBUG_LOGS
 	/* for debug let's show the previous values */
@@ -199,7 +194,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
 		(data&0x3), ((data>>2)&1));
 #endif /* CY82C693_DEBUG_LOGS */
 
-	data = (u8)mode|(u8)(single<<2);
+	data = (mode & 3) | (single << 2);
 
 	outb(index, CY82_INDEX_PORT);
 	outb(data, CY82_DATA_PORT);
@@ -207,7 +202,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
 #if CY82C693_DEBUG_INFO
 	printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
 		drive->name, HWIF(drive)->channel, drive->select.b.unit,
-		mode, single);
+		mode & 3, single);
 #endif /* CY82C693_DEBUG_INFO */
 
 	/* 
@@ -230,39 +225,6 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
 #endif /* CY82C693_DEBUG_INFO */
 }
 
-/* 
- * used to set DMA mode for CY82C693 (single and multi modes)
- */
-static int cy82c693_ide_dma_on (ide_drive_t *drive)
-{
-	struct hd_driveid *id = drive->id;
-
-#if CY82C693_DEBUG_INFO
-	printk (KERN_INFO "dma_on: %s\n", drive->name);
-#endif /* CY82C693_DEBUG_INFO */
-
-	if (id != NULL) {		
-		/* Enable DMA on any drive that has DMA
-		 * (multi or single) enabled
-		 */
-		if (id->field_valid & 2) {	/* regular DMA */
-			int mmode, smode;
-
-			mmode = id->dma_mword & (id->dma_mword >> 8);
-			smode = id->dma_1word & (id->dma_1word >> 8);
-			       		      
-			if (mmode != 0) {
-				/* enable multi */
-				cy82c693_dma_enable(drive, (mmode >> 1), 0);
-			} else if (smode != 0) {
-				/* enable single */
-				cy82c693_dma_enable(drive, (smode >> 1), 1);
-			}
-		}
-	}
-        return __ide_dma_on(drive);
-}
-
 static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
 	ide_hwif_t *hwif = HWIF(drive);
@@ -429,11 +391,7 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
 static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
 {
 	hwif->set_pio_mode = &cy82c693_set_pio_mode;
-
-	if (hwif->dma_base == 0)
-		return;
-
-	hwif->ide_dma_on = &cy82c693_ide_dma_on;
+	hwif->set_dma_mode = &cy82c693_set_dma_mode;
 }
 
 static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
@@ -454,11 +412,11 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = {
 	.init_iops	= init_iops_cy82c693,
 	.init_hwif	= init_hwif_cy82c693,
 	.chipset	= ide_cy82c693,
-	.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+	.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_CY82C693 |
 			  IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO4,
-	.swdma_mask	= ATA_SWDMA2_ONLY,
-	.mwdma_mask	= ATA_MWDMA2_ONLY,
+	.swdma_mask	= ATA_SWDMA2,
+	.mwdma_mask	= ATA_MWDMA2,
 };
 
 static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 8382908..26aa492 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -80,7 +80,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
 	hw.irq = dev->irq;
 	hw.chipset = ide_pci;		/* this enables IRQ sharing */
 
-	rc = ide_register_hw(&hw, &ide_undecoded_slave, 0, &hwif);
+	rc = ide_register_hw(&hw, &ide_undecoded_slave, &hwif);
 	if (rc < 0) {
 		printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
 		pci_disable_device(dev);
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 3777fb8..1268593 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -725,15 +725,18 @@ static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	hpt3xx_set_mode(drive, XFER_PIO_0 + pio);
 }
 
-static int hpt3xx_quirkproc(ide_drive_t *drive)
+static void hpt3xx_quirkproc(ide_drive_t *drive)
 {
 	struct hd_driveid *id	= drive->id;
 	const  char **list	= quirk_drives;
 
 	while (*list)
-		if (strstr(id->model, *list++))
-			return 1;
-	return 0;
+		if (strstr(id->model, *list++)) {
+			drive->quirk_list = 1;
+			return;
+		}
+
+	drive->quirk_list = 0;
 }
 
 static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 99b7d76..e610a53 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -431,33 +431,29 @@ static u8 __devinit ata66_it821x(ide_hwif_t *hwif)
 }
 
 /**
- *	it821x_fixup	-	post init callback
- *	@hwif: interface
+ *	it821x_quirkproc	-	post init callback
+ *	@drive: drive
  *
- *	This callback is run after the drives have been probed but
+ *	This callback is run after the drive has been probed but
  *	before anything gets attached. It allows drivers to do any
  *	final tuning that is needed, or fixups to work around bugs.
  */
 
-static void __devinit it821x_fixups(ide_hwif_t *hwif)
+static void __devinit it821x_quirkproc(ide_drive_t *drive)
 {
-	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
-	int i;
+	struct it821x_dev *itdev = ide_get_hwifdata(drive->hwif);
+	struct hd_driveid *id = drive->id;
+	u16 *idbits = (u16 *)drive->id;
 
-	if(!itdev->smart) {
+	if (!itdev->smart) {
 		/*
 		 *	If we are in pass through mode then not much
 		 *	needs to be done, but we do bother to clear the
 		 *	IRQ mask as we may well be in PIO (eg rev 0x10)
 		 *	for now and we know unmasking is safe on this chipset.
 		 */
-		for (i = 0; i < 2; i++) {
-			ide_drive_t *drive = &hwif->drives[i];
-			if(drive->present)
-				drive->unmask = 1;
-		}
-		return;
-	}
+		drive->unmask = 1;
+	} else {
 	/*
 	 *	Perform fixups on smart mode. We need to "lose" some
 	 *	capabilities the firmware lacks but does not filter, and
@@ -465,16 +461,6 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
 	 *	in RAID mode.
 	 */
 
-	for(i = 0; i < 2; i++) {
-		ide_drive_t *drive = &hwif->drives[i];
-		struct hd_driveid *id;
-		u16 *idbits;
-
-		if(!drive->present)
-			continue;
-		id = drive->id;
-		idbits = (u16 *)drive->id;
-
 		/* Check for RAID v native */
 		if(strstr(id->model, "Integrated Technology Express")) {
 			/* In raid mode the ident block is slightly buggy
@@ -537,6 +523,8 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
 	struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
 	u8 conf;
 
+	hwif->quirkproc = &it821x_quirkproc;
+
 	if (idev == NULL) {
 		printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
 		return;
@@ -633,7 +621,6 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
 		.name		= name_str,		\
 		.init_chipset	= init_chipset_it821x,	\
 		.init_hwif	= init_hwif_it821x,	\
-		.fixup	 	= it821x_fixups,	\
 		.host_flags	= IDE_HFLAG_BOOTABLE,	\
 		.pio_mask	= ATA_PIO4,		\
 	}
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index ef4a99b..89d2363 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -203,14 +203,17 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
 		return ATA_CBL_PATA80;
 }
 
-static int pdcnew_quirkproc(ide_drive_t *drive)
+static void pdcnew_quirkproc(ide_drive_t *drive)
 {
 	const char **list, *model = drive->id->model;
 
 	for (list = pdc_quirk_drives; *list != NULL; list++)
-		if (strstr(model, *list) != NULL)
-			return 2;
-	return 0;
+		if (strstr(model, *list) != NULL) {
+			drive->quirk_list = 2;
+			return;
+		}
+
+	drive->quirk_list = 0;
 }
 
 static void pdcnew_reset(ide_drive_t *drive)
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 67b2781..3a1e081 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -176,14 +176,17 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
 	outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
 }
 
-static int pdc202xx_quirkproc (ide_drive_t *drive)
+static void pdc202xx_quirkproc(ide_drive_t *drive)
 {
 	const char **list, *model = drive->id->model;
 
 	for (list = pdc_quirk_drives; *list != NULL; list++)
-		if (strstr(model, *list) != NULL)
-			return 2;
-	return 0;
+		if (strstr(model, *list) != NULL) {
+			drive->quirk_list = 2;
+			return;
+		}
+
+	drive->quirk_list = 0;
 }
 
 static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index fef20bd..32fdf53 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -220,9 +220,9 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	}
 	if (mode != -1) {
 		printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
-		hwif->dma_off_quietly(drive);
-		if (ide_set_dma_mode(drive, mode) == 0)
-			hwif->dma_host_on(drive);
+		ide_dma_off_quietly(drive);
+		if (ide_set_dma_mode(drive, mode) == 0 && drive->using_dma)
+			hwif->dma_host_set(drive, 1);
 		return;
 	}
 
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index e9bd269..877c09b 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -164,25 +164,12 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
 	ultra_timing	&= ~(0x0F << (4*unit));
 	ultra_enable	&= ~(0x01 << drive->dn);
 
-	switch(speed) {
-		case XFER_MW_DMA_2:
-		case XFER_MW_DMA_1:
-		case XFER_MW_DMA_0:
-			dma_timing |= dma_modes[speed - XFER_MW_DMA_0];
-			break;
-
-		case XFER_UDMA_5:
-		case XFER_UDMA_4:
-		case XFER_UDMA_3:
-		case XFER_UDMA_2:
-		case XFER_UDMA_1:
-		case XFER_UDMA_0:
-			dma_timing   |= dma_modes[2];
-			ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit));
-			ultra_enable |= (0x01 << drive->dn);
-		default:
-			break;
-	}
+	if (speed >= XFER_UDMA_0) {
+		dma_timing   |= dma_modes[2];
+		ultra_timing |= (udma_modes[speed - XFER_UDMA_0] << (4 * unit));
+		ultra_enable |= (0x01 << drive->dn);
+	} else if (speed >= XFER_MW_DMA_0)
+		dma_timing   |= dma_modes[speed - XFER_MW_DMA_0];
 
 	pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing);
 	pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing);
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 7e9dade..9e0be7d 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -277,21 +277,6 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
 	return dma_stat;
 }
 
-static int
-sgiioc4_ide_dma_on(ide_drive_t * drive)
-{
-	drive->using_dma = 1;
-
-	return 0;
-}
-
-static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
-{
-	drive->using_dma = 0;
-
-	drive->hwif->dma_host_off(drive);
-}
-
 static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
 }
@@ -303,13 +288,10 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
 	return sgiioc4_checkirq(HWIF(drive));
 }
 
-static void sgiioc4_dma_host_on(ide_drive_t * drive)
-{
-}
-
-static void sgiioc4_dma_host_off(ide_drive_t * drive)
+static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
 {
-	sgiioc4_clearirq(drive);
+	if (!on)
+		sgiioc4_clearirq(drive);
 }
 
 static void
@@ -593,14 +575,11 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
 
 	hwif->mwdma_mask = ATA_MWDMA2_ONLY;
 
+	hwif->dma_host_set = &sgiioc4_dma_host_set;
 	hwif->dma_setup = &sgiioc4_ide_dma_setup;
 	hwif->dma_start = &sgiioc4_ide_dma_start;
 	hwif->ide_dma_end = &sgiioc4_ide_dma_end;
-	hwif->ide_dma_on = &sgiioc4_ide_dma_on;
-	hwif->dma_off_quietly = &sgiioc4_dma_off_quietly;
 	hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
-	hwif->dma_host_on = &sgiioc4_dma_host_on;
-	hwif->dma_host_off = &sgiioc4_dma_host_off;
 	hwif->dma_lost_irq = &sgiioc4_dma_lost_irq;
 	hwif->dma_timeout = &ide_dma_timeout;
 }
@@ -614,6 +593,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 	ide_hwif_t *hwif;
 	int h;
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+	hw_regs_t hw;
 
 	/*
 	 * Find an empty HWIF; if none available, return -ENOMEM.
@@ -653,21 +633,16 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 		return -ENOMEM;
 	}
 
-	if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) {
-		hw_regs_t hw;
-
-		/* Initialize the IO registers */
-		memset(&hw, 0, sizeof(hw));
-		sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
-		memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
-		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
-	}
+	/* Initialize the IO registers */
+	memset(&hw, 0, sizeof(hw));
+	sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
+	hw.irq = dev->irq;
+	hw.chipset = ide_pci;
+	hw.dev = &dev->dev;
+	ide_init_port_hw(hwif, &hw);
 
-	hwif->irq = dev->irq;
-	hwif->chipset = ide_pci;
 	hwif->pci_dev = dev;
 	hwif->channel = 0;	/* Single Channel chip */
-	hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */
 
 	/* The IOC4 uses MMIO rather than Port IO. */
 	default_hwif_mmiops(hwif);
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 7b45eaf..908f37b 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -713,9 +713,6 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
 	const char *s = &drive->id->model[0];
 	unsigned len;
 
-	if (!drive->present)
-		return 0;
-
 	len = strnlen(s, sizeof(drive->id->model));
 
 	if ((len > 4) && (!memcmp(s, "ST", 2))) {
@@ -730,18 +727,20 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
 }
 
 /**
- *	siimage_fixup		-	post probe fixups
- *	@hwif: interface to fix up
+ *	sil_quirkproc		-	post probe fixups
+ *	@drive: drive
  *
  *	Called after drive probe we use this to decide whether the
  *	Seagate fixup must be applied. This used to be in init_iops but
  *	that can occur before we know what drives are present.
  */
 
-static void __devinit siimage_fixup(ide_hwif_t *hwif)
+static void __devinit sil_quirkproc(ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = drive->hwif;
+
 	/* Try and raise the rqsize */
-	if (!is_sata(hwif) || !is_dev_seagate_sata(&hwif->drives[0]))
+	if (!is_sata(hwif) || !is_dev_seagate_sata(drive))
 		hwif->rqsize = 128;
 }
 
@@ -804,6 +803,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
 
 	hwif->set_pio_mode = &sil_set_pio_mode;
 	hwif->set_dma_mode = &sil_set_dma_mode;
+	hwif->quirkproc = &sil_quirkproc;
 
 	if (sata) {
 		static int first = 1;
@@ -842,7 +842,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
 		.init_chipset	= init_chipset_siimage,	\
 		.init_iops	= init_iops_siimage,	\
 		.init_hwif	= init_hwif_siimage,	\
-		.fixup		= siimage_fixup,	\
 		.host_flags	= IDE_HFLAG_BOOTABLE,	\
 		.pio_mask	= ATA_PIO4,		\
 		.mwdma_mask	= ATA_MWDMA2,		\
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 069f104..c7a125b 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -13,6 +13,7 @@
  *  -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org
  *
  * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C)      2007 Bartlomiej Zolnierkiewicz
  */
 
 #include <linux/types.h>
@@ -90,14 +91,8 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	drive->drive_data &= 0xffff0000;
 	drive->drive_data |= drv_ctrl;
 
-	if (!drive->using_dma) {
-		/*
-		 * If we are actually using MW DMA, then we can not
-		 * reprogram the interface drive control register.
-		 */
-		pci_write_config_word(dev, reg,  drv_ctrl);
-		pci_read_config_word (dev, reg, &drv_ctrl);
-	}
+	pci_write_config_word(dev, reg,  drv_ctrl);
+	pci_read_config_word (dev, reg, &drv_ctrl);
 
 	printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name,
 			  ide_xfer_verbose(pio + XFER_PIO_0),
@@ -123,17 +118,6 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
 	 */
 	drive->drive_data &= 0x0000ffff;
 	drive->drive_data |= (unsigned long)drv_ctrl << 16;
-
-	/*
-	 * If we are already using DMA, we just reprogram
-	 * the drive control register.
-	 */
-	if (drive->using_dma) {
-		struct pci_dev *dev	= HWIF(drive)->pci_dev;
-		int reg 		= 0x44 + drive->dn * 4;
-
-		pci_write_config_word(dev, reg, drv_ctrl);
-	}
 }
 
 /*
@@ -201,6 +185,11 @@ static void sl82c105_dma_start(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= hwif->pci_dev;
+	int reg 		= 0x44 + drive->dn * 4;
+
+	DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name));
+
+	pci_write_config_word(dev, reg, drive->drive_data >> 16);
 
 	sl82c105_reset_host(dev);
 	ide_dma_start(drive);
@@ -214,64 +203,24 @@ static void sl82c105_dma_timeout(ide_drive_t *drive)
 	ide_dma_timeout(drive);
 }
 
-static int sl82c105_ide_dma_on(ide_drive_t *drive)
-{
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
-	int rc, reg 		= 0x44 + drive->dn * 4;
-
-	DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name));
-
-	rc = __ide_dma_on(drive);
-	if (rc == 0) {
-		pci_write_config_word(dev, reg, drive->drive_data >> 16);
-
-		printk(KERN_INFO "%s: DMA enabled\n", drive->name);
-	}
-	return rc;
-}
-
-static void sl82c105_dma_off_quietly(ide_drive_t *drive)
+static int sl82c105_dma_end(ide_drive_t *drive)
 {
 	struct pci_dev *dev	= HWIF(drive)->pci_dev;
 	int reg 		= 0x44 + drive->dn * 4;
+	int ret;
 
-	DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name));
+	DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name));
 
-	pci_write_config_word(dev, reg, drive->drive_data);
+	ret = __ide_dma_end(drive);
 
-	ide_dma_off_quietly(drive);
-}
+	pci_write_config_word(dev, reg, drive->drive_data);
 
-/*
- * Ok, that is nasty, but we must make sure the DMA timings
- * won't be used for a PIO access. The solution here is
- * to make sure the 16 bits mode is diabled on the channel
- * when DMA is enabled, thus causing the chip to use PIO0
- * timings for those operations.
- */
-static void sl82c105_selectproc(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	u32 val, old, mask;
-
-	//DBG(("sl82c105_selectproc(drive:%s)\n", drive->name));
-
-	mask = hwif->channel ? CTRL_P1F16 : CTRL_P0F16;
-	old = val = (u32)pci_get_drvdata(dev);
-	if (drive->using_dma)
-		val &= ~mask;
-	else
-		val |= mask;
-	if (old != val) {
-		pci_write_config_dword(dev, 0x40, val);	
-		pci_set_drvdata(dev, (void *)val);
-	}
+	return ret;
 }
 
 /*
  * ATA reset will clear the 16 bits mode in the control
- * register, we need to update our cache
+ * register, we need to reprogram it
  */
 static void sl82c105_resetproc(ide_drive_t *drive)
 {
@@ -281,7 +230,8 @@ static void sl82c105_resetproc(ide_drive_t *drive)
 	DBG(("sl82c105_resetproc(drive:%s)\n", drive->name));
 
 	pci_read_config_dword(dev, 0x40, &val);
-	pci_set_drvdata(dev, (void *)val);
+	val |= (CTRL_P1F16 | CTRL_P0F16);
+	pci_write_config_dword(dev, 0x40, val);
 }
 
 /*
@@ -334,7 +284,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
 	pci_read_config_dword(dev, 0x40, &val);
 	val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
 	pci_write_config_dword(dev, 0x40, val);
-	pci_set_drvdata(dev, (void *)val);
 
 	return dev->irq;
 }
@@ -350,7 +299,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
 
 	hwif->set_pio_mode	= &sl82c105_set_pio_mode;
 	hwif->set_dma_mode	= &sl82c105_set_dma_mode;
-	hwif->selectproc	= &sl82c105_selectproc;
 	hwif->resetproc 	= &sl82c105_resetproc;
 
 	if (!hwif->dma_base)
@@ -369,10 +317,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
 
 	hwif->mwdma_mask = ATA_MWDMA2;
 
-	hwif->ide_dma_on		= &sl82c105_ide_dma_on;
-	hwif->dma_off_quietly		= &sl82c105_dma_off_quietly;
 	hwif->dma_lost_irq		= &sl82c105_dma_lost_irq;
 	hwif->dma_start			= &sl82c105_dma_start;
+	hwif->ide_dma_end		= &sl82c105_dma_end;
 	hwif->dma_timeout		= &sl82c105_dma_timeout;
 
 	if (hwif->mate)
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index 0151d7f..04cd893 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -241,11 +241,7 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive)
 	return (status == 0x00ff);
 }
 
-static void trm290_dma_host_on(ide_drive_t *drive)
-{
-}
-
-static void trm290_dma_host_off(ide_drive_t *drive)
+static void trm290_dma_host_set(ide_drive_t *drive, int on)
 {
 }
 
@@ -289,8 +285,7 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
 
 	ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
 
-	hwif->dma_host_off	= &trm290_dma_host_off;
-	hwif->dma_host_on	= &trm290_dma_host_on;
+	hwif->dma_host_set	= &trm290_dma_host_set;
 	hwif->dma_setup 	= &trm290_dma_setup;
 	hwif->dma_exec_cmd	= &trm290_dma_exec_cmd;
 	hwif->dma_start 	= &trm290_dma_start;
diff --git a/drivers/ide/ppc/Makefile b/drivers/ide/ppc/Makefile
new file mode 100644
index 0000000..65af584
--- /dev/null
+++ b/drivers/ide/ppc/Makefile
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_BLK_DEV_IDE_PMAC)		+= pmac.o
+obj-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= mpc8xx.o
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
index 5f0da35..3fd5d45 100644
--- a/drivers/ide/ppc/mpc8xx.c
+++ b/drivers/ide/ppc/mpc8xx.c
@@ -838,3 +838,21 @@ void m8xx_ide_init(void)
 	ppc_ide_md.default_io_base      = m8xx_ide_default_io_base;
 	ppc_ide_md.ide_init_hwif        = m8xx_ide_init_hwif_ports;
 }
+
+static int __init mpc8xx_ide_probe(void)
+{
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+
+#ifdef IDE0_BASE_OFFSET
+	idx[0] = 0;
+#ifdef IDE1_BASE_OFFSET
+	idx[1] = 1;
+#endif
+#endif
+
+	ide_device_add(idx);
+
+	return 0;
+}
+
+module_init(mpc8xx_ide_probe);
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 3dce800..736d12c 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1012,12 +1012,11 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
  * rare machines unfortunately, but it's better this way.
  */
 static int
-pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
 {
 	struct device_node *np = pmif->node;
 	const int *bidp;
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-	hw_regs_t hw;
 
 	pmif->cable_80 = 0;
 	pmif->broken_dma = pmif->broken_dma_warn = 0;
@@ -1103,11 +1102,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
 	/* Tell common code _not_ to mess with resources */
 	hwif->mmio = 1;
 	hwif->hwif_data = pmif;
-	memset(&hw, 0, sizeof(hw));
-	pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, &hwif->irq);
-	memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
-	hwif->chipset = ide_pmac;
-	hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;
+	hw->chipset = ide_pmac;
+	ide_init_port_hw(hwif, hw);
+	hwif->noprobe = pmif->mediabay;
 	hwif->hold = pmif->mediabay;
 	hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
 	hwif->drives[0].unmask = 1;
@@ -1136,8 +1133,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
 		hwif->noprobe = 0;
 #endif /* CONFIG_PMAC_MEDIABAY */
 
-	hwif->sg_max_nents = MAX_DCMDS;
-
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 	/* has a DBDMA controller channel */
 	if (pmif->dma_regs)
@@ -1163,6 +1158,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	ide_hwif_t *hwif;
 	pmac_ide_hwif_t *pmif;
 	int i, rc;
+	hw_regs_t hw;
 
 	i = 0;
 	while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0
@@ -1205,7 +1201,6 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	regbase = (unsigned long) base;
 
 	hwif->pci_dev = mdev->bus->pdev;
-	hwif->gendev.parent = &mdev->ofdev.dev;
 
 	pmif->mdev = mdev;
 	pmif->node = mdev->ofdev.node;
@@ -1223,7 +1218,12 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 	dev_set_drvdata(&mdev->ofdev.dev, hwif);
 
-	rc = pmac_ide_setup_device(pmif, hwif);
+	memset(&hw, 0, sizeof(hw));
+	pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, NULL);
+	hw.irq = irq;
+	hw.dev = &mdev->ofdev.dev;
+
+	rc = pmac_ide_setup_device(pmif, hwif, &hw);
 	if (rc != 0) {
 		/* The inteface is released to the common IDE layer */
 		dev_set_drvdata(&mdev->ofdev.dev, NULL);
@@ -1282,6 +1282,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 	void __iomem *base;
 	unsigned long rbase, rlen;
 	int i, rc;
+	hw_regs_t hw;
 
 	np = pci_device_to_OF_node(pdev);
 	if (np == NULL) {
@@ -1315,7 +1316,6 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 	}
 
 	hwif->pci_dev = pdev;
-	hwif->gendev.parent = &pdev->dev;
 	pmif->mdev = NULL;
 	pmif->node = np;
 
@@ -1332,7 +1332,12 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	pci_set_drvdata(pdev, hwif);
 
-	rc = pmac_ide_setup_device(pmif, hwif);
+	memset(&hw, 0, sizeof(hw));
+	pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, NULL);
+	hw.irq = pdev->irq;
+	hw.dev = &pdev->dev;
+
+	rc = pmac_ide_setup_device(pmif, hwif, &hw);
 	if (rc != 0) {
 		/* The inteface is released to the common IDE layer */
 		pci_set_drvdata(pdev, NULL);
@@ -1698,11 +1703,7 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
 	return 1;
 }
 
-static void pmac_ide_dma_host_off(ide_drive_t *drive)
-{
-}
-
-static void pmac_ide_dma_host_on(ide_drive_t *drive)
+static void pmac_ide_dma_host_set(ide_drive_t *drive, int on)
 {
 }
 
@@ -1748,15 +1749,14 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
 		return;
 	}
 
-	hwif->dma_off_quietly = &ide_dma_off_quietly;
-	hwif->ide_dma_on = &__ide_dma_on;
+	hwif->sg_max_nents = MAX_DCMDS;
+
+	hwif->dma_host_set = &pmac_ide_dma_host_set;
 	hwif->dma_setup = &pmac_ide_dma_setup;
 	hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd;
 	hwif->dma_start = &pmac_ide_dma_start;
 	hwif->ide_dma_end = &pmac_ide_dma_end;
 	hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
-	hwif->dma_host_off = &pmac_ide_dma_host_off;
-	hwif->dma_host_on = &pmac_ide_dma_host_on;
 	hwif->dma_timeout = &ide_dma_timeout;
 	hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
 
@@ -1786,3 +1786,5 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
 }
 
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+
+module_init(pmac_ide_probe);
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index d2cd5a3..676c66e 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -165,13 +165,17 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
 
 		dma_base = pci_resource_start(dev, baridx);
 
-		if (dma_base == 0)
+		if (dma_base == 0) {
 			printk(KERN_ERR "%s: DMA base is invalid\n", d->name);
+			return 0;
+		}
 	}
 
-	if ((d->host_flags & IDE_HFLAG_CS5520) == 0 && dma_base) {
+	if (hwif->channel)
+		dma_base += 8;
+
+	if ((d->host_flags & IDE_HFLAG_CS5520) == 0) {
 		u8 simplex_stat = 0;
-		dma_base += hwif->channel ? 8 : 0;
 
 		switch(dev->device) {
 			case PCI_DEVICE_ID_AL_M5219:
@@ -359,6 +363,8 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port
 	unsigned long ctl = 0, base = 0;
 	ide_hwif_t *hwif;
 	u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0;
+	u8 oldnoprobe = 0;
+	struct hw_regs_s hw;
 
 	if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
 		/*  Possibly we should fail if these checks report true */
@@ -381,26 +387,25 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port
 	}
 	if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL)
 		return NULL;	/* no room in ide_hwifs[] */
-	if (hwif->io_ports[IDE_DATA_OFFSET] != base ||
-	    hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) {
-		hw_regs_t hw;
-
-		memset(&hw, 0, sizeof(hw));
-#ifndef CONFIG_IDE_ARCH_OBSOLETE_INIT
-		ide_std_init_ports(&hw, base, ctl | 2);
-#else
-		ide_init_hwif_ports(&hw, base, ctl | 2, NULL);
-#endif
-		memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
-		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
-	}
-	hwif->chipset = d->chipset ? d->chipset : ide_pci;
+
+	memset(&hw, 0, sizeof(hw));
+	hw.irq = hwif->irq ? hwif->irq : irq;
+	hw.dev = &dev->dev;
+	hw.chipset = d->chipset ? d->chipset : ide_pci;
+	ide_std_init_ports(&hw, base, ctl | 2);
+
+	if (hwif->io_ports[IDE_DATA_OFFSET] == base &&
+	    hwif->io_ports[IDE_CONTROL_OFFSET] == (ctl | 2))
+		oldnoprobe = hwif->noprobe;
+
+	ide_init_port_hw(hwif, &hw);
+
+	hwif->noprobe = oldnoprobe;
+
 	hwif->pci_dev = dev;
 	hwif->cds = d;
 	hwif->channel = port;
 
-	if (!hwif->irq)
-		hwif->irq = irq;
 	if (mate) {
 		hwif->mate = mate;
 		mate->mate = hwif;
@@ -535,12 +540,8 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
 		if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
 			continue;
 
-		/* setup proper ancestral information */
-		hwif->gendev.parent = &dev->dev;
-
 		*(idx + port) = hwif->index;
 
-		
 		if (d->init_iops)
 			d->init_iops(hwif);
 
@@ -551,8 +552,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
 		    (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
 			hwif->irq = port ? 15 : 14;
 
-		hwif->fixup = d->fixup;
-
 		hwif->host_flags = d->host_flags;
 		hwif->pio_mask = d->pio_mask;
 
@@ -699,105 +698,3 @@ out:
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_pci_devices);
-
-#ifdef CONFIG_IDEPCI_PCIBUS_ORDER
-/*
- *	Module interfaces
- */
-
-static int pre_init = 1;		/* Before first ordered IDE scan */
-static LIST_HEAD(ide_pci_drivers);
-
-/*
- *	__ide_pci_register_driver	-	attach IDE driver
- *	@driver: pci driver
- *	@module: owner module of the driver
- *
- *	Registers a driver with the IDE layer. The IDE layer arranges that
- *	boot time setup is done in the expected device order and then
- *	hands the controllers off to the core PCI code to do the rest of
- *	the work.
- *
- *	Returns are the same as for pci_register_driver
- */
-
-int __ide_pci_register_driver(struct pci_driver *driver, struct module *module,
-			      const char *mod_name)
-{
-	if (!pre_init)
-		return __pci_register_driver(driver, module, mod_name);
-	driver->driver.owner = module;
-	list_add_tail(&driver->node, &ide_pci_drivers);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
-
-/**
- *	ide_scan_pcidev		-	find an IDE driver for a device
- *	@dev: PCI device to check
- *
- *	Look for an IDE driver to handle the device we are considering.
- *	This is only used during boot up to get the ordering correct. After
- *	boot up the pci layer takes over the job.
- */
-
-static int __init ide_scan_pcidev(struct pci_dev *dev)
-{
-	struct list_head *l;
-	struct pci_driver *d;
-
-	list_for_each(l, &ide_pci_drivers) {
-		d = list_entry(l, struct pci_driver, node);
-		if (d->id_table) {
-			const struct pci_device_id *id =
-				pci_match_id(d->id_table, dev);
-
-			if (id != NULL && d->probe(dev, id) >= 0) {
-				dev->driver = d;
-				pci_dev_get(dev);
-				return 1;
-			}
-		}
-	}
-	return 0;
-}
-
-/**
- *	ide_scan_pcibus		-	perform the initial IDE driver scan
- *	@scan_direction: set for reverse order scanning
- *
- *	Perform the initial bus rather than driver ordered scan of the
- *	PCI drivers. After this all IDE pci handling becomes standard
- *	module ordering not traditionally ordered.
- */
- 	
-void __init ide_scan_pcibus (int scan_direction)
-{
-	struct pci_dev *dev = NULL;
-	struct pci_driver *d;
-	struct list_head *l, *n;
-
-	pre_init = 0;
-	if (!scan_direction)
-		while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
-			ide_scan_pcidev(dev);
-	else
-		while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID,
-						     dev)))
-			ide_scan_pcidev(dev);
-
-	/*
-	 *	Hand the drivers over to the PCI layer now we
-	 *	are post init.
-	 */
-
-	list_for_each_safe(l, n, &ide_pci_drivers) {
-		list_del(l);
-		d = list_entry(l, struct pci_driver, node);
-		if (__pci_register_driver(d, d->driver.owner,
-					  d->driver.mod_name))
-			printk(KERN_ERR "%s: failed to register %s driver\n",
-					__FUNCTION__, d->driver.mod_name);
-	}
-}
-#endif
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 48d647a..eaba4a9 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -563,7 +563,8 @@ static void media_bay_step(int i)
 				ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL);
 				hw.irq = bay->cd_irq;
 				hw.chipset = ide_pmac;
-				bay->cd_index = ide_register_hw(&hw, NULL, 0, NULL);
+				bay->cd_index =
+					ide_register_hw(&hw, NULL, NULL);
 				pmu_resume();
 			}
 			if (bay->cd_index == -1) {
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index bd20a4e..49b7a4c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -143,7 +143,6 @@ enum rq_cmd_type_bits {
 	 * use REQ_TYPE_SPECIAL and use rq->cmd[0] with the range of driver
 	 * private REQ_LB opcodes to differentiate what type of request this is
 	 */
-	REQ_TYPE_ATA_CMD,
 	REQ_TYPE_ATA_TASKFILE,
 	REQ_TYPE_ATA_PC,
 };
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 1e44099..27cb39d 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -107,7 +107,6 @@ typedef unsigned char	byte;	/* used everywhere */
 #define BAD_W_STAT		(BAD_R_STAT  | WRERR_STAT)
 #define BAD_STAT		(BAD_R_STAT  | DRQ_STAT)
 #define DRIVE_READY		(READY_STAT  | SEEK_STAT)
-#define DATA_READY		(DRQ_STAT)
 
 #define BAD_CRC			(ABRT_ERR    | ICRC_ERR)
 
@@ -198,8 +197,11 @@ typedef struct hw_regs_s {
 } hw_regs_t;
 
 struct hwif_s * ide_find_port(unsigned long);
+void ide_init_port_data(struct hwif_s *, unsigned int);
+void ide_init_port_hw(struct hwif_s *, hw_regs_t *);
 
-int ide_register_hw(hw_regs_t *, void (*)(struct hwif_s *), int,
+struct ide_drive_s;
+int ide_register_hw(hw_regs_t *, void (*)(struct ide_drive_s *),
 		    struct hwif_s **);
 
 void ide_setup_ports(	hw_regs_t *hw,
@@ -391,7 +393,6 @@ typedef struct ide_drive_s {
 	u8	state;			/* retry state */
 	u8	waiting_for_dma;	/* dma currently in progress */
 	u8	unmask;			/* okay to unmask other irqs */
-	u8	bswap;			/* byte swap data */
 	u8	noflush;		/* don't attempt flushes */
 	u8	dsc_overlap;		/* DSC overlap */
 	u8	nice1;			/* give potential excess bandwidth */
@@ -527,31 +528,26 @@ typedef struct hwif_s {
 	/* special host masking for drive selection */
 	void	(*maskproc)(ide_drive_t *, int);
 	/* check host's drive quirk list */
-	int	(*quirkproc)(ide_drive_t *);
+	void	(*quirkproc)(ide_drive_t *);
 	/* driver soft-power interface */
 	int	(*busproc)(ide_drive_t *, int);
 #endif
 	u8 (*mdma_filter)(ide_drive_t *);
 	u8 (*udma_filter)(ide_drive_t *);
 
-	void (*fixup)(struct hwif_s *);
-
 	void (*ata_input_data)(ide_drive_t *, void *, u32);
 	void (*ata_output_data)(ide_drive_t *, void *, u32);
 
 	void (*atapi_input_bytes)(ide_drive_t *, void *, u32);
 	void (*atapi_output_bytes)(ide_drive_t *, void *, u32);
 
+	void (*dma_host_set)(ide_drive_t *, int);
 	int (*dma_setup)(ide_drive_t *);
 	void (*dma_exec_cmd)(ide_drive_t *, u8);
 	void (*dma_start)(ide_drive_t *);
 	int (*ide_dma_end)(ide_drive_t *drive);
-	int (*ide_dma_on)(ide_drive_t *drive);
-	void (*dma_off_quietly)(ide_drive_t *drive);
 	int (*ide_dma_test_irq)(ide_drive_t *drive);
 	void (*ide_dma_clear_irq)(ide_drive_t *drive);
-	void (*dma_host_on)(ide_drive_t *drive);
-	void (*dma_host_off)(ide_drive_t *drive);
 	void (*dma_lost_irq)(ide_drive_t *drive);
 	void (*dma_timeout)(ide_drive_t *drive);
 
@@ -874,14 +870,6 @@ extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t);
 
 extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
 
-/*
- * Issue ATA command and wait for completion.
- * Use for implementing commands in kernel
- *
- *  (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
- */
-extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
-
 enum {
 	IDE_TFLAG_LBA48			= (1 << 0),
 	IDE_TFLAG_NO_SELECT_MASK	= (1 << 1),
@@ -934,6 +922,14 @@ enum {
 	IDE_TFLAG_IN_TF			= IDE_TFLAG_IN_NSECT |
 					  IDE_TFLAG_IN_LBA,
 	IDE_TFLAG_IN_DEVICE		= (1 << 29),
+	IDE_TFLAG_HOB			= IDE_TFLAG_OUT_HOB |
+					  IDE_TFLAG_IN_HOB,
+	IDE_TFLAG_TF			= IDE_TFLAG_OUT_TF |
+					  IDE_TFLAG_IN_TF,
+	IDE_TFLAG_DEVICE		= IDE_TFLAG_OUT_DEVICE |
+					  IDE_TFLAG_IN_DEVICE,
+	/* force 16-bit I/O operations */
+	IDE_TFLAG_IO_16BIT		= (1 << 30),
 };
 
 struct ide_taskfile {
@@ -988,6 +984,10 @@ void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8);
 
 ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);
 
+void task_end_request(ide_drive_t *, struct request *, u8);
+
+u8 wait_drive_not_busy(ide_drive_t *);
+
 int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16);
 int ide_no_data_taskfile(ide_drive_t *, ide_task_t *);
 
@@ -1015,10 +1015,9 @@ extern void do_ide_request(struct request_queue *);
 
 void ide_init_disk(struct gendisk *, ide_drive_t *);
 
-extern int ideprobe_init(void);
-
 #ifdef CONFIG_IDEPCI_PCIBUS_ORDER
-extern void ide_scan_pcibus(int scan_direction) __init;
+extern int ide_scan_direction;
+int __init ide_scan_pcibus(void);
 extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name);
 #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME)
 #else
@@ -1095,6 +1094,8 @@ enum {
 	/* unmask IRQs */
 	IDE_HFLAG_UNMASK_IRQS		= (1 << 25),
 	IDE_HFLAG_ABUSE_SET_DMA_MODE	= (1 << 26),
+	/* host is CY82C693 */
+	IDE_HFLAG_CY82C693		= (1 << 27),
 };
 
 #ifdef CONFIG_BLK_DEV_OFFBOARD
@@ -1109,7 +1110,6 @@ struct ide_port_info {
 	void			(*init_iops)(ide_hwif_t *);
 	void                    (*init_hwif)(ide_hwif_t *);
 	void			(*init_dma)(ide_hwif_t *, unsigned long);
-	void			(*fixup)(ide_hwif_t *);
 	ide_pci_enablebit_t	enablebits[2];
 	hwif_chipset_t		chipset;
 	u8			extra;
@@ -1147,7 +1147,9 @@ static inline u8 ide_max_dma_mode(ide_drive_t *drive)
 	return ide_find_dma_mode(drive, XFER_UDMA_6);
 }
 
+void ide_dma_off_quietly(ide_drive_t *);
 void ide_dma_off(ide_drive_t *);
+void ide_dma_on(ide_drive_t *);
 int ide_set_dma(ide_drive_t *);
 ide_startstop_t ide_dma_intr(ide_drive_t *);
 
@@ -1158,10 +1160,7 @@ extern void ide_destroy_dmatable(ide_drive_t *);
 extern int ide_release_dma(ide_hwif_t *);
 extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
 
-void ide_dma_host_off(ide_drive_t *);
-void ide_dma_off_quietly(ide_drive_t *);
-void ide_dma_host_on(ide_drive_t *);
-extern int __ide_dma_on(ide_drive_t *);
+void ide_dma_host_set(ide_drive_t *, int);
 extern int ide_dma_setup(ide_drive_t *);
 extern void ide_dma_start(ide_drive_t *);
 extern int __ide_dma_end(ide_drive_t *);
@@ -1173,7 +1172,9 @@ extern void ide_dma_timeout(ide_drive_t *);
 static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; }
 static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
 static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
+static inline void ide_dma_off_quietly(ide_drive_t *drive) { ; }
 static inline void ide_dma_off(ide_drive_t *drive) { ; }
+static inline void ide_dma_on(ide_drive_t *drive) { ; }
 static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
 static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -1203,8 +1204,9 @@ extern void ide_unregister (unsigned int index);
 void ide_register_region(struct gendisk *);
 void ide_unregister_region(struct gendisk *);
 
-void ide_undecoded_slave(ide_hwif_t *);
+void ide_undecoded_slave(ide_drive_t *);
 
+int ide_device_add_all(u8 *idx);
 int ide_device_add(u8 idx[4]);
 
 static inline void *ide_get_hwifdata (ide_hwif_t * hwif)
@@ -1302,4 +1304,9 @@ static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive)
 	return &hwif->drives[(drive->dn ^ 1) & 1];
 }
 
+static inline void ide_set_irq(ide_drive_t *drive, int on)
+{
+	drive->hwif->OUTB(drive->ctl | (on ? 0 : 2), IDE_CONTROL_REG);
+}
+
 #endif /* _IDE_H */

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>  (linux.* mail to news gateway)
  2008-01-26 19:43 [git patches] IDE updates part #2 Bartlomiej Zolnierkiewicz
@ 2008-01-26 20:31 ` Frans Pop
  2008-01-26 20:42   ` Jan Engelhardt
  0 siblings, 1 reply; 7+ messages in thread
From: Frans Pop @ 2008-01-26 20:31 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel, torvalds

>  config BLK_DEV_IDE_PMAC
> -       bool "Builtin PowerMac IDE support"
> +       tristate "Builtin PowerMac IDE support"

This does not seem to make sense: if the option is now tristate, it is no
longer "Builtin", so probably s/Builtin // in the description.

Cheers,
FJP

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>  (linux.* mail to news gateway)
  2008-01-26 20:31 ` From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> (linux.* mail to news gateway) Frans Pop
@ 2008-01-26 20:42   ` Jan Engelhardt
  2008-01-26 21:08     ` Bartlomiej Zolnierkiewicz
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Engelhardt @ 2008-01-26 20:42 UTC (permalink / raw)
  To: Frans Pop; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, linux-kernel, torvalds


On Jan 26 2008 21:31, Frans Pop wrote:
>>  config BLK_DEV_IDE_PMAC
>> -       bool "Builtin PowerMac IDE support"
>> +       tristate "Builtin PowerMac IDE support"
>
>This does not seem to make sense: if the option is now tristate, it is no
>longer "Builtin", so probably s/Builtin // in the description.

Or something like s/Builtin/Onboard/;

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>  (linux.* mail to news gateway)
  2008-01-26 20:42   ` Jan Engelhardt
@ 2008-01-26 21:08     ` Bartlomiej Zolnierkiewicz
  2008-01-27 15:20       ` [PATCH] Use on-board instead of built-in in config options Frans Pop
  0 siblings, 1 reply; 7+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-01-26 21:08 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Frans Pop, linux-ide, linux-kernel, torvalds

On Saturday 26 January 2008, Jan Engelhardt wrote:
> 
> On Jan 26 2008 21:31, Frans Pop wrote:
> >>  config BLK_DEV_IDE_PMAC
> >> -       bool "Builtin PowerMac IDE support"
> >> +       tristate "Builtin PowerMac IDE support"

this change is no-op at the moment because the next Kconfig line is:

	depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y

[ PPC-specific IDE host drivers are still a special case because they are
  using ppc_ide_md architecture hooks instead of doing proper host driver
  initialization sequence - to be fixed after adding warm-plug support... ]

> >This does not seem to make sense: if the option is now tristate, it is no
> >longer "Builtin", so probably s/Builtin // in the description.
> 
> Or something like s/Builtin/Onboard/;

Please send a patch.

Thanks,
Bart

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] Use on-board instead of built-in in config options
  2008-01-26 21:08     ` Bartlomiej Zolnierkiewicz
@ 2008-01-27 15:20       ` Frans Pop
  2008-02-01 21:49         ` Bartlomiej Zolnierkiewicz
  0 siblings, 1 reply; 7+ messages in thread
From: Frans Pop @ 2008-01-27 15:20 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz
  Cc: Jan Engelhardt, linux-ide, linux-kernel, torvalds

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

On Saturday 26 January 2008, Bartlomiej Zolnierkiewicz wrote:
> On Saturday 26 January 2008, Jan Engelhardt wrote:
> > On Jan 26 2008 21:31, Frans Pop wrote:
> > >>  config BLK_DEV_IDE_PMAC
> > >> -       bool "Builtin PowerMac IDE support"
> > >> +       tristate "Builtin PowerMac IDE support"
>
> this change is no-op at the moment because the next Kconfig line is:
>
> 	depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y
>
> [ PPC-specific IDE host drivers are still a special case because they are
>   using ppc_ide_md architecture hooks instead of doing proper host driver
>   initialization sequence - to be fixed after adding warm-plug support...
> ]
>
> > >This does not seem to make sense: if the option is now tristate, it is
> > > no longer "Builtin", so probably s/Builtin // in the description.
> >
> > Or something like s/Builtin/Onboard/;

I did not even consider that meaning of built-in, but that does seem more 
descriptive.

> Please send a patch.

Of course :-)

---
From: Frans Pop <elendil@planet.nl>

To avoid confusion between 'built-in' drivers and 'on-board'
controllers, consistently use the term 'on-board' for controllers.

Minor line-wrapping improvements in descriptions for config options.

Signed-off-by: Frans Pop <elendil@planet.nl>

---
Spelling for on-board seems to be rather inconsistent. All of "on board",
"on-board" and onboard currently occur. I've chosen "on-board" as that seems 
most correct to me.


[-- Attachment #2: ide_use_on-board.patch --]
[-- Type: text/x-diff, Size: 6070 bytes --]

diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 64df55e..92b0117 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -617,8 +617,8 @@ config BLK_DEV_SC1200
 	tristate "National SCx200 chipset support"
 	select BLK_DEV_IDEDMA_PCI
 	help
-	  This driver adds support for the built in IDE on the National
-	  SCx200 series of embedded x86 "Geode" systems
+	  This driver adds support for the on-board IDE controller on the
+	  National SCx200 series of embedded x86 "Geode" systems.
 
 config BLK_DEV_PIIX
 	tristate "Intel PIIXn chipsets support"
@@ -793,22 +793,22 @@ config BLK_DEV_CELLEB
 	depends on PPC_CELLEB
 	select BLK_DEV_IDEDMA_PCI
 	help
-	  This driver provides support for the built-in IDE controller on
+	  This driver provides support for the on-board IDE controller on
 	  Toshiba Cell Reference Board.
 	  If unsure, say Y.
 
 endif
 
 config BLK_DEV_IDE_PMAC
-	tristate "Builtin PowerMac IDE support"
+	tristate "PowerMac on-board IDE support"
 	depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y
 	help
-	  This driver provides support for the built-in IDE controller on
+	  This driver provides support for the on-board IDE controller on
 	  most of the recent Apple Power Macintoshes and PowerBooks.
 	  If unsure, say Y.
 
 config BLK_DEV_IDE_PMAC_ATA100FIRST
-	bool "Probe internal ATA/100 (Kauai) first"
+	bool "Probe on-board ATA/100 (Kauai) first"
 	depends on BLK_DEV_IDE_PMAC
 	help
 	  This option will cause the ATA/100 controller found in UniNorth2
@@ -823,7 +823,7 @@ config BLK_DEV_IDEDMA_PMAC
 	depends on BLK_DEV_IDE_PMAC
 	select BLK_DEV_IDEDMA_PCI
 	help
-	  This option allows the driver for the built-in IDE controller on
+	  This option allows the driver for the on-board IDE controller on
 	  Power Macintoshes and PowerBooks to use DMA (direct memory access)
 	  to transfer data to and from memory.  Saying Y is safe and improves
 	  performance.
@@ -934,7 +934,7 @@ config BLK_DEV_GAYLE
 	help
 	  This is the IDE driver for the Amiga Gayle IDE interface. It supports
 	  both the `A1200 style' and `A4000 style' of the Gayle IDE interface,
-	  This includes builtin IDE interfaces on some Amiga models (A600,
+	  This includes on-board IDE interfaces on some Amiga models (A600,
 	  A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion
 	  bus (M-Tech E-Matrix 530 expansion card).
 	  Say Y if you have an Amiga with a Gayle IDE interface and want to use
@@ -948,10 +948,10 @@ config BLK_DEV_IDEDOUBLER
 	depends on BLK_DEV_GAYLE && EXPERIMENTAL
 	---help---
 	  This driver provides support for the so-called `IDE doublers' (made
-	  by various manufacturers, e.g. Eyetech) that can be connected to the
-	  builtin IDE interface of some Amiga models. Using such an IDE
-	  doubler, you can connect up to four instead of two IDE devices on
-	  the Amiga's builtin IDE interface.
+	  by various manufacturers, e.g. Eyetech) that can be connected to
+	  the on-board IDE interface of some Amiga models. Using such an IDE
+	  doubler, you can connect up to four instead of two IDE devices to
+	  the Amiga's on-board IDE interface.
 
 	  Note that the normal Amiga Gayle IDE driver may not work correctly
 	  if you have an IDE doubler and don't enable this driver!
@@ -963,9 +963,9 @@ config BLK_DEV_BUDDHA
 	tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
 	depends on ZORRO && EXPERIMENTAL
 	help
-	  This is the IDE driver for the IDE interfaces on the Buddha, 
-	  Catweasel and X-Surf expansion boards.  It supports up to two interfaces 
-	  on the Buddha, three on the Catweasel and two on the X-Surf.
+	  This is the IDE driver for the IDE interfaces on the Buddha, Catweasel
+	  and X-Surf expansion boards.  It supports up to two interfaces on the
+	  Buddha, three on the Catweasel and two on the X-Surf.
 
 	  Say Y if you have a Buddha or Catweasel expansion board and want to
 	  use IDE devices (hard disks, CD-ROM drives, etc.) that are connected
@@ -975,23 +975,23 @@ config BLK_DEV_FALCON_IDE
 	tristate "Falcon IDE interface support"
 	depends on ATARI
 	help
-	  This is the IDE driver for the builtin IDE interface on the Atari
+	  This is the IDE driver for the on-board IDE interface on the Atari
 	  Falcon. Say Y if you have a Falcon and want to use IDE devices (hard
-	  disks, CD-ROM drives, etc.) that are connected to the builtin IDE
+	  disks, CD-ROM drives, etc.) that are connected to the on-board IDE
 	  interface.
 
 config BLK_DEV_MAC_IDE
 	tristate "Macintosh Quadra/Powerbook IDE interface support"
 	depends on MAC
 	help
-	  This is the IDE driver for the builtin IDE interface on some m68k
+	  This is the IDE driver for the on-board IDE interface on some m68k
 	  Macintosh models. It supports both the `Quadra style' (used in
 	  Quadra/ Centris 630 and Performa 588 models) and `Powerbook style'
 	  (used in the Powerbook 150 and 190 models) IDE interface.
 
 	  Say Y if you have such an Macintosh model and want to use IDE
 	  devices (hard disks, CD-ROM drives, etc.) that are connected to the
-	  builtin IDE interface.
+	  on-board IDE interface.
 
 config BLK_DEV_Q40IDE
 	tristate "Q40/Q60 IDE interface support"
@@ -1062,8 +1062,8 @@ config BLK_DEV_ALI14XX
 	  boot parameter.  It enables support for the secondary IDE interface
 	  of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster
 	  I/O speeds to be set as well.  See the files
-	  <file:Documentation/ide.txt> and <file:drivers/ide/legacy/ali14xx.c> for
-	  more info.
+	  <file:Documentation/ide.txt> and <file:drivers/ide/legacy/ali14xx.c>
+	  for more info.
 
 config BLK_DEV_DTC2278
 	tristate "DTC-2278 support"
@@ -1088,8 +1088,8 @@ config BLK_DEV_QD65XX
 	help
 	  This driver is enabled at runtime using the "qd65xx.probe" kernel
 	  boot parameter.  It permits faster I/O speeds to be set.  See the
-	  <file:Documentation/ide.txt> and <file:drivers/ide/legacy/qd65xx.c> for
-	  more info.
+	  <file:Documentation/ide.txt> and <file:drivers/ide/legacy/qd65xx.c>
+	  for more info.
 
 config BLK_DEV_UMC8672
 	tristate "UMC-8672 support"

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Use on-board instead of built-in in config options
  2008-01-27 15:20       ` [PATCH] Use on-board instead of built-in in config options Frans Pop
@ 2008-02-01 21:49         ` Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 7+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-02-01 21:49 UTC (permalink / raw)
  To: Frans Pop; +Cc: Jan Engelhardt, linux-ide, linux-kernel, torvalds

On Sunday 27 January 2008, Frans Pop wrote:
> On Saturday 26 January 2008, Bartlomiej Zolnierkiewicz wrote:
> > On Saturday 26 January 2008, Jan Engelhardt wrote:
> > > On Jan 26 2008 21:31, Frans Pop wrote:
> > > >>  config BLK_DEV_IDE_PMAC
> > > >> -       bool "Builtin PowerMac IDE support"
> > > >> +       tristate "Builtin PowerMac IDE support"
> >
> > this change is no-op at the moment because the next Kconfig line is:
> >
> > 	depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y
> >
> > [ PPC-specific IDE host drivers are still a special case because they are
> >   using ppc_ide_md architecture hooks instead of doing proper host driver
> >   initialization sequence - to be fixed after adding warm-plug support...
> > ]
> >
> > > >This does not seem to make sense: if the option is now tristate, it is
> > > > no longer "Builtin", so probably s/Builtin // in the description.
> > >
> > > Or something like s/Builtin/Onboard/;
> 
> I did not even consider that meaning of built-in, but that does seem more 
> descriptive.
> 
> > Please send a patch.
> 
> Of course :-)
> 
> ---
> From: Frans Pop <elendil@planet.nl>
> 
> To avoid confusion between 'built-in' drivers and 'on-board'
> controllers, consistently use the term 'on-board' for controllers.
> 
> Minor line-wrapping improvements in descriptions for config options.
> 
> Signed-off-by: Frans Pop <elendil@planet.nl>

applied, thanks

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [git patches] IDE updates part 2
@ 2008-04-26 16:12 Bartlomiej Zolnierkiewicz
  0 siblings, 0 replies; 7+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-04-26 16:12 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Andrew Morton, Stephen Rothwell, Al Viro Al, linux-ide, linux-kernel


Contains:

- critical+obvious execve() fix from Al (not an IDE fix but included here
  to have IDE changes fully bisectable in the mainline)

- fix the infamous ide_4drives allmodconfig error (Frederik Deweerdt)

- fix checking of PCI BARs 0-3 for standard IDE PCI controllers
  (Sergei Shtylyov)

- rework of I/O and MEM resource handling (me)

- preparations for removal of the static array of IDE interfaces (me)

- a lot of coding style fixes (Paolo Ciarrocchi)

- removal of the internal 64k buffer from ide-cd (Borislav Petkov)

- and more (thanks to all people contributing)


PS1 There are still 3-4 IDE updates to go.

PS2 I'm still catching up with the patches/mail from the last week so if
    you've sent me something recently please give me few more days for reply
    before re-sending.


Linus, please pull from:

master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6.git/

to receive the following updates:

 drivers/ide/Kconfig               |    2 +-
 drivers/ide/arm/bast-ide.c        |   12 +-
 drivers/ide/arm/icside.c          |    2 +-
 drivers/ide/arm/ide_arm.c         |    2 +-
 drivers/ide/arm/palm_bk3710.c     |   26 ++--
 drivers/ide/arm/rapide.c          |    2 +-
 drivers/ide/cris/ide-cris.c       |    2 +-
 drivers/ide/h8300/ide-h8300.c     |    3 +-
 drivers/ide/ide-cd.c              |  412 ++++++++++++++-----------------------
 drivers/ide/ide-cd.h              |    4 -
 drivers/ide/ide-disk.c            |  159 ++++++++-------
 drivers/ide/ide-dma.c             |   13 +-
 drivers/ide/ide-floppy.c          |   16 +-
 drivers/ide/ide-generic.c         |   16 ++-
 drivers/ide/ide-io.c              |    4 -
 drivers/ide/ide-lib.c             |   22 +-
 drivers/ide/ide-pnp.c             |   12 +-
 drivers/ide/ide-probe.c           |   48 +++++
 drivers/ide/ide-proc.c            |  155 +++++++-------
 drivers/ide/ide.c                 |   69 ++-----
 drivers/ide/legacy/ali14xx.c      |   30 ++-
 drivers/ide/legacy/buddha.c       |    2 +-
 drivers/ide/legacy/dtc2278.c      |   22 +-
 drivers/ide/legacy/falconide.c    |    9 +-
 drivers/ide/legacy/gayle.c        |    2 +-
 drivers/ide/legacy/hd.c           |   78 ++++----
 drivers/ide/legacy/ht6560b.c      |   34 ++--
 drivers/ide/legacy/ide-4drives.c  |   36 ++--
 drivers/ide/legacy/ide-cs.c       |    2 +-
 drivers/ide/legacy/ide_platform.c |    7 +-
 drivers/ide/legacy/macide.c       |    2 +-
 drivers/ide/legacy/q40ide.c       |    2 +-
 drivers/ide/legacy/qd65xx.c       |  165 +++++++--------
 drivers/ide/legacy/qd65xx.h       |    1 -
 drivers/ide/legacy/umc8672.c      |   81 ++++----
 drivers/ide/mips/au1xxx-ide.c     |    8 +-
 drivers/ide/mips/swarm.c          |    9 +-
 drivers/ide/pci/aec62xx.c         |    3 +-
 drivers/ide/pci/alim15x3.c        |    1 -
 drivers/ide/pci/amd74xx.c         |    4 +-
 drivers/ide/pci/atiixp.c          |    5 +-
 drivers/ide/pci/cmd640.c          |  188 +++++++++---------
 drivers/ide/pci/cmd64x.c          |    9 +-
 drivers/ide/pci/cs5520.c          |    3 +-
 drivers/ide/pci/cs5530.c          |    3 +-
 drivers/ide/pci/cs5535.c          |    2 +-
 drivers/ide/pci/cy82c693.c        |   77 ++++----
 drivers/ide/pci/delkin_cb.c       |    6 +-
 drivers/ide/pci/generic.c         |   10 +-
 drivers/ide/pci/hpt34x.c          |    2 +-
 drivers/ide/pci/hpt366.c          |    2 +-
 drivers/ide/pci/it8213.c          |   12 +-
 drivers/ide/pci/it821x.c          |   25 ++-
 drivers/ide/pci/jmicron.c         |    4 +-
 drivers/ide/pci/ns87415.c         |    3 +-
 drivers/ide/pci/opti621.c         |   61 +++---
 drivers/ide/pci/piix.c            |    4 +-
 drivers/ide/pci/rz1000.c          |    2 +-
 drivers/ide/pci/sc1200.c          |    3 +-
 drivers/ide/pci/scc_pata.c        |   17 +-
 drivers/ide/pci/serverworks.c     |    5 +-
 drivers/ide/pci/sgiioc4.c         |   12 +-
 drivers/ide/pci/siimage.c         |    1 -
 drivers/ide/pci/sis5513.c         |  225 ++++++++++----------
 drivers/ide/pci/sl82c105.c        |    3 +-
 drivers/ide/pci/slc90e66.c        |    8 +-
 drivers/ide/pci/tc86c001.c        |   28 ++--
 drivers/ide/pci/triflex.c         |    1 -
 drivers/ide/pci/trm290.c          |    1 -
 drivers/ide/pci/via82cxxx.c       |    4 +-
 drivers/ide/ppc/mpc8xx.c          |   58 ++++--
 drivers/ide/ppc/pmac.c            |   90 +++++----
 drivers/ide/setup-pci.c           |  129 +++---------
 include/linux/Kbuild              |    1 -
 include/linux/hdsmart.h           |  126 -----------
 include/linux/ide.h               |   23 ++-
 kernel/fork.c                     |    2 +-
 77 files changed, 1195 insertions(+), 1439 deletions(-)
 delete mode 100644 include/linux/hdsmart.h


Adrian Bunk (1):
      remove include/linux/hdsmart.h

Al Viro (1):
      fix execve()

Bartlomiej Zolnierkiewicz (35):
      ide: cleanup ide_match_hwif()
      ide: cleanup ide_find_port()
      swarm: use ide_find_port()
      ide-pmac: dynamically allocate struct pmac_ide_hwif instances (take 2)
      ide-pmac: use ide_find_port()
      sgiioc4: use ide_find_port()
      scc_pata: use ide_find_port()
      au1xxx-ide: use ide_find_port()
      cmd640: remove cmd_drives[]
      cmd640: use ide_find_port()
      scc_pata: store 'hwif' pointer in struct scc_ports
      umc8672: don't use ide_hwifs[] in umc_set_pio_mode()
      ht6560b: use driver name for resource allocation
      qd65xx: return error value in qd_probe()
      ide: IDE_HFLAG_BOOTABLE -> IDE_HFLAG_NON_BOOTABLE
      ide: remove PIO "downgrade" quirk
      ide: merge ide_match_hwif() and ide_find_port()
      ide: use ide_find_port() in legacy VLB host drivers (take 2)
      ide-generic: use ide_find_port() (take 3)
      ide: unexport ide_hwifs[]
      ide-disk: add proc_idedisk_read_smart() helper
      ide-disk: fix issues found by checkpatch.pl
      ide_platform: fix resources handling
      delkin_cb: fix resources handling
      bast-ide: fix resources reservation
      ide-mpc8xx: make m8xx_ide_init_ports() return an error value
      ide-mpc8xx: fix resources reservation
      falconide: fix resources reservation (take 2)
      ide: remove IDE_HFLAG_CY82C693 host flag
      ide: remove hwif->straight8 flag
      qd65xx: always use ->selectproc method
      qd65xx: use IDE_HFLAG_SINGLE host flag
      it821x: fix kzalloc() failure handling
      sis5513: fail early for unsupported chipsets
      ide: sanitize handling of IDE_HFLAG_NO_SET_MODE host flag

Borislav Petkov (2):
      ide-cd: remove the internal 64k buffer
      ide-cd: put proc-related functions together under single ifdef

Frederik Deweerdt (1):
      ide/Kconfig: BLK_DEV_4DRIVES should be a tristate

Julia Lawall (1):
      ide: use DIV_ROUND_UP

Paolo Ciarrocchi (19):
      IDE: Coding Style fixes to drivers/ide/setup-pci.c
      IDE: Coding Style fixes to drivers/ide/pci/tc86c001.c
      IDE: Coding Style fixes to drivers/ide/pci/slc90e66.c
      IDE: Coding Style fixes to drivers/ide/pci/sis5513.c
      IDE: Coding Style fixes to drivers/ide/pci/jmicron.c
      IDE: Coding Style fixes to drivers/ide/pci/generic.c
      IDE: Coding Style fixes to drivers/ide/legacy/umc8672.c
      IDE: Coding Style fixes to drivers/ide/legacy/ide-4drives.c
      IDE: Coding Style fixes to drivers/ide/ide-proc.c
      IDE: Coding Style fixes to drivers/ide/ide-pnp.c
      IDE: Coding Style fixes to drivers/ide/pci/opti621.c
      IDE: Coding Style fixes to drivers/ide/pci/cmd640.c
      IDE: Coding Style fixes to drivers/ide/legacy/hd.c
      IDE: Coding Style fixes to drivers/ide/legacy/ali14xx.c
      IDE: Coding Style fixes to drivers/ide/ide-floppy.c
      IDE: Coding Style fixes to drivers/ide/pci/it8213.c
      IDE: Coding Style fixes to drivers/ide/pci/cy82c693.c
      IDE: Coding Style fixes to drivers/ide/ide-cd.c
      ide-cd: Replace __FUNCTION__ with __func__

Sergei Shtylyov (1):
      ide: make ide_pci_check_iomem() actually work


diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 8753203..3f9e100 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -1031,7 +1031,7 @@ comment "Other IDE chipsets support"
 comment "Note: most of these also require special kernel boot parameters"
 
 config BLK_DEV_4DRIVES
-	bool "Generic 4 drives/port support"
+	tristate "Generic 4 drives/port support"
 	help
 	  Certain older chipsets, including the Tekram 690CD, use a single set
 	  of I/O ports at 0x1f0 to control up to four drives, instead of the
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
index ec46c44..a80b957 100644
--- a/drivers/ide/arm/bast-ide.c
+++ b/drivers/ide/arm/bast-ide.c
@@ -21,6 +21,8 @@
 #include <asm/arch/bast-map.h>
 #include <asm/arch/bast-irq.h>
 
+#define DRV_NAME "bast-ide"
+
 static int __init bastide_register(unsigned int base, unsigned int aux, int irq)
 {
 	ide_hwif_t *hwif;
@@ -41,7 +43,7 @@ static int __init bastide_register(unsigned int base, unsigned int aux, int irq)
 	hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
 	hw.irq = irq;
 
-	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	hwif = ide_find_port();
 	if (hwif == NULL)
 		goto out;
 
@@ -53,6 +55,7 @@ static int __init bastide_register(unsigned int base, unsigned int aux, int irq)
 		ide_init_port_data(hwif, i);
 
 	ide_init_port_hw(hwif, &hw);
+	hwif->mmio = 1;
 	hwif->quirkproc = NULL;
 
 	idx[0] = i;
@@ -64,6 +67,8 @@ out:
 
 static int __init bastide_init(void)
 {
+	unsigned long base = BAST_VA_IDEPRI + BAST_IDE_CS;
+
 	/* we can treat the VR1000 and the BAST the same */
 
 	if (!(machine_is_bast() || machine_is_vr1000()))
@@ -71,6 +76,11 @@ static int __init bastide_init(void)
 
 	printk("BAST: IDE driver, (c) 2003-2004 Simtec Electronics\n");
 
+	if (!request_mem_region(base, 0x400000, DRV_NAME)) {
+		printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+		return -EBUSY;
+	}
+
 	bastide_register(BAST_VA_IDEPRI, BAST_VA_IDEPRIAUX, IRQ_IDE0);
 	bastide_register(BAST_VA_IDESEC, BAST_VA_IDESECAUX, IRQ_IDE1);
 
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index e816b0f..fd12bbe 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -400,7 +400,7 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e
 	unsigned long port = (unsigned long)base + info->dataoffset;
 	ide_hwif_t *hwif;
 
-	hwif = ide_find_port(port);
+	hwif = ide_find_port();
 	if (hwif) {
 		int i;
 
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
index be9ff73..82643df 100644
--- a/drivers/ide/arm/ide_arm.c
+++ b/drivers/ide/arm/ide_arm.c
@@ -34,7 +34,7 @@ static int __init ide_arm_init(void)
 	ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206);
 	hw.irq = IDE_ARM_IRQ;
 
-	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	hwif = ide_find_port();
 	if (hwif) {
 		ide_init_port_hw(hwif, &hw);
 		idx[0] = hwif->index;
diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c
index 420fcb7..666df77 100644
--- a/drivers/ide/arm/palm_bk3710.c
+++ b/drivers/ide/arm/palm_bk3710.c
@@ -96,11 +96,11 @@ static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
 	u16 val16;
 
 	/* DMA Data Setup */
-	t0 = (palm_bk3710_udmatimings[mode].cycletime + ide_palm_clk - 1)
-			/ ide_palm_clk - 1;
-	tenv = (20 + ide_palm_clk - 1) / ide_palm_clk - 1;
-	trp = (palm_bk3710_udmatimings[mode].rptime + ide_palm_clk - 1)
-			/ ide_palm_clk - 1;
+	t0 = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].cycletime,
+			  ide_palm_clk) - 1;
+	tenv = DIV_ROUND_UP(20, ide_palm_clk) - 1;
+	trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime,
+			   ide_palm_clk) - 1;
 
 	/* udmatim Register */
 	val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0);
@@ -141,8 +141,8 @@ static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev,
 	cycletime = max_t(int, t->cycle, min_cycle);
 
 	/* DMA Data Setup */
-	t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk;
-	td = (t->active + ide_palm_clk - 1) / ide_palm_clk;
+	t0 = DIV_ROUND_UP(cycletime, ide_palm_clk);
+	td = DIV_ROUND_UP(t->active, ide_palm_clk);
 	tkw = t0 - td - 1;
 	td -= 1;
 
@@ -168,9 +168,9 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
 	struct ide_timing *t;
 
 	/* PIO Data Setup */
-	t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk;
-	t2 = (ide_timing_find_mode(XFER_PIO_0 + mode)->active +
-	      ide_palm_clk - 1)	/ ide_palm_clk;
+	t0 = DIV_ROUND_UP(cycletime, ide_palm_clk);
+	t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active,
+			  ide_palm_clk);
 
 	t2i = t0 - t2 - 1;
 	t2 -= 1;
@@ -192,8 +192,8 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
 
 	/* TASKFILE Setup */
 	t = ide_timing_find_mode(XFER_PIO_0 + mode);
-	t0 = (t->cyc8b + ide_palm_clk - 1) / ide_palm_clk;
-	t2 = (t->act8b + ide_palm_clk - 1) / ide_palm_clk;
+	t0 = DIV_ROUND_UP(t->cyc8b, ide_palm_clk);
+	t2 = DIV_ROUND_UP(t->act8b, ide_palm_clk);
 
 	t2i = t0 - t2 - 1;
 	t2 -= 1;
@@ -378,7 +378,7 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
 	hw.irq = irq->start;
 	hw.chipset = ide_palm3710;
 
-	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	hwif = ide_find_port();
 	if (hwif == NULL)
 		goto out;
 
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index b30adcf..2c3d0ec 100644
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -44,7 +44,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
 		goto release;
 	}
 
-	hwif = ide_find_port((unsigned long)base);
+	hwif = ide_find_port();
 	if (hwif) {
 		memset(&hw, 0, sizeof(hw));
 		rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq);
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 31266d2..790a775 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -804,7 +804,7 @@ static int __init init_e100_ide(void)
 
 		cris_setup_ports(&hw, cris_ide_base_address(h));
 
-		hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+		hwif = ide_find_port();
 		if (hwif == NULL)
 			continue;
 		ide_init_port_data(hwif, hwif->index);
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index 4108ec4..92b02b9 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -99,8 +99,7 @@ static int __init h8300_ide_init(void)
 
 	hw_setup(&hw);
 
-	/* register if */
-	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	hwif = ide_find_port();
 	if (hwif == NULL) {
 		printk(KERN_ERR "ide-h8300: IDE I/F register failed\n");
 		return -ENOENT;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index fe5aefb..1afd95a 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -13,8 +13,8 @@
  *
  * Suggestions are welcome. Patches that work are more welcome though. ;-)
  * For those wishing to work on this driver, please be sure you download
- * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI 
- * (SFF-8020i rev 2.6) standards. These documents can be obtained by 
+ * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
+ * (SFF-8020i rev 2.6) standards. These documents can be obtained by
  * anonymous ftp from:
  * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
  * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
@@ -51,7 +51,7 @@
 
 static DEFINE_MUTEX(idecd_ref_mutex);
 
-#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) 
+#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref)
 
 #define ide_cd_g(disk) \
 	container_of((disk)->private_data, struct cdrom_info, driver)
@@ -83,13 +83,12 @@ static void ide_cd_put(struct cdrom_info *cd)
 
 /* Mark that we've seen a media change, and invalidate our internal
    buffers. */
-static void cdrom_saw_media_change (ide_drive_t *drive)
+static void cdrom_saw_media_change(ide_drive_t *drive)
 {
 	struct cdrom_info *cd = drive->driver_data;
 
 	cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED;
 	cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
-	cd->nsectors_buffered = 0;
 }
 
 static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
@@ -101,38 +100,39 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
 		return 0;
 
 	switch (sense->sense_key) {
-		case NO_SENSE: case RECOVERED_ERROR:
-			break;
-		case NOT_READY:
-			/*
-			 * don't care about tray state messages for
-			 * e.g. capacity commands or in-progress or
-			 * becoming ready
-			 */
-			if (sense->asc == 0x3a || sense->asc == 0x04)
-				break;
-			log = 1;
-			break;
-		case ILLEGAL_REQUEST:
-			/*
-			 * don't log START_STOP unit with LoEj set, since
-			 * we cannot reliably check if drive can auto-close
-			 */
-			if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
-				break;
-			log = 1;
-			break;
-		case UNIT_ATTENTION:
-			/*
-			 * Make good and sure we've seen this potential media
-			 * change. Some drives (i.e. Creative) fail to present
-			 * the correct sense key in the error register.
-			 */
-			cdrom_saw_media_change(drive);
+	case NO_SENSE:
+	case RECOVERED_ERROR:
+		break;
+	case NOT_READY:
+		/*
+		 * don't care about tray state messages for
+		 * e.g. capacity commands or in-progress or
+		 * becoming ready
+		 */
+		if (sense->asc == 0x3a || sense->asc == 0x04)
 			break;
-		default:
-			log = 1;
+		log = 1;
+		break;
+	case ILLEGAL_REQUEST:
+		/*
+		 * don't log START_STOP unit with LoEj set, since
+		 * we cannot reliably check if drive can auto-close
+		 */
+		if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
 			break;
+		log = 1;
+		break;
+	case UNIT_ATTENTION:
+		/*
+		 * Make good and sure we've seen this potential media
+		 * change. Some drives (i.e. Creative) fail to present
+		 * the correct sense key in the error register.
+		 */
+		cdrom_saw_media_change(drive);
+		break;
+	default:
+		log = 1;
+		break;
 	}
 	return log;
 }
@@ -159,8 +159,8 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
 		if (sense->sense_key == 0x05 && sense->asc == 0x24)
 			return;
 
- 	if (sense->error_code == 0x70) {	/* Current Error */
- 		switch(sense->sense_key) {
+	if (sense->error_code == 0x70) {	/* Current Error */
+		switch (sense->sense_key) {
 		case MEDIUM_ERROR:
 		case VOLUME_OVERFLOW:
 		case ILLEGAL_REQUEST:
@@ -179,7 +179,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
 				bio_sectors = 4;
 			if (drive->queue->hardsect_size == 2048)
 				sector <<= 2;	/* Device sector size is 2K */
-			sector &= ~(bio_sectors -1);
+			sector &= ~(bio_sectors - 1);
 			valid = (sector - failed_command->sector) << 9;
 
 			if (valid < 0)
@@ -188,8 +188,8 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
 				drive->probed_capacity - sector < 4 * 75) {
 				set_capacity(info->disk, sector);
 			}
- 		}
- 	}
+		}
+	}
 
 	ide_cd_log_error(drive->name, failed_command, sense);
 }
@@ -230,7 +230,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
 	(void) ide_do_drive_cmd(drive, rq, ide_preempt);
 }
 
-static void cdrom_end_request (ide_drive_t *drive, int uptodate)
+static void cdrom_end_request(ide_drive_t *drive, int uptodate)
 {
 	struct request *rq = HWGROUP(drive)->rq;
 	int nsectors = rq->hard_cur_sectors;
@@ -293,7 +293,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 {
 	struct request *rq = HWGROUP(drive)->rq;
 	int stat, err, sense_key;
-	
+
 	/* Check for errors. */
 	stat = ide_read_status(drive);
 
@@ -334,26 +334,26 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 
 		/* Check for tray open. */
 		if (sense_key == NOT_READY) {
-			cdrom_saw_media_change (drive);
+			cdrom_saw_media_change(drive);
 		} else if (sense_key == UNIT_ATTENTION) {
 			/* Check for media change. */
-			cdrom_saw_media_change (drive);
+			cdrom_saw_media_change(drive);
 			/*printk("%s: media changed\n",drive->name);*/
 			return 0;
- 		} else if ((sense_key == ILLEGAL_REQUEST) &&
- 			   (rq->cmd[0] == GPCMD_START_STOP_UNIT)) {
- 			/*
- 			 * Don't print error message for this condition--
- 			 * SFF8090i indicates that 5/24/00 is the correct
- 			 * response to a request to close the tray if the
- 			 * drive doesn't have that capability.
- 			 * cdrom_log_sense() knows this!
- 			 */
+		} else if (sense_key == ILLEGAL_REQUEST &&
+			   rq->cmd[0] == GPCMD_START_STOP_UNIT) {
+			/*
+			 * Don't print error message for this condition--
+			 * SFF8090i indicates that 5/24/00 is the correct
+			 * response to a request to close the tray if the
+			 * drive doesn't have that capability.
+			 * cdrom_log_sense() knows this!
+			 */
 		} else if (!(rq->cmd_flags & REQ_QUIET)) {
 			/* Otherwise, print an error. */
 			ide_dump_status(drive, "packet command error", stat);
 		}
-		
+
 		rq->cmd_flags |= REQ_FAILED;
 
 		/*
@@ -374,10 +374,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 		if (sense_key == NOT_READY) {
 			/* Tray open. */
 			if (rq_data_dir(rq) == READ) {
-				cdrom_saw_media_change (drive);
+				cdrom_saw_media_change(drive);
 
 				/* Fail the request. */
-				printk ("%s: tray open\n", drive->name);
+				printk("%s: tray open\n", drive->name);
 				do_end_request = 1;
 			} else {
 				struct cdrom_info *info = drive->driver_data;
@@ -399,7 +399,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 					 */
 					spin_lock_irqsave(&ide_lock, flags);
 					blk_plug_device(drive->queue);
-					spin_unlock_irqrestore(&ide_lock,flags);
+					spin_unlock_irqrestore(&ide_lock, flags);
 					return 1;
 				}
 			}
@@ -407,25 +407,31 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 			/* Media change. */
 			cdrom_saw_media_change (drive);
 
-			/* Arrange to retry the request.
-			   But be sure to give up if we've retried
-			   too many times. */
+			/*
+			 * Arrange to retry the request.
+			 * But be sure to give up if we've retried
+			 * too many times.
+			 */
 			if (++rq->errors > ERROR_MAX)
 				do_end_request = 1;
 		} else if (sense_key == ILLEGAL_REQUEST ||
 			   sense_key == DATA_PROTECT) {
-			/* No point in retrying after an illegal
-			   request or data protect error.*/
-			ide_dump_status_no_sense (drive, "command error", stat);
+			/*
+			 * No point in retrying after an illegal
+			 * request or data protect error.
+			 */
+			ide_dump_status_no_sense(drive, "command error", stat);
 			do_end_request = 1;
 		} else if (sense_key == MEDIUM_ERROR) {
-			/* No point in re-trying a zillion times on a bad 
-			 * sector...  If we got here the error is not correctable */
-			ide_dump_status_no_sense (drive, "media error (bad sector)", stat);
+			/*
+			 * No point in re-trying a zillion times on a bad
+			 * sector... If we got here the error is not correctable
+			 */
+			ide_dump_status_no_sense(drive, "media error (bad sector)", stat);
 			do_end_request = 1;
 		} else if (sense_key == BLANK_CHECK) {
 			/* Disk appears blank ?? */
-			ide_dump_status_no_sense (drive, "media error (blank)", stat);
+			ide_dump_status_no_sense(drive, "media error (blank)", stat);
 			do_end_request = 1;
 		} else if ((err & ~ABRT_ERR) != 0) {
 			/* Go to the default handler
@@ -486,18 +492,18 @@ static int cdrom_timer_expiry(ide_drive_t *drive)
 	 * ide_timer_expiry keep polling us for these.
 	 */
 	switch (rq->cmd[0]) {
-		case GPCMD_BLANK:
-		case GPCMD_FORMAT_UNIT:
-		case GPCMD_RESERVE_RZONE_TRACK:
-		case GPCMD_CLOSE_TRACK:
-		case GPCMD_FLUSH_CACHE:
-			wait = ATAPI_WAIT_PC;
-			break;
-		default:
-			if (!(rq->cmd_flags & REQ_QUIET))
-				printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]);
-			wait = 0;
-			break;
+	case GPCMD_BLANK:
+	case GPCMD_FORMAT_UNIT:
+	case GPCMD_RESERVE_RZONE_TRACK:
+	case GPCMD_CLOSE_TRACK:
+	case GPCMD_FLUSH_CACHE:
+		wait = ATAPI_WAIT_PC;
+		break;
+	default:
+		if (!(rq->cmd_flags & REQ_QUIET))
+			printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]);
+		wait = 0;
+		break;
 	}
 	return wait;
 }
@@ -557,7 +563,7 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
    HANDLER is the interrupt handler to call when the command completes
    or there's data ready. */
 #define ATAPI_MIN_CDB_BYTES 12
-static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
+static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
 					  struct request *rq,
 					  ide_handler_t *handler)
 {
@@ -626,47 +632,6 @@ static void ide_cd_drain_data(ide_drive_t *drive, int nsects)
 }
 
 /*
- * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
- * buffer.  Once the first sector is added, any subsequent sectors are
- * assumed to be continuous (until the buffer is cleared).  For the first
- * sector added, SECTOR is its sector number.  (SECTOR is then ignored until
- * the buffer is cleared.)
- */
-static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
-                                  int sectors_to_transfer)
-{
-	struct cdrom_info *info = drive->driver_data;
-
-	/* Number of sectors to read into the buffer. */
-	int sectors_to_buffer = min_t(int, sectors_to_transfer,
-				     (SECTOR_BUFFER_SIZE >> SECTOR_BITS) -
-				       info->nsectors_buffered);
-
-	char *dest;
-
-	/* If we couldn't get a buffer, don't try to buffer anything... */
-	if (info->buffer == NULL)
-		sectors_to_buffer = 0;
-
-	/* If this is the first sector in the buffer, remember its number. */
-	if (info->nsectors_buffered == 0)
-		info->sector_buffered = sector;
-
-	/* Read the data into the buffer. */
-	dest = info->buffer + info->nsectors_buffered * SECTOR_SIZE;
-	while (sectors_to_buffer > 0) {
-		HWIF(drive)->atapi_input_bytes(drive, dest, SECTOR_SIZE);
-		--sectors_to_buffer;
-		--sectors_to_transfer;
-		++info->nsectors_buffered;
-		dest += SECTOR_SIZE;
-	}
-
-	/* Throw away any remaining data. */
-	ide_cd_drain_data(drive, sectors_to_transfer);
-}
-
-/*
  * Check the contents of the interrupt reason register from the cdrom
  * and attempt to recover if there are problems.  Returns  0 if everything's
  * ok; nonzero if the request has been terminated.
@@ -686,7 +651,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
 
 		/* Whoops... */
 		printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
-				drive->name, __FUNCTION__);
+				drive->name, __func__);
 
 		xf = rw ? hwif->atapi_output_bytes : hwif->atapi_input_bytes;
 		ide_cd_pad_transfer(drive, xf, len);
@@ -699,7 +664,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
 	} else {
 		/* Drive wants a command packet, or invalid ireason... */
 		printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n",
-				drive->name, __FUNCTION__, ireason);
+				drive->name, __func__, ireason);
 	}
 
 	if (rq->cmd_type == REQ_TYPE_ATA_PC)
@@ -721,7 +686,7 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
 		return 0;
 
 	printk(KERN_ERR "%s: %s: Bad transfer size %d\n",
-			drive->name, __FUNCTION__, len);
+			drive->name, __func__, len);
 
 	if (cd->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES)
 		printk(KERN_ERR "  This drive is not supported by "
@@ -734,65 +699,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
 	return 1;
 }
 
-/*
- * Try to satisfy some of the current read request from our cached data.
- * Returns nonzero if the request has been completed, zero otherwise.
- */
-static int cdrom_read_from_buffer (ide_drive_t *drive)
-{
-	struct cdrom_info *info = drive->driver_data;
-	struct request *rq = HWGROUP(drive)->rq;
-	unsigned short sectors_per_frame;
-
-	sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
-
-	/* Can't do anything if there's no buffer. */
-	if (info->buffer == NULL) return 0;
-
-	/* Loop while this request needs data and the next block is present
-	   in our cache. */
-	while (rq->nr_sectors > 0 &&
-	       rq->sector >= info->sector_buffered &&
-	       rq->sector < info->sector_buffered + info->nsectors_buffered) {
-		if (rq->current_nr_sectors == 0)
-			cdrom_end_request(drive, 1);
-
-		memcpy (rq->buffer,
-			info->buffer +
-			(rq->sector - info->sector_buffered) * SECTOR_SIZE,
-			SECTOR_SIZE);
-		rq->buffer += SECTOR_SIZE;
-		--rq->current_nr_sectors;
-		--rq->nr_sectors;
-		++rq->sector;
-	}
-
-	/* If we've satisfied the current request,
-	   terminate it successfully. */
-	if (rq->nr_sectors == 0) {
-		cdrom_end_request(drive, 1);
-		return -1;
-	}
-
-	/* Move on to the next buffer if needed. */
-	if (rq->current_nr_sectors == 0)
-		cdrom_end_request(drive, 1);
-
-	/* If this condition does not hold, then the kluge i use to
-	   represent the number of sectors to skip at the start of a transfer
-	   will fail.  I think that this will never happen, but let's be
-	   paranoid and check. */
-	if (rq->current_nr_sectors < bio_cur_sectors(rq->bio) &&
-	    (rq->sector & (sectors_per_frame - 1))) {
-		printk(KERN_ERR "%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
-			drive->name, (long)rq->sector);
-		cdrom_end_request(drive, 0);
-		return -1;
-	}
-
-	return 0;
-}
-
 static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
 
 /*
@@ -825,7 +731,7 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
 			if (rq->current_nr_sectors !=
 			    bio_cur_sectors(rq->bio)) {
 				printk(KERN_ERR "%s: %s: buffer botch (%u)\n",
-						drive->name, __FUNCTION__,
+						drive->name, __func__,
 						rq->current_nr_sectors);
 				cdrom_end_request(drive, 0);
 				return ide_stopped;
@@ -849,7 +755,7 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
 #define IDECD_SEEK_TIMER	(5 * WAIT_MIN_SLEEP)	/* 100 ms */
 #define IDECD_SEEK_TIMEOUT	(2 * WAIT_CMD)		/* 20 sec */
 
-static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
+static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive)
 {
 	struct cdrom_info *info = drive->driver_data;
 	int stat;
@@ -866,14 +772,14 @@ static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
 			 * this condition is far too common, to bother
 			 * users about it
 			 */
-			/* printk("%s: disabled DSC seek overlap\n", drive->name);*/ 
+			/* printk("%s: disabled DSC seek overlap\n", drive->name);*/
 			drive->dsc_overlap = 0;
 		}
 	}
 	return ide_stopped;
 }
 
-static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
+static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive)
 {
 	struct request *rq = HWGROUP(drive)->rq;
 	sector_t frame = rq->sector;
@@ -888,7 +794,7 @@ static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
 	return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
 }
 
-static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
+static ide_startstop_t cdrom_start_seek(ide_drive_t *drive, unsigned int block)
 {
 	struct cdrom_info *info = drive->driver_data;
 
@@ -897,9 +803,11 @@ static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
 	return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
 }
 
-/* Fix up a possibly partially-processed request so that we can
-   start it over entirely, or even put it back on the request queue. */
-static void restore_request (struct request *rq)
+/*
+ * Fix up a possibly partially-processed request so that we can
+ * start it over entirely, or even put it back on the request queue.
+ */
+static void restore_request(struct request *rq)
 {
 	if (rq->buffer != bio_data(rq->bio)) {
 		sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
@@ -950,7 +858,7 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
 		error = ide_do_drive_cmd(drive, rq, ide_wait);
 		time = jiffies - time;
 
-		/* FIXME: we should probably abort/retry or something 
+		/* FIXME: we should probably abort/retry or something
 		 * in case of failure */
 		if (rq->cmd_flags & REQ_FAILED) {
 			/* The request failed.  Retry if it was due to a unit
@@ -1057,7 +965,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 			if (rq->current_nr_sectors > 0) {
 				printk(KERN_ERR "%s: %s: data underrun "
 						"(%d blocks)\n",
-						drive->name, __FUNCTION__,
+						drive->name, __func__,
 						rq->current_nr_sectors);
 				if (!write)
 					rq->cmd_flags |= REQ_FAILED;
@@ -1134,11 +1042,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 		if (!ptr) {
 			if (blk_fs_request(rq) && !write)
 				/*
-				 * If the buffers are full, cache the rest
-				 * of the data in our internal buffer.
-				 */
-				cdrom_buffer_sectors(drive, rq->sector,
-						     thislen >> 9);
+				 * If the buffers are full, pipe the rest into
+				 * oblivion. */
+				ide_cd_drain_data(drive, thislen >> 9);
 			else {
 				printk(KERN_ERR "%s: confused, missing data\n",
 						drive->name);
@@ -1243,10 +1149,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
 		 * weirdness which might be present in the request packet.
 		 */
 		restore_request(rq);
-
-		/* Satisfy whatever we can of this request from our cache. */
-		if (cdrom_read_from_buffer(drive))
-			return ide_stopped;
 	}
 
 	/*
@@ -1262,9 +1164,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
 	} else
 		cd->dma = drive->using_dma;
 
-	/* Clear the local sector buffer. */
-	cd->nsectors_buffered = 0;
-
 	if (write)
 		cd->devinfo.media_written = 1;
 
@@ -1320,7 +1219,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
  * cdrom driver request routine.
  */
 static ide_startstop_t
-ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
+ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, sector_t block)
 {
 	ide_startstop_t action;
 	struct cdrom_info *info = drive->driver_data;
@@ -1335,13 +1234,13 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
 					ide_stall_queue(drive, IDECD_SEEK_TIMER);
 					return ide_stopped;
 				}
-				printk (KERN_ERR "%s: DSC timeout\n", drive->name);
+				printk(KERN_ERR "%s: DSC timeout\n", drive->name);
 			}
 			info->cd_flags &= ~IDE_CD_FLAG_SEEKING;
 		}
-		if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) {
+		if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
 			action = cdrom_start_seek(drive, block);
-		} else
+		else
 			action = cdrom_start_rw(drive, rq);
 		info->last_block = block;
 		return action;
@@ -1374,7 +1273,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
  */
 
 static
-void msf_from_bcd (struct atapi_msf *msf)
+void msf_from_bcd(struct atapi_msf *msf)
 {
 	msf->minute = BCD2BIN(msf->minute);
 	msf->second = BCD2BIN(msf->second);
@@ -1474,7 +1373,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
 		/* Try to allocate space. */
 		toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
 		if (toc == NULL) {
-			printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
+			printk(KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
 			return -ENOMEM;
 		}
 		info->toc = toc;
@@ -1569,9 +1468,9 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
 				toc->ent[i].track = BCD2BIN(toc->ent[i].track);
 			msf_from_bcd(&toc->ent[i].addr.msf);
 		}
-		toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute,
-						   toc->ent[i].addr.msf.second,
-						   toc->ent[i].addr.msf.frame);
+		toc->ent[i].addr.lba = msf_to_lba(toc->ent[i].addr.msf.minute,
+						  toc->ent[i].addr.msf.second,
+						  toc->ent[i].addr.msf.frame);
 	}
 
 	/* Read the multisession information. */
@@ -1595,9 +1494,9 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
 		if (stat)
 			return stat;
 
-		msf_from_bcd (&ms_tmp.ent.addr.msf);
+		msf_from_bcd(&ms_tmp.ent.addr.msf);
 		toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
-					  	   ms_tmp.ent.addr.msf.second,
+						   ms_tmp.ent.addr.msf.second,
 						   ms_tmp.ent.addr.msf.frame);
 	}
 
@@ -1679,7 +1578,7 @@ static struct cdrom_device_ops ide_cdrom_dops = {
 	.generic_packet		= ide_cdrom_packet,
 };
 
-static int ide_cdrom_register (ide_drive_t *drive, int nslots)
+static int ide_cdrom_register(ide_drive_t *drive, int nslots)
 {
 	struct cdrom_info *info = drive->driver_data;
 	struct cdrom_device_info *devinfo = &info->devinfo;
@@ -1698,7 +1597,7 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
 }
 
 static
-int ide_cdrom_probe_capabilities (ide_drive_t *drive)
+int ide_cdrom_probe_capabilities(ide_drive_t *drive)
 {
 	struct cdrom_info *cd = drive->driver_data;
 	struct cdrom_device_info *cdi = &cd->devinfo;
@@ -1870,7 +1769,7 @@ static int ide_cdrom_prep_pc(struct request *rq)
 		rq->errors = ILLEGAL_REQUEST;
 		return BLKPREP_KILL;
 	}
-	
+
 	return BLKPREP_OK;
 }
 
@@ -1948,7 +1847,7 @@ static unsigned int ide_cd_flags(struct hd_driveid *id)
 }
 
 static
-int ide_cdrom_setup (ide_drive_t *drive)
+int ide_cdrom_setup(ide_drive_t *drive)
 {
 	struct cdrom_info *cd = drive->driver_data;
 	struct cdrom_device_info *cdi = &cd->devinfo;
@@ -1979,7 +1878,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
 	else if (cd->cd_flags & IDE_CD_FLAG_SANYO_3CD)
 		cdi->sanyo_slot = 3;	/* 3 => use CD in slot 0 */
 
-	nslots = ide_cdrom_probe_capabilities (drive);
+	nslots = ide_cdrom_probe_capabilities(drive);
 
 	/*
 	 * set correct block size
@@ -1991,7 +1890,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
 		drive->dsc_overlap = (drive->next != drive);
 
 	if (ide_cdrom_register(drive, nslots)) {
-		printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
+		printk(KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
 		cd->devinfo.handle = NULL;
 		return 1;
 	}
@@ -1999,19 +1898,6 @@ int ide_cdrom_setup (ide_drive_t *drive)
 	return 0;
 }
 
-#ifdef CONFIG_IDE_PROC_FS
-static
-sector_t ide_cdrom_capacity (ide_drive_t *drive)
-{
-	unsigned long capacity, sectors_per_frame;
-
-	if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
-		return 0;
-
-	return capacity * sectors_per_frame;
-}
-#endif
-
 static void ide_cd_remove(ide_drive_t *drive)
 {
 	struct cdrom_info *info = drive->driver_data;
@@ -2030,7 +1916,6 @@ static void ide_cd_release(struct kref *kref)
 	ide_drive_t *drive = info->drive;
 	struct gendisk *g = info->disk;
 
-	kfree(info->buffer);
 	kfree(info->toc);
 	if (devinfo->handle == drive)
 		unregister_cdrom(devinfo);
@@ -2045,14 +1930,24 @@ static void ide_cd_release(struct kref *kref)
 static int ide_cd_probe(ide_drive_t *);
 
 #ifdef CONFIG_IDE_PROC_FS
+static sector_t ide_cdrom_capacity(ide_drive_t *drive)
+{
+	unsigned long capacity, sectors_per_frame;
+
+	if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
+		return 0;
+
+	return capacity * sectors_per_frame;
+}
+
 static int proc_idecd_read_capacity
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
 	ide_drive_t *drive = data;
 	int len;
 
-	len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive));
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static ide_proc_entry_t idecd_proc[] = {
@@ -2081,20 +1976,17 @@ static ide_driver_t ide_cdrom_driver = {
 #endif
 };
 
-static int idecd_open(struct inode * inode, struct file * file)
+static int idecd_open(struct inode *inode, struct file *file)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct cdrom_info *info;
 	int rc = -ENOMEM;
 
-	if (!(info = ide_cd_get(disk)))
+	info = ide_cd_get(disk);
+	if (!info)
 		return -ENXIO;
 
-	if (!info->buffer)
-		info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
-
-	if (info->buffer)
-		rc = cdrom_open(&info->devinfo, inode, file);
+	rc = cdrom_open(&info->devinfo, inode, file);
 
 	if (rc < 0)
 		ide_cd_put(info);
@@ -2102,12 +1994,12 @@ static int idecd_open(struct inode * inode, struct file * file)
 	return rc;
 }
 
-static int idecd_release(struct inode * inode, struct file * file)
+static int idecd_release(struct inode *inode, struct file *file)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct cdrom_info *info = ide_cd_g(disk);
 
-	cdrom_release (&info->devinfo, file);
+	cdrom_release(&info->devinfo, file);
 
 	ide_cd_put(info);
 
@@ -2139,7 +2031,7 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
 	struct packet_command cgc;
 	char buffer[16];
 	int stat;
- 	char spindown;
+	char spindown;
 
 	init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
 
@@ -2148,12 +2040,12 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
 		return stat;
 
 	spindown = buffer[11] & 0x0f;
-	if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
+	if (copy_to_user((void __user *)arg, &spindown, sizeof(char)))
 		return -EFAULT;
 	return 0;
 }
 
-static int idecd_ioctl (struct inode *inode, struct file *file,
+static int idecd_ioctl(struct inode *inode, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
 	struct block_device *bdev = inode->i_bdev;
@@ -2161,13 +2053,13 @@ static int idecd_ioctl (struct inode *inode, struct file *file,
 	int err;
 
 	switch (cmd) {
- 	case CDROMSETSPINDOWN:
+	case CDROMSETSPINDOWN:
 		return idecd_set_spindown(&info->devinfo, arg);
- 	case CDROMGETSPINDOWN:
+	case CDROMGETSPINDOWN:
 		return idecd_get_spindown(&info->devinfo, arg);
 	default:
 		break;
- 	}
+	}
 
 	err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
 	if (err == -EINVAL)
@@ -2193,16 +2085,16 @@ static int idecd_revalidate_disk(struct gendisk *disk)
 }
 
 static struct block_device_operations idecd_ops = {
-	.owner		= THIS_MODULE,
-	.open		= idecd_open,
-	.release	= idecd_release,
-	.ioctl		= idecd_ioctl,
-	.media_changed	= idecd_media_changed,
-	.revalidate_disk= idecd_revalidate_disk
+	.owner			= THIS_MODULE,
+	.open			= idecd_open,
+	.release		= idecd_release,
+	.ioctl			= idecd_ioctl,
+	.media_changed		= idecd_media_changed,
+	.revalidate_disk	= idecd_revalidate_disk
 };
 
 /* options */
-static char *ignore = NULL;
+static char *ignore;
 
 module_param(ignore, charp, 0400);
 MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 22e3751..a58801c 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -119,10 +119,6 @@ struct cdrom_info {
 
 	struct atapi_toc *toc;
 
-	unsigned long	sector_buffered;
-	unsigned long	nsectors_buffered;
-	unsigned char	*buffer;
-
 	/* The result of the last successful request sense command
 	   on this device. */
 	struct request_sense sense_data;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 39501d1..8e08d08 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -16,8 +16,6 @@
 
 #define IDEDISK_VERSION	"1.18"
 
-//#define DEBUG
-
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -88,7 +86,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp)
  *
  * It is called only once for each drive.
  */
-static int lba_capacity_is_ok (struct hd_driveid *id)
+static int lba_capacity_is_ok(struct hd_driveid *id)
 {
 	unsigned long lba_sects, chs_sects, head, tail;
 
@@ -176,7 +174,8 @@ static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
  * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
  * using LBA if supported, or CHS otherwise, to address sectors.
  */
-static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block)
+static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
+					sector_t block)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	unsigned int dma	= drive->using_dma;
@@ -228,7 +227,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
 			tf->device = (block >> 8) & 0xf;
 		}
 	} else {
-		unsigned int sect,head,cyl,track;
+		unsigned int sect, head, cyl, track;
+
 		track = (int)block / drive->sect;
 		sect  = (int)block % drive->sect + 1;
 		head  = track % drive->head;
@@ -271,7 +271,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
  * 1073741822 == 549756 MB or 48bit addressing fake drive
  */
 
-static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
+static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
+				      sector_t block)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 
@@ -452,7 +453,7 @@ static void idedisk_check_hpa(ide_drive_t *drive)
  * in above order (i.e., if value of higher priority is available,
  * reset will be ignored).
  */
-static void init_idedisk_capacity (ide_drive_t  *drive)
+static void init_idedisk_capacity(ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
 	/*
@@ -479,7 +480,7 @@ static void init_idedisk_capacity (ide_drive_t  *drive)
 	}
 }
 
-static sector_t idedisk_capacity (ide_drive_t *drive)
+static sector_t idedisk_capacity(ide_drive_t *drive)
 {
 	return drive->capacity64 - drive->sect0;
 }
@@ -524,10 +525,11 @@ static int proc_idedisk_read_cache
 	int		len;
 
 	if (drive->id_read)
-		len = sprintf(out,"%i\n", drive->id->buf_size / 2);
+		len = sprintf(out, "%i\n", drive->id->buf_size / 2);
 	else
-		len = sprintf(out,"(none)\n");
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+		len = sprintf(out, "(none)\n");
+
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static int proc_idedisk_read_capacity
@@ -536,54 +538,52 @@ static int proc_idedisk_read_capacity
 	ide_drive_t*drive = (ide_drive_t *)data;
 	int len;
 
-	len = sprintf(page,"%llu\n", (long long)idedisk_capacity(drive));
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	len = sprintf(page, "%llu\n", (long long)idedisk_capacity(drive));
+
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
-static int proc_idedisk_read_smart_thresholds
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int proc_idedisk_read_smart(char *page, char **start, off_t off,
+				   int count, int *eof, void *data, u8 sub_cmd)
 {
 	ide_drive_t	*drive = (ide_drive_t *)data;
 	int		len = 0, i = 0;
 
-	if (get_smart_data(drive, page, SMART_READ_THRESHOLDS) == 0) {
+	if (get_smart_data(drive, page, sub_cmd) == 0) {
 		unsigned short *val = (unsigned short *) page;
 		char *out = ((char *)val) + (SECTOR_WORDS * 4);
 		page = out;
 		do {
-			out += sprintf(out, "%04x%c", le16_to_cpu(*val), (++i & 7) ? ' ' : '\n');
+			out += sprintf(out, "%04x%c", le16_to_cpu(*val),
+				       (++i & 7) ? ' ' : '\n');
 			val += 1;
 		} while (i < (SECTOR_WORDS * 2));
 		len = out - page;
 	}
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
-static int proc_idedisk_read_smart_values
+static int proc_idedisk_read_sv
 	(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;
+	return proc_idedisk_read_smart(page, start, off, count, eof, data,
+				       SMART_READ_VALUES);
+}
 
-	if (get_smart_data(drive, page, SMART_READ_VALUES) == 0) {
-		unsigned short *val = (unsigned short *) page;
-		char *out = ((char *)val) + (SECTOR_WORDS * 4);
-		page = out;
-		do {
-			out += sprintf(out, "%04x%c", le16_to_cpu(*val), (++i & 7) ? ' ' : '\n');
-			val += 1;
-		} while (i < (SECTOR_WORDS * 2));
-		len = out - page;
-	}
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+static int proc_idedisk_read_st
+	(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	return proc_idedisk_read_smart(page, start, off, count, eof, data,
+				       SMART_READ_THRESHOLDS);
 }
 
 static ide_proc_entry_t idedisk_proc[] = {
-	{ "cache",		S_IFREG|S_IRUGO,	proc_idedisk_read_cache,		NULL },
-	{ "capacity",		S_IFREG|S_IRUGO,	proc_idedisk_read_capacity,		NULL },
-	{ "geometry",		S_IFREG|S_IRUGO,	proc_ide_read_geometry,			NULL },
-	{ "smart_values",	S_IFREG|S_IRUSR,	proc_idedisk_read_smart_values,		NULL },
-	{ "smart_thresholds",	S_IFREG|S_IRUSR,	proc_idedisk_read_smart_thresholds,	NULL },
+	{ "cache",	  S_IFREG|S_IRUGO, proc_idedisk_read_cache,    NULL },
+	{ "capacity",	  S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL },
+	{ "geometry",	  S_IFREG|S_IRUGO, proc_ide_read_geometry,     NULL },
+	{ "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv,       NULL },
+	{ "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st,   NULL },
 	{ NULL, 0, NULL, NULL }
 };
 #endif	/* CONFIG_IDE_PROC_FS */
@@ -625,12 +625,13 @@ static int set_multcount(ide_drive_t *drive, int arg)
 	if (drive->special.b.set_multmode)
 		return -EBUSY;
 
-	ide_init_drive_cmd (&rq);
+	ide_init_drive_cmd(&rq);
 	rq.cmd_type = REQ_TYPE_ATA_TASKFILE;
 
 	drive->mult_req = arg;
 	drive->special.b.set_multmode = 1;
-	(void) ide_do_drive_cmd (drive, &rq, ide_wait);
+	(void)ide_do_drive_cmd(drive, &rq, ide_wait);
+
 	return (drive->mult_count == arg) ? 0 : -EIO;
 }
 
@@ -706,7 +707,7 @@ static int write_cache(ide_drive_t *drive, int arg)
 	return err;
 }
 
-static int do_idedisk_flushcache (ide_drive_t *drive)
+static int do_idedisk_flushcache(ide_drive_t *drive)
 {
 	ide_task_t args;
 
@@ -719,7 +720,7 @@ static int do_idedisk_flushcache (ide_drive_t *drive)
 	return ide_no_data_taskfile(drive, &args);
 }
 
-static int set_acoustic (ide_drive_t *drive, int arg)
+static int set_acoustic(ide_drive_t *drive, int arg)
 {
 	ide_task_t args;
 
@@ -753,7 +754,7 @@ static int set_lba_addressing(ide_drive_t *drive, int arg)
 		return 0;
 
 	if (!idedisk_supports_lba48(drive->id))
-                return -EIO;
+		return -EIO;
 	drive->addressing = arg;
 	return 0;
 }
@@ -763,23 +764,35 @@ static void idedisk_add_settings(ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
 
-	ide_add_setting(drive,	"bios_cyl",	SETTING_RW,	TYPE_INT,	0,	65535,			1,	1,	&drive->bios_cyl,	NULL);
-	ide_add_setting(drive,	"bios_head",	SETTING_RW,	TYPE_BYTE,	0,	255,			1,	1,	&drive->bios_head,	NULL);
-	ide_add_setting(drive,	"bios_sect",	SETTING_RW,	TYPE_BYTE,	0,	63,			1,	1,	&drive->bios_sect,	NULL);
-	ide_add_setting(drive,	"address",	SETTING_RW,	TYPE_BYTE,	0,	2,			1,	1,	&drive->addressing,	set_lba_addressing);
-	ide_add_setting(drive,	"multcount",	SETTING_RW,	TYPE_BYTE,	0,	id->max_multsect,	1,	1,	&drive->mult_count,	set_multcount);
-	ide_add_setting(drive,	"nowerr",	SETTING_RW,	TYPE_BYTE,	0,	1,			1,	1,	&drive->nowerr,		set_nowerr);
-	ide_add_setting(drive,	"lun",		SETTING_RW,	TYPE_INT,	0,	7,			1,	1,	&drive->lun,		NULL);
-	ide_add_setting(drive,	"wcache",	SETTING_RW,	TYPE_BYTE,	0,	1,			1,	1,	&drive->wcache,		write_cache);
-	ide_add_setting(drive,	"acoustic",	SETTING_RW,	TYPE_BYTE,	0,	254,			1,	1,	&drive->acoustic,	set_acoustic);
- 	ide_add_setting(drive,	"failures",	SETTING_RW,	TYPE_INT,	0,	65535,			1,	1,	&drive->failures,	NULL);
- 	ide_add_setting(drive,	"max_failures",	SETTING_RW,	TYPE_INT,	0,	65535,			1,	1,	&drive->max_failures,	NULL);
+	ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1,
+			&drive->bios_cyl, NULL);
+	ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1,
+			&drive->bios_head, NULL);
+	ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1,
+			&drive->bios_sect, NULL);
+	ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1,
+			&drive->addressing, set_lba_addressing);
+	ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0,
+			id->max_multsect, 1, 1, &drive->mult_count,
+			set_multcount);
+	ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
+			&drive->nowerr, set_nowerr);
+	ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1,
+			&drive->lun, NULL);
+	ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
+			&drive->wcache, write_cache);
+	ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1,
+			&drive->acoustic, set_acoustic);
+	ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1,
+			&drive->failures, NULL);
+	ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535,
+			1, 1, &drive->max_failures, NULL);
 }
 #else
 static inline void idedisk_add_settings(ide_drive_t *drive) { ; }
 #endif
 
-static void idedisk_setup (ide_drive_t *drive)
+static void idedisk_setup(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct hd_driveid *id = drive->id;
@@ -792,11 +805,10 @@ static void idedisk_setup (ide_drive_t *drive)
 
 	if (drive->removable) {
 		/*
-		 * Removable disks (eg. SYQUEST); ignore 'WD' drives 
+		 * Removable disks (eg. SYQUEST); ignore 'WD' drives
 		 */
-		if (id->model[0] != 'W' || id->model[1] != 'D') {
+		if (id->model[0] != 'W' || id->model[1] != 'D')
 			drive->doorlocking = 1;
-		}
 	}
 
 	(void)set_lba_addressing(drive, 1);
@@ -810,10 +822,11 @@ static void idedisk_setup (ide_drive_t *drive)
 		blk_queue_max_sectors(drive->queue, max_s);
 	}
 
-	printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name, drive->queue->max_sectors / 2);
+	printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name,
+			 drive->queue->max_sectors / 2);
 
 	/* calculate drive capacity, and select LBA if possible */
-	init_idedisk_capacity (drive);
+	init_idedisk_capacity(drive);
 
 	/* limit drive capacity to 137GB if LBA48 cannot be used */
 	if (drive->addressing == 0 && drive->capacity64 > 1ULL << 28) {
@@ -826,9 +839,9 @@ static void idedisk_setup (ide_drive_t *drive)
 
 	if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) {
 		if (drive->capacity64 > 1ULL << 28) {
-			printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode will"
-					 " be used for accessing sectors > %u\n",
-					 drive->name, 1 << 28);
+			printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
+					 " will be used for accessing sectors "
+					 "> %u\n", drive->name, 1 << 28);
 		} else
 			drive->addressing = 0;
 	}
@@ -837,7 +850,8 @@ static void idedisk_setup (ide_drive_t *drive)
 	 * if possible, give fdisk access to more of the drive,
 	 * by correcting bios_cyls:
 	 */
-	capacity = idedisk_capacity (drive);
+	capacity = idedisk_capacity(drive);
+
 	if (!drive->forced_geom) {
 
 		if (idedisk_supports_lba48(drive->id)) {
@@ -993,7 +1007,8 @@ static int idedisk_open(struct inode *inode, struct file *filp)
 	struct ide_disk_obj *idkp;
 	ide_drive_t *drive;
 
-	if (!(idkp = ide_disk_get(disk)))
+	idkp = ide_disk_get(disk);
+	if (idkp == NULL)
 		return -ENXIO;
 
 	drive = idkp->drive;
@@ -1115,13 +1130,13 @@ static int idedisk_revalidate_disk(struct gendisk *disk)
 }
 
 static struct block_device_operations idedisk_ops = {
-	.owner		= THIS_MODULE,
-	.open		= idedisk_open,
-	.release	= idedisk_release,
-	.ioctl		= idedisk_ioctl,
-	.getgeo		= idedisk_getgeo,
-	.media_changed	= idedisk_media_changed,
-	.revalidate_disk= idedisk_revalidate_disk
+	.owner			= THIS_MODULE,
+	.open			= idedisk_open,
+	.release		= idedisk_release,
+	.ioctl			= idedisk_ioctl,
+	.getgeo			= idedisk_getgeo,
+	.media_changed		= idedisk_media_changed,
+	.revalidate_disk	= idedisk_revalidate_disk
 };
 
 MODULE_DESCRIPTION("ATA DISK Driver");
@@ -1184,7 +1199,7 @@ failed:
 	return -ENODEV;
 }
 
-static void __exit idedisk_exit (void)
+static void __exit idedisk_exit(void)
 {
 	driver_unregister(&idedisk_driver.gen_driver);
 }
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index d61e578..8757e5e 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -703,17 +703,8 @@ static int ide_tune_dma(ide_drive_t *drive)
 
 	speed = ide_max_dma_mode(drive);
 
-	if (!speed) {
-		 /* is this really correct/needed? */
-		if ((hwif->host_flags & IDE_HFLAG_CY82C693) &&
-		    ide_dma_good_drive(drive))
-			return 1;
-		else
-			return 0;
-	}
-
-	if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
-		return 1;
+	if (!speed)
+		return 0;
 
 	if (ide_set_dma_mode(drive, speed))
 		return 0;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 5f133df..ed19a8b 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -396,7 +396,7 @@ static void idefloppy_retry_pc(ide_drive_t *drive)
 }
 
 /* The usual interrupt handler called during a packet command. */
-static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
+static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
 {
 	idefloppy_floppy_t *floppy = drive->driver_data;
 	ide_hwif_t *hwif = drive->hwif;
@@ -1596,13 +1596,13 @@ static int idefloppy_revalidate_disk(struct gendisk *disk)
 }
 
 static struct block_device_operations idefloppy_ops = {
-	.owner		= THIS_MODULE,
-	.open		= idefloppy_open,
-	.release	= idefloppy_release,
-	.ioctl		= idefloppy_ioctl,
-	.getgeo		= idefloppy_getgeo,
-	.media_changed	= idefloppy_media_changed,
-	.revalidate_disk= idefloppy_revalidate_disk
+	.owner			= THIS_MODULE,
+	.open			= idefloppy_open,
+	.release		= idefloppy_release,
+	.ioctl			= idefloppy_ioctl,
+	.getgeo			= idefloppy_getgeo,
+	.media_changed		= idefloppy_media_changed,
+	.revalidate_disk	= idefloppy_revalidate_disk
 };
 
 static int ide_floppy_probe(ide_drive_t *drive)
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 25fda0a..19f63e3 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -33,7 +33,7 @@ static ssize_t store_add(struct class *cls, const char *buf, size_t n)
 	if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
 		return -EINVAL;
 
-	hwif = ide_find_port(base);
+	hwif = ide_find_port();
 	if (hwif == NULL)
 		return -ENOENT;
 
@@ -90,11 +90,21 @@ static int __init ide_generic_init(void)
 	int i;
 
 	for (i = 0; i < MAX_HWIFS; i++) {
-		ide_hwif_t *hwif = &ide_hwifs[i];
+		ide_hwif_t *hwif;
 		unsigned long io_addr = ide_default_io_base(i);
 		hw_regs_t hw;
 
-		if (hwif->chipset == ide_unknown && io_addr) {
+		if (io_addr) {
+			/*
+			 * Skip probing if the corresponding
+			 * slot is already occupied.
+			 */
+			hwif = ide_find_port();
+			if (hwif == NULL || hwif->index != i) {
+				idx[i] = 0xff;
+				continue;
+			}
+
 			memset(&hw, 0, sizeof(hw));
 			ide_std_init_ports(&hw, io_addr, io_addr + 0x206);
 			hw.irq = ide_default_irq(io_addr);
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 31e5afa..51d181e 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -726,10 +726,6 @@ static ide_startstop_t do_special (ide_drive_t *drive)
 		s->b.set_tune = 0;
 
 		if (set_pio_mode_abuse(drive->hwif, req_pio)) {
-
-			if (hwif->set_pio_mode == NULL)
-				return ide_stopped;
-
 			/*
 			 * take ide_lock for drive->[no_]unmask/[no_]io_32bit
 			 */
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 7031a8d..c859de7 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -274,16 +274,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
 		if (overridden)
 			printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
 					 drive->name);
-
-		/*
-		 * Conservative "downgrade" for all pre-ATA2 drives
-		 */
-		if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_DOWNGRADE) == 0 &&
-		    pio_mode && pio_mode < 4) {
-			pio_mode--;
-			printk(KERN_INFO "%s: applying conservative "
-					 "PIO \"downgrade\"\n", drive->name);
-		}
 	}
 
 	if (pio_mode > max_mode)
@@ -300,7 +290,8 @@ void ide_set_pio(ide_drive_t *drive, u8 req_pio)
 	ide_hwif_t *hwif = drive->hwif;
 	u8 host_pio, pio;
 
-	if (hwif->set_pio_mode == NULL)
+	if (hwif->set_pio_mode == NULL ||
+	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
 		return;
 
 	BUG_ON(hwif->pio_mask == 0x00);
@@ -353,6 +344,9 @@ int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
 {
 	ide_hwif_t *hwif = drive->hwif;
 
+	if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+		return 0;
+
 	if (hwif->set_pio_mode == NULL)
 		return -1;
 
@@ -380,6 +374,9 @@ int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
 {
 	ide_hwif_t *hwif = drive->hwif;
 
+	if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+		return 0;
+
 	if (hwif->set_dma_mode == NULL)
 		return -1;
 
@@ -410,7 +407,8 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
 {
 	ide_hwif_t *hwif = drive->hwif;
 
-	if (hwif->set_dma_mode == NULL)
+	if (hwif->set_dma_mode == NULL ||
+	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
 		return -1;
 
 	rate = ide_rate_filter(drive, rate);
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index 34c2ad3..8a178a5 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -11,7 +11,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * (for example /usr/src/linux/COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/init.h>
@@ -20,12 +20,12 @@
 
 /* Add your devices here :)) */
 static struct pnp_device_id idepnp_devices[] = {
-  	/* Generic ESDI/IDE/ATA compatible hard disk controller */
+	/* Generic ESDI/IDE/ATA compatible hard disk controller */
 	{.id = "PNP0600", .driver_data = 0},
 	{.id = ""}
 };
 
-static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
+static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
 	hw_regs_t hw;
 	ide_hwif_t *hwif;
@@ -38,7 +38,7 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
 				pnp_port_start(dev, 1));
 	hw.irq = pnp_irq(dev, 0);
 
-	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	hwif = ide_find_port();
 	if (hwif) {
 		u8 index = hwif->index;
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
@@ -47,7 +47,7 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
 		ide_init_port_hw(hwif, &hw);
 
 		printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
-		pnp_set_drvdata(dev,hwif);
+		pnp_set_drvdata(dev, hwif);
 
 		ide_device_add(idx, NULL);
 
@@ -57,7 +57,7 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
 	return -1;
 }
 
-static void idepnp_remove(struct pnp_dev * dev)
+static void idepnp_remove(struct pnp_dev *dev)
 {
 	ide_hwif_t *hwif = pnp_get_drvdata(dev);
 
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 6a196c2..8754297 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1444,6 +1444,54 @@ static int ide_sysfs_register_port(ide_hwif_t *hwif)
 	return rc;
 }
 
+/**
+ *	ide_find_port_slot	-	find free ide_hwifs[] slot
+ *	@d: IDE port info
+ *
+ *	Return the new hwif.  If we are out of free slots return NULL.
+ */
+
+ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d)
+{
+	ide_hwif_t *hwif;
+	int i;
+	u8 bootable = (d && (d->host_flags & IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1;
+
+	/*
+	 * Claim an unassigned slot.
+	 *
+	 * Give preference to claiming other slots before claiming ide0/ide1,
+	 * just in case there's another interface yet-to-be-scanned
+	 * which uses ports 0x1f0/0x170 (the ide0/ide1 defaults).
+	 *
+	 * Unless there is a bootable card that does not use the standard
+	 * ports 0x1f0/0x170 (the ide0/ide1 defaults).
+	 */
+	if (bootable) {
+		i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0;
+
+		for (; i < MAX_HWIFS; i++) {
+			hwif = &ide_hwifs[i];
+			if (hwif->chipset == ide_unknown)
+				return hwif;
+		}
+	} else {
+		for (i = 2; i < MAX_HWIFS; i++) {
+			hwif = &ide_hwifs[i];
+			if (hwif->chipset == ide_unknown)
+				return hwif;
+		}
+		for (i = 0; i < 2 && i < MAX_HWIFS; i++) {
+			hwif = &ide_hwifs[i];
+			if (hwif->chipset == ide_unknown)
+				return hwif;
+		}
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(ide_find_port_slot);
+
 int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
 {
 	ide_hwif_t *hwif, *mate = NULL;
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index edd7f18..5d3562b 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -47,28 +47,28 @@ static int proc_ide_read_imodel
 	const char	*name;
 
 	switch (hwif->chipset) {
-		case ide_generic:	name = "generic";	break;
-		case ide_pci:		name = "pci";		break;
-		case ide_cmd640:	name = "cmd640";	break;
-		case ide_dtc2278:	name = "dtc2278";	break;
-		case ide_ali14xx:	name = "ali14xx";	break;
-		case ide_qd65xx:	name = "qd65xx";	break;
-		case ide_umc8672:	name = "umc8672";	break;
-		case ide_ht6560b:	name = "ht6560b";	break;
-		case ide_rz1000:	name = "rz1000";	break;
-		case ide_trm290:	name = "trm290";	break;
-		case ide_cmd646:	name = "cmd646";	break;
-		case ide_cy82c693:	name = "cy82c693";	break;
-		case ide_4drives:	name = "4drives";	break;
-		case ide_pmac:		name = "mac-io";	break;
-		case ide_au1xxx:	name = "au1xxx";	break;
-		case ide_palm3710:      name = "palm3710";      break;
-		case ide_etrax100:	name = "etrax100";	break;
-		case ide_acorn:		name = "acorn";		break;
-		default:		name = "(unknown)";	break;
+	case ide_generic:	name = "generic";	break;
+	case ide_pci:		name = "pci";		break;
+	case ide_cmd640:	name = "cmd640";	break;
+	case ide_dtc2278:	name = "dtc2278";	break;
+	case ide_ali14xx:	name = "ali14xx";	break;
+	case ide_qd65xx:	name = "qd65xx";	break;
+	case ide_umc8672:	name = "umc8672";	break;
+	case ide_ht6560b:	name = "ht6560b";	break;
+	case ide_rz1000:	name = "rz1000";	break;
+	case ide_trm290:	name = "trm290";	break;
+	case ide_cmd646:	name = "cmd646";	break;
+	case ide_cy82c693:	name = "cy82c693";	break;
+	case ide_4drives:	name = "4drives";	break;
+	case ide_pmac:		name = "mac-io";	break;
+	case ide_au1xxx:	name = "au1xxx";	break;
+	case ide_palm3710:      name = "palm3710";      break;
+	case ide_etrax100:	name = "etrax100";	break;
+	case ide_acorn:		name = "acorn";		break;
+	default:		name = "(unknown)";	break;
 	}
 	len = sprintf(page, "%s\n", name);
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static int proc_ide_read_mate
@@ -81,7 +81,7 @@ static int proc_ide_read_mate
 		len = sprintf(page, "%s\n", hwif->mate->name);
 	else
 		len = sprintf(page, "(none)\n");
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static int proc_ide_read_channel
@@ -93,7 +93,7 @@ static int proc_ide_read_channel
 	page[0] = hwif->channel ? '1' : '0';
 	page[1] = '\n';
 	len = 2;
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static int proc_ide_read_identify
@@ -120,7 +120,7 @@ static int proc_ide_read_identify
 			len = out - page;
 		}
 	}
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 /**
@@ -197,7 +197,7 @@ EXPORT_SYMBOL(ide_add_setting);
  *	The caller must hold the setting semaphore.
  */
 
-static void __ide_remove_setting (ide_drive_t *drive, char *name)
+static void __ide_remove_setting(ide_drive_t *drive, char *name)
 {
 	ide_settings_t **p, *setting;
 
@@ -205,7 +205,8 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name)
 
 	while ((*p) && strcmp((*p)->name, name))
 		p = &((*p)->next);
-	if ((setting = (*p)) == NULL)
+	setting = (*p);
+	if (setting == NULL)
 		return;
 
 	(*p) = setting->next;
@@ -223,7 +224,7 @@ static void __ide_remove_setting (ide_drive_t *drive, char *name)
  *	caller must hold ide_setting_mtx.
  */
 
-static void auto_remove_settings (ide_drive_t *drive)
+static void auto_remove_settings(ide_drive_t *drive)
 {
 	ide_settings_t *setting;
 repeat:
@@ -279,16 +280,16 @@ static int ide_read_setting(ide_drive_t *drive, ide_settings_t *setting)
 
 	if ((setting->rw & SETTING_READ)) {
 		spin_lock_irqsave(&ide_lock, flags);
-		switch(setting->data_type) {
-			case TYPE_BYTE:
-				val = *((u8 *) setting->data);
-				break;
-			case TYPE_SHORT:
-				val = *((u16 *) setting->data);
-				break;
-			case TYPE_INT:
-				val = *((u32 *) setting->data);
-				break;
+		switch (setting->data_type) {
+		case TYPE_BYTE:
+			val = *((u8 *) setting->data);
+			break;
+		case TYPE_SHORT:
+			val = *((u16 *) setting->data);
+			break;
+		case TYPE_INT:
+			val = *((u32 *) setting->data);
+			break;
 		}
 		spin_unlock_irqrestore(&ide_lock, flags);
 	}
@@ -326,15 +327,15 @@ static int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int va
 	if (ide_spin_wait_hwgroup(drive))
 		return -EBUSY;
 	switch (setting->data_type) {
-		case TYPE_BYTE:
-			*((u8 *) setting->data) = val;
-			break;
-		case TYPE_SHORT:
-			*((u16 *) setting->data) = val;
-			break;
-		case TYPE_INT:
-			*((u32 *) setting->data) = val;
-			break;
+	case TYPE_BYTE:
+		*((u8 *) setting->data) = val;
+		break;
+	case TYPE_SHORT:
+		*((u16 *) setting->data) = val;
+		break;
+	case TYPE_INT:
+		*((u32 *) setting->data) = val;
+		break;
 	}
 	spin_unlock_irq(&ide_lock);
 	return 0;
@@ -390,7 +391,7 @@ void ide_add_generic_settings (ide_drive_t *drive)
 
 static void proc_ide_settings_warn(void)
 {
-	static int warned = 0;
+	static int warned;
 
 	if (warned)
 		return;
@@ -413,11 +414,12 @@ static int proc_ide_read_settings
 	mutex_lock(&ide_setting_mtx);
 	out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
 	out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
-	while(setting) {
+	while (setting) {
 		mul_factor = setting->mul_factor;
 		div_factor = setting->div_factor;
 		out += sprintf(out, "%-24s", setting->name);
-		if ((rc = ide_read_setting(drive, setting)) >= 0)
+		rc = ide_read_setting(drive, setting);
+		if (rc >= 0)
 			out += sprintf(out, "%-16d", rc * mul_factor / div_factor);
 		else
 			out += sprintf(out, "%-16s", "write-only");
@@ -431,7 +433,7 @@ static int proc_ide_read_settings
 	}
 	len = out - page;
 	mutex_unlock(&ide_setting_mtx);
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 #define MAX_LEN	30
@@ -512,8 +514,7 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer,
 
 			mutex_lock(&ide_setting_mtx);
 			setting = ide_find_setting_by_name(drive, name);
-			if (!setting)
-			{
+			if (!setting) {
 				mutex_unlock(&ide_setting_mtx);
 				goto parse_error;
 			}
@@ -533,8 +534,8 @@ parse_error:
 int proc_ide_read_capacity
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	int len = sprintf(page,"%llu\n", (long long)0x7fffffff);
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	int len = sprintf(page, "%llu\n", (long long)0x7fffffff);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 EXPORT_SYMBOL_GPL(proc_ide_read_capacity);
@@ -546,13 +547,13 @@ int proc_ide_read_geometry
 	char		*out = page;
 	int		len;
 
-	out += sprintf(out,"physical     %d/%d/%d\n",
+	out += sprintf(out, "physical     %d/%d/%d\n",
 			drive->cyl, drive->head, drive->sect);
-	out += sprintf(out,"logical      %d/%d/%d\n",
+	out += sprintf(out, "logical      %d/%d/%d\n",
 			drive->bios_cyl, drive->bios_head, drive->bios_sect);
 
 	len = out - page;
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 EXPORT_SYMBOL(proc_ide_read_geometry);
@@ -566,7 +567,7 @@ static int proc_ide_read_dmodel
 
 	len = sprintf(page, "%.40s\n",
 		(id && id->model[0]) ? (char *)id->model : "(none)");
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static int proc_ide_read_driver
@@ -583,7 +584,7 @@ static int proc_ide_read_driver
 				dev->driver->name, ide_drv->version);
 	} else
 		len = sprintf(page, "ide-default version 0.9.newide\n");
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
@@ -639,30 +640,26 @@ static int proc_ide_read_media
 	int		len;
 
 	switch (drive->media) {
-		case ide_disk:	media = "disk\n";
-				break;
-		case ide_cdrom:	media = "cdrom\n";
-				break;
-		case ide_tape:	media = "tape\n";
-				break;
-		case ide_floppy:media = "floppy\n";
-				break;
-		case ide_optical:media = "optical\n";
-				break;
-		default:	media = "UNKNOWN\n";
-				break;
+	case ide_disk:		media = "disk\n";	break;
+	case ide_cdrom:		media = "cdrom\n";	break;
+	case ide_tape:		media = "tape\n";	break;
+	case ide_floppy:	media = "floppy\n";	break;
+	case ide_optical:	media = "optical\n";	break;
+	default:		media = "UNKNOWN\n";	break;
 	}
-	strcpy(page,media);
+	strcpy(page, media);
 	len = strlen(media);
-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
 }
 
 static ide_proc_entry_t generic_drive_entries[] = {
-	{ "driver",	S_IFREG|S_IRUGO,	proc_ide_read_driver,	proc_ide_write_driver },
-	{ "identify",	S_IFREG|S_IRUSR,	proc_ide_read_identify,	NULL },
-	{ "media",	S_IFREG|S_IRUGO,	proc_ide_read_media,	NULL },
-	{ "model",	S_IFREG|S_IRUGO,	proc_ide_read_dmodel,	NULL },
-	{ "settings",	S_IFREG|S_IRUSR|S_IWUSR,proc_ide_read_settings,	proc_ide_write_settings },
+	{ "driver",	S_IFREG|S_IRUGO,	 proc_ide_read_driver,
+						 proc_ide_write_driver },
+	{ "identify",	S_IFREG|S_IRUSR,	 proc_ide_read_identify, NULL },
+	{ "media",	S_IFREG|S_IRUGO,	 proc_ide_read_media,    NULL },
+	{ "model",	S_IFREG|S_IRUGO,	 proc_ide_read_dmodel,   NULL },
+	{ "settings",	S_IFREG|S_IRUSR|S_IWUSR, proc_ide_read_settings,
+						 proc_ide_write_settings },
 	{ NULL,	0, NULL, NULL }
 };
 
@@ -734,7 +731,6 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
 	spin_unlock_irqrestore(&ide_lock, flags);
 	mutex_unlock(&ide_setting_mtx);
 }
-
 EXPORT_SYMBOL(ide_proc_unregister_driver);
 
 void ide_proc_port_register_devices(ide_hwif_t *hwif)
@@ -755,7 +751,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif)
 		drive->proc = proc_mkdir(drive->name, parent);
 		if (drive->proc)
 			ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
-		sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name);
+		sprintf(name, "ide%d/%s", (drive->name[2]-'a')/2, drive->name);
 		ent = proc_symlink(drive->name, proc_ide_root, name);
 		if (!ent) return;
 	}
@@ -795,7 +791,6 @@ void ide_pci_create_host_proc(const char *name, get_info_t *get_info)
 {
 	create_proc_info_entry(name, 0, proc_ide_root, get_info);
 }
-
 EXPORT_SYMBOL_GPL(ide_pci_create_host_proc);
 #endif
 
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 917c72d..d868ca4 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -100,13 +100,8 @@ int ide_noacpitfs = 1;
 int ide_noacpionboot = 1;
 #endif
 
-/*
- * This is declared extern in ide.h, for access by other IDE modules:
- */
 ide_hwif_t ide_hwifs[MAX_HWIFS];	/* master data repository */
 
-EXPORT_SYMBOL(ide_hwifs);
-
 static void ide_port_init_devices_data(ide_hwif_t *);
 
 /*
@@ -232,30 +227,6 @@ static int ide_system_bus_speed(void)
 	return pci_dev_present(pci_default) ? 33 : 50;
 }
 
-ide_hwif_t * ide_find_port(unsigned long base)
-{
-	ide_hwif_t *hwif;
-	int i;
-
-	for (i = 0; i < MAX_HWIFS; i++) {
-		hwif = &ide_hwifs[i];
-		if (hwif->io_ports[IDE_DATA_OFFSET] == base)
-			goto found;
-	}
-
-	for (i = 0; i < MAX_HWIFS; i++) {
-		hwif = &ide_hwifs[i];
-		if (hwif->chipset == ide_unknown)
-			goto found;
-	}
-
-	hwif = NULL;
-found:
-	return hwif;
-}
-
-EXPORT_SYMBOL_GPL(ide_find_port);
-
 static struct resource* hwif_request_region(ide_hwif_t *hwif,
 					    unsigned long addr, int num)
 {
@@ -280,29 +251,21 @@ static struct resource* hwif_request_region(ide_hwif_t *hwif,
 int ide_hwif_request_regions(ide_hwif_t *hwif)
 {
 	unsigned long addr;
-	unsigned int i;
 
 	if (hwif->mmio)
 		return 0;
+
 	addr = hwif->io_ports[IDE_CONTROL_OFFSET];
+
 	if (addr && !hwif_request_region(hwif, addr, 1))
 		goto control_region_busy;
-	hwif->straight8 = 0;
+
 	addr = hwif->io_ports[IDE_DATA_OFFSET];
-	if ((addr | 7) == hwif->io_ports[IDE_STATUS_OFFSET]) {
-		if (!hwif_request_region(hwif, addr, 8))
-			goto data_region_busy;
-		hwif->straight8 = 1;
-		return 0;
-	}
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		addr = hwif->io_ports[i];
-		if (!hwif_request_region(hwif, addr, 1)) {
-			while (--i)
-				release_region(addr, 1);
-			goto data_region_busy;
-		}
-	}
+	BUG_ON((addr | 7) != hwif->io_ports[IDE_STATUS_OFFSET]);
+
+	if (!hwif_request_region(hwif, addr, 8))
+		goto data_region_busy;
+
 	return 0;
 
 data_region_busy:
@@ -328,19 +291,13 @@ control_region_busy:
 
 void ide_hwif_release_regions(ide_hwif_t *hwif)
 {
-	u32 i = 0;
-
 	if (hwif->mmio)
 		return;
+
 	if (hwif->io_ports[IDE_CONTROL_OFFSET])
 		release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
-	if (hwif->straight8) {
-		release_region(hwif->io_ports[IDE_DATA_OFFSET], 8);
-		return;
-	}
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		if (hwif->io_ports[i])
-			release_region(hwif->io_ports[i], 1);
+
+	release_region(hwif->io_ports[IDE_DATA_OFFSET], 8);
 }
 
 void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
@@ -627,11 +584,13 @@ out:
 int set_pio_mode(ide_drive_t *drive, int arg)
 {
 	struct request rq;
+	ide_hwif_t *hwif = drive->hwif;
 
 	if (arg < 0 || arg > 255)
 		return -EINVAL;
 
-	if (drive->hwif->set_pio_mode == NULL)
+	if (hwif->set_pio_mode == NULL ||
+	    (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
 		return -ENOSYS;
 
 	if (drive->special.b.set_tune)
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
index bc8b1f8..33bb7b8 100644
--- a/drivers/ide/legacy/ali14xx.c
+++ b/drivers/ide/legacy/ali14xx.c
@@ -86,7 +86,7 @@ static u8 regOff;	/* output to base port to close registers */
 /*
  * Read a controller register.
  */
-static inline u8 inReg (u8 reg)
+static inline u8 inReg(u8 reg)
 {
 	outb_p(reg, regPort);
 	return inb(dataPort);
@@ -95,7 +95,7 @@ static inline u8 inReg (u8 reg)
 /*
  * Write a controller register.
  */
-static void outReg (u8 data, u8 reg)
+static void outReg(u8 data, u8 reg)
 {
 	outb_p(reg, regPort);
 	outb_p(data, dataPort);
@@ -143,7 +143,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
 /*
  * Auto-detect the IDE controller port.
  */
-static int __init findPort (void)
+static int __init findPort(void)
 {
 	int i;
 	u8 t;
@@ -175,7 +175,8 @@ static int __init findPort (void)
 /*
  * Initialize controller registers with default values.
  */
-static int __init initRegisters (void) {
+static int __init initRegisters(void)
+{
 	const RegInitializer *p;
 	u8 t;
 	unsigned long flags;
@@ -199,7 +200,8 @@ static const struct ide_port_info ali14xx_port_info = {
 
 static int __init ali14xx_probe(void)
 {
-	static u8 idx[4] = { 0, 1, 0xff, 0xff };
+	ide_hwif_t *hwif, *mate;
+	static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	hw_regs_t hw[2];
 
 	printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
@@ -219,18 +221,26 @@ static int __init ali14xx_probe(void)
 	ide_std_init_ports(&hw[1], 0x170, 0x376);
 	hw[1].irq = 15;
 
-	ide_init_port_hw(&ide_hwifs[0], &hw[0]);
-	ide_init_port_hw(&ide_hwifs[1], &hw[1]);
+	hwif = ide_find_port();
+	if (hwif) {
+		ide_init_port_hw(hwif, &hw[0]);
+		hwif->set_pio_mode = &ali14xx_set_pio_mode;
+		idx[0] = hwif->index;
+	}
 
-	ide_hwifs[0].set_pio_mode = &ali14xx_set_pio_mode;
-	ide_hwifs[1].set_pio_mode = &ali14xx_set_pio_mode;
+	mate = ide_find_port();
+	if (mate) {
+		ide_init_port_hw(mate, &hw[1]);
+		mate->set_pio_mode = &ali14xx_set_pio_mode;
+		idx[1] = mate->index;
+	}
 
 	ide_device_add(idx, &ali14xx_port_info);
 
 	return 0;
 }
 
-int probe_ali14xx = 0;
+int probe_ali14xx;
 
 module_param_named(probe, probe_ali14xx, bool, 0);
 MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets");
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index fdd3791..6956eb8 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -221,7 +221,7 @@ fail_base2:
 
 			buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr);
 
-			hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+			hwif = ide_find_port();
 			if (hwif) {
 				u8 index = hwif->index;
 
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c
index 5f69cd2..9c6b324 100644
--- a/drivers/ide/legacy/dtc2278.c
+++ b/drivers/ide/legacy/dtc2278.c
@@ -102,15 +102,9 @@ static int __init dtc2278_probe(void)
 {
 	unsigned long flags;
 	ide_hwif_t *hwif, *mate;
-	static u8 idx[4] = { 0, 1, 0xff, 0xff };
+	static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	hw_regs_t hw[2];
 
-	hwif = &ide_hwifs[0];
-	mate = &ide_hwifs[1];
-
-	if (hwif->chipset != ide_unknown || mate->chipset != ide_unknown)
-		return 1;
-
 	local_irq_save(flags);
 	/*
 	 * This enables the second interface
@@ -137,10 +131,18 @@ static int __init dtc2278_probe(void)
 	ide_std_init_ports(&hw[1], 0x170, 0x376);
 	hw[1].irq = 15;
 
-	ide_init_port_hw(hwif, &hw[0]);
-	ide_init_port_hw(mate, &hw[1]);
+	hwif = ide_find_port();
+	if (hwif) {
+		ide_init_port_hw(hwif, &hw[0]);
+		hwif->set_pio_mode = dtc2278_set_pio_mode;
+		idx[0] = hwif->index;
+	}
 
-	hwif->set_pio_mode = &dtc2278_set_pio_mode;
+	mate = ide_find_port();
+	if (mate) {
+		ide_init_port_hw(mate, &hw[1]);
+		idx[1] = mate->index;
+	}
 
 	ide_device_add(idx, &dtc2278_port_info);
 
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
index e950afa..8c9c9f7 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -22,6 +22,7 @@
 #include <asm/atariints.h>
 #include <asm/atari_stdma.h>
 
+#define DRV_NAME "falconide"
 
     /*
      *  Base of the IDE interface
@@ -74,15 +75,21 @@ static int __init falconide_init(void)
 
 	printk(KERN_INFO "ide: Falcon IDE controller\n");
 
+	if (!request_mem_region(ATA_HD_BASE, 0x40, DRV_NAME)) {
+		printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+		return -EBUSY;
+	}
+
 	falconide_setup_ports(&hw);
 
-	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	hwif = ide_find_port();
 	if (hwif) {
 		u8 index = hwif->index;
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
 
 		ide_init_port_data(hwif, index);
 		ide_init_port_hw(hwif, &hw);
+		hwif->mmio = 1;
 
 		ide_get_lock(NULL, NULL);
 		ide_device_add(idx, NULL);
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index e3b4638..fcc8d52 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -175,7 +175,7 @@ found:
 
 	gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr);
 
-	hwif = ide_find_port(base);
+	hwif = ide_find_port();
 	if (hwif) {
 	    u8 index = hwif->index;
 
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 0b0d867..abdedf5 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -122,12 +122,12 @@ static int hd_error;
  *  This struct defines the HD's and their types.
  */
 struct hd_i_struct {
-	unsigned int head,sect,cyl,wpcom,lzone,ctl;
+	unsigned int head, sect, cyl, wpcom, lzone, ctl;
 	int unit;
 	int recalibrate;
 	int special_op;
 };
-	
+
 #ifdef HD_TYPE
 static struct hd_i_struct hd_info[] = { HD_TYPE };
 static int NR_HD = ARRAY_SIZE(hd_info);
@@ -168,7 +168,7 @@ unsigned long read_timer(void)
 
 	spin_lock_irqsave(&i8253_lock, flags);
 	t = jiffies * 11932;
-    	outb_p(0, 0x43);
+	outb_p(0, 0x43);
 	i = inb_p(0x40);
 	i |= inb(0x40) << 8;
 	spin_unlock_irqrestore(&i8253_lock, flags);
@@ -183,7 +183,7 @@ static void __init hd_setup(char *str, int *ints)
 	if (ints[0] != 3)
 		return;
 	if (hd_info[0].head != 0)
-		hdind=1;
+		hdind = 1;
 	hd_info[hdind].head = ints[2];
 	hd_info[hdind].sect = ints[3];
 	hd_info[hdind].cyl = ints[1];
@@ -193,7 +193,7 @@ static void __init hd_setup(char *str, int *ints)
 	NR_HD = hdind+1;
 }
 
-static void dump_status (const char *msg, unsigned int stat)
+static void dump_status(const char *msg, unsigned int stat)
 {
 	char *name = "hd?";
 	if (CURRENT)
@@ -291,7 +291,6 @@ static int controller_ready(unsigned int drive, unsigned int head)
 	return 0;
 }
 
-		
 static void hd_out(struct hd_i_struct *disk,
 		   unsigned int nsect,
 		   unsigned int sect,
@@ -313,15 +312,15 @@ static void hd_out(struct hd_i_struct *disk,
 		return;
 	}
 	SET_HANDLER(intr_addr);
-	outb_p(disk->ctl,HD_CMD);
-	port=HD_DATA;
-	outb_p(disk->wpcom>>2,++port);
-	outb_p(nsect,++port);
-	outb_p(sect,++port);
-	outb_p(cyl,++port);
-	outb_p(cyl>>8,++port);
-	outb_p(0xA0|(disk->unit<<4)|head,++port);
-	outb_p(cmd,++port);
+	outb_p(disk->ctl, HD_CMD);
+	port = HD_DATA;
+	outb_p(disk->wpcom >> 2, ++port);
+	outb_p(nsect, ++port);
+	outb_p(sect, ++port);
+	outb_p(cyl, ++port);
+	outb_p(cyl >> 8, ++port);
+	outb_p(0xA0 | (disk->unit << 4) | head, ++port);
+	outb_p(cmd, ++port);
 }
 
 static void hd_request (void);
@@ -344,14 +343,14 @@ static void reset_controller(void)
 {
 	int	i;
 
-	outb_p(4,HD_CMD);
-	for(i = 0; i < 1000; i++) barrier();
-	outb_p(hd_info[0].ctl & 0x0f,HD_CMD);
-	for(i = 0; i < 1000; i++) barrier();
+	outb_p(4, HD_CMD);
+	for (i = 0; i < 1000; i++) barrier();
+	outb_p(hd_info[0].ctl & 0x0f, HD_CMD);
+	for (i = 0; i < 1000; i++) barrier();
 	if (drive_busy())
 		printk("hd: controller still busy\n");
 	else if ((hd_error = inb(HD_ERROR)) != 1)
-		printk("hd: controller reset failed: %02x\n",hd_error);
+		printk("hd: controller reset failed: %02x\n", hd_error);
 }
 
 static void reset_hd(void)
@@ -371,8 +370,8 @@ repeat:
 	if (++i < NR_HD) {
 		struct hd_i_struct *disk = &hd_info[i];
 		disk->special_op = disk->recalibrate = 1;
-		hd_out(disk,disk->sect,disk->sect,disk->head-1,
-			disk->cyl,WIN_SPECIFY,&reset_hd);
+		hd_out(disk, disk->sect, disk->sect, disk->head-1,
+			disk->cyl, WIN_SPECIFY, &reset_hd);
 		if (reset)
 			goto repeat;
 	} else
@@ -393,7 +392,7 @@ static void unexpected_hd_interrupt(void)
 	unsigned int stat = inb_p(HD_STATUS);
 
 	if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) {
-		dump_status ("unexpected interrupt", stat);
+		dump_status("unexpected interrupt", stat);
 		SET_TIMER;
 	}
 }
@@ -453,7 +452,7 @@ static void read_intr(void)
 	return;
 ok_to_read:
 	req = CURRENT;
-	insw(HD_DATA,req->buffer,256);
+	insw(HD_DATA, req->buffer, 256);
 	req->sector++;
 	req->buffer += 512;
 	req->errors = 0;
@@ -507,7 +506,7 @@ ok_to_write:
 		end_request(req, 1);
 	if (i > 0) {
 		SET_HANDLER(&write_intr);
-		outsw(HD_DATA,req->buffer,256);
+		outsw(HD_DATA, req->buffer, 256);
 		local_irq_enable();
 	} else {
 #if (HD_DELAY > 0)
@@ -560,11 +559,11 @@ static int do_special_op(struct hd_i_struct *disk, struct request *req)
 {
 	if (disk->recalibrate) {
 		disk->recalibrate = 0;
-		hd_out(disk,disk->sect,0,0,0,WIN_RESTORE,&recal_intr);
+		hd_out(disk, disk->sect, 0, 0, 0, WIN_RESTORE, &recal_intr);
 		return reset;
 	}
 	if (disk->head > 16) {
-		printk ("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name);
+		printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name);
 		end_request(req, 0);
 	}
 	disk->special_op = 0;
@@ -633,19 +632,21 @@ repeat:
 	if (blk_fs_request(req)) {
 		switch (rq_data_dir(req)) {
 		case READ:
-			hd_out(disk,nsect,sec,head,cyl,WIN_READ,&read_intr);
+			hd_out(disk, nsect, sec, head, cyl, WIN_READ,
+				&read_intr);
 			if (reset)
 				goto repeat;
 			break;
 		case WRITE:
-			hd_out(disk,nsect,sec,head,cyl,WIN_WRITE,&write_intr);
+			hd_out(disk, nsect, sec, head, cyl, WIN_WRITE,
+				&write_intr);
 			if (reset)
 				goto repeat;
 			if (wait_DRQ()) {
 				bad_rw_intr();
 				goto repeat;
 			}
-			outsw(HD_DATA,req->buffer,256);
+			outsw(HD_DATA, req->buffer, 256);
 			break;
 		default:
 			printk("unknown hd-command\n");
@@ -655,7 +656,7 @@ repeat:
 	}
 }
 
-static void do_hd_request (struct request_queue * q)
+static void do_hd_request(struct request_queue *q)
 {
 	disable_irq(HD_IRQ);
 	hd_request();
@@ -708,12 +709,12 @@ static int __init hd_init(void)
 {
 	int drive;
 
-	if (register_blkdev(MAJOR_NR,"hd"))
+	if (register_blkdev(MAJOR_NR, "hd"))
 		return -1;
 
 	hd_queue = blk_init_queue(do_hd_request, &hd_lock);
 	if (!hd_queue) {
-		unregister_blkdev(MAJOR_NR,"hd");
+		unregister_blkdev(MAJOR_NR, "hd");
 		return -ENOMEM;
 	}
 
@@ -742,7 +743,7 @@ static int __init hd_init(void)
 		goto out;
 	}
 
-	for (drive=0 ; drive < NR_HD ; drive++) {
+	for (drive = 0 ; drive < NR_HD ; drive++) {
 		struct gendisk *disk = alloc_disk(64);
 		struct hd_i_struct *p = &hd_info[drive];
 		if (!disk)
@@ -756,7 +757,7 @@ static int __init hd_init(void)
 		disk->queue = hd_queue;
 		p->unit = drive;
 		hd_gendisk[drive] = disk;
-		printk ("%s: %luMB, CHS=%d/%d/%d\n",
+		printk("%s: %luMB, CHS=%d/%d/%d\n",
 			disk->disk_name, (unsigned long)get_capacity(disk)/2048,
 			p->cyl, p->head, p->sect);
 	}
@@ -776,7 +777,7 @@ static int __init hd_init(void)
 	}
 
 	/* Let them fly */
-	for(drive=0; drive < NR_HD; drive++)
+	for (drive = 0; drive < NR_HD; drive++)
 		add_disk(hd_gendisk[drive]);
 
 	return 0;
@@ -791,7 +792,7 @@ out1:
 	NR_HD = 0;
 out:
 	del_timer(&device_timer);
-	unregister_blkdev(MAJOR_NR,"hd");
+	unregister_blkdev(MAJOR_NR, "hd");
 	blk_cleanup_queue(hd_queue);
 	return -1;
 Enomem:
@@ -800,7 +801,8 @@ Enomem:
 	goto out;
 }
 
-static int __init parse_hd_setup (char *line) {
+static int __init parse_hd_setup(char *line)
+{
 	int ints[6];
 
 	(void) get_options(line, ARRAY_SIZE(ints), ints);
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index 88fe907..60f52f5 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -35,6 +35,7 @@
  *  Try:  http://www.maf.iki.fi/~maf/ht6560b/
  */
 
+#define DRV_NAME	"ht6560b"
 #define HT6560B_VERSION "v0.08"
 
 #include <linux/module.h>
@@ -339,16 +340,13 @@ static const struct ide_port_info ht6560b_port_info __initdata = {
 static int __init ht6560b_init(void)
 {
 	ide_hwif_t *hwif, *mate;
-	static u8 idx[4] = { 0, 1, 0xff, 0xff };
+	static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	hw_regs_t hw[2];
 
 	if (probe_ht6560b == 0)
 		return -ENODEV;
 
-	hwif = &ide_hwifs[0];
-	mate = &ide_hwifs[1];
-
-	if (!request_region(HT_CONFIG_PORT, 1, hwif->name)) {
+	if (!request_region(HT_CONFIG_PORT, 1, DRV_NAME)) {
 		printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n",
 			__FUNCTION__);
 		return -ENODEV;
@@ -367,17 +365,23 @@ static int __init ht6560b_init(void)
 	ide_std_init_ports(&hw[1], 0x170, 0x376);
 	hw[1].irq = 15;
 
-	ide_init_port_hw(hwif, &hw[0]);
-	ide_init_port_hw(mate, &hw[1]);
-
-	hwif->selectproc = &ht6560b_selectproc;
-	hwif->set_pio_mode = &ht6560b_set_pio_mode;
-
-	mate->selectproc = &ht6560b_selectproc;
-	mate->set_pio_mode = &ht6560b_set_pio_mode;
+	hwif = ide_find_port();
+	if (hwif) {
+		ide_init_port_hw(hwif, &hw[0]);
+		hwif->selectproc     = ht6560b_selectproc;
+		hwif->set_pio_mode   = ht6560b_set_pio_mode;
+		hwif->port_init_devs = ht6560b_port_init_devs;
+		idx[0] = hwif->index;
+	}
 
-	hwif->port_init_devs = ht6560b_port_init_devs;
-	mate->port_init_devs = ht6560b_port_init_devs;
+	mate = ide_find_port();
+	if (mate) {
+		ide_init_port_hw(mate, &hw[1]);
+		mate->selectproc     = ht6560b_selectproc;
+		mate->set_pio_mode   = ht6560b_set_pio_mode;
+		mate->port_init_devs = ht6560b_port_init_devs;
+		idx[1] = mate->index;
+	}
 
 	ide_device_add(idx, &ht6560b_port_info);
 
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c
index ecd7f35..c352f12 100644
--- a/drivers/ide/legacy/ide-4drives.c
+++ b/drivers/ide/legacy/ide-4drives.c
@@ -4,7 +4,7 @@
 #include <linux/module.h>
 #include <linux/ide.h>
 
-int probe_4drives = 0;
+int probe_4drives;
 
 module_param_named(probe, probe_4drives, bool, 0);
 MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
@@ -12,31 +12,37 @@ MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
 static int __init ide_4drives_init(void)
 {
 	ide_hwif_t *hwif, *mate;
-	u8 idx[4] = { 0, 1, 0xff, 0xff };
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	hw_regs_t hw;
 
 	if (probe_4drives == 0)
 		return -ENODEV;
 
-	hwif = &ide_hwifs[0];
-	mate = &ide_hwifs[1];
-
 	memset(&hw, 0, sizeof(hw));
 
 	ide_std_init_ports(&hw, 0x1f0, 0x3f6);
 	hw.irq = 14;
 	hw.chipset = ide_4drives;
 
-	ide_init_port_hw(hwif, &hw);
-	ide_init_port_hw(mate, &hw);
-
-	mate->drives[0].select.all ^= 0x20;
-	mate->drives[1].select.all ^= 0x20;
-
-	hwif->mate = mate;
-	mate->mate = hwif;
-
-	hwif->serialized = mate->serialized = 1;
+	hwif = ide_find_port();
+	if (hwif) {
+		ide_init_port_hw(hwif, &hw);
+		idx[0] = hwif->index;
+	}
+
+	mate = ide_find_port();
+	if (mate) {
+		ide_init_port_hw(mate, &hw);
+		mate->drives[0].select.all ^= 0x20;
+		mate->drives[1].select.all ^= 0x20;
+		idx[1] = mate->index;
+
+		if (hwif) {
+			hwif->mate = mate;
+			mate->mate = hwif;
+			hwif->serialized = mate->serialized = 1;
+		}
+	}
 
 	ide_device_add(idx, NULL);
 
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 9a23b94..b97b8d5 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -156,7 +156,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq
     hw.chipset = ide_pci;
     hw.dev = &handle->dev;
 
-    hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+    hwif = ide_find_port();
     if (hwif == NULL)
 	return -1;
 
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
index 361b1bb..bf24077 100644
--- a/drivers/ide/legacy/ide_platform.c
+++ b/drivers/ide/legacy/ide_platform.c
@@ -89,7 +89,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
 			res_alt->start, res_alt->end - res_alt->start + 1);
 	}
 
-	hwif = ide_find_port((unsigned long)base);
+	hwif = ide_find_port();
 	if (!hwif) {
 		ret = -ENODEV;
 		goto out;
@@ -100,11 +100,10 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
 	hw.dev = &pdev->dev;
 
 	ide_init_port_hw(hwif, &hw);
+	hwif->mmio = 1;
 
-	if (mmio) {
-		hwif->mmio = 1;
+	if (mmio)
 		default_hwif_mmiops(hwif);
-	}
 
 	idx[0] = hwif->index;
 
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index eaf5dbe..7429b80 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -120,7 +120,7 @@ static int __init macide_init(void)
 
 	macide_setup_ports(&hw, base, irq, ack_intr);
 
-	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	hwif = ide_find_port();
 	if (hwif) {
 		u8 index = hwif->index;
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index 2da2875..fcbff0e 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -137,7 +137,7 @@ static int __init q40ide_init(void)
 //			m68kide_iops,
 			q40ide_default_irq(pcide_bases[i]));
 
-	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	hwif = ide_find_port();
 	if (hwif) {
 		ide_init_port_data(hwif, hwif->index);
 		ide_init_port_hw(hwif, &hw);
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
index 7016bdf..6e820c7 100644
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -88,12 +88,12 @@
 static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
 
 /*
- * qd_select:
+ * qd65xx_select:
  *
- * This routine is invoked from ide.c to prepare for access to a given drive.
+ * This routine is invoked to prepare for access to a given drive.
  */
 
-static void qd_select (ide_drive_t *drive)
+static void qd65xx_select(ide_drive_t *drive)
 {
 	u8 index = ((	(QD_TIMREG(drive)) & 0x80 ) >> 7) |
 			(QD_TIMREG(drive) & 0x02);
@@ -168,36 +168,15 @@ static int qd_find_disk_type (ide_drive_t *drive,
 }
 
 /*
- * qd_timing_ok:
- *
- * check whether timings don't conflict
- */
-
-static int qd_timing_ok (ide_drive_t drives[])
-{
-	return (IDE_IMPLY(drives[0].present && drives[1].present,
-			IDE_IMPLY(QD_TIMREG(drives) == QD_TIMREG(drives+1),
-			          QD_TIMING(drives) == QD_TIMING(drives+1))));
-	/* if same timing register, must be same timing */
-}
-
-/*
  * qd_set_timing:
  *
- * records the timing, and enables selectproc as needed
+ * records the timing
  */
 
 static void qd_set_timing (ide_drive_t *drive, u8 timing)
 {
-	ide_hwif_t *hwif = HWIF(drive);
-
 	drive->drive_data &= 0xff00;
 	drive->drive_data |= timing;
-	if (qd_timing_ok(hwif->drives)) {
-		qd_select(drive); /* selects once */
-		hwif->selectproc = NULL;
-	} else
-		hwif->selectproc = &qd_select;
 
 	printk(KERN_DEBUG "%s: %#x\n", drive->name, timing);
 }
@@ -225,10 +204,11 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
 static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-	int base = HWIF(drive)->select_data;
+	ide_hwif_t *hwif = drive->hwif;
 	unsigned int cycle_time;
 	int active_time   = 175;
 	int recovery_time = 415; /* worst case values from the dos driver */
+	u8 base = (hwif->config_data & 0xff00) >> 8;
 
 	if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) {
 		cycle_time = ide_pio_cycle_time(drive, pio);
@@ -299,21 +279,10 @@ static int __init qd_testreg(int port)
 	return (readreg != QD_TESTVAL);
 }
 
-/*
- * qd_setup:
- *
- * called to setup an ata channel : adjusts attributes & links for tuning
- */
-
-static void __init qd_setup(ide_hwif_t *hwif, int base, int config)
-{
-	hwif->select_data = base;
-	hwif->config_data = config;
-}
-
 static void __init qd6500_port_init_devs(ide_hwif_t *hwif)
 {
-	u8 base = hwif->select_data, config = QD_CONFIG(hwif);
+	u8 base = (hwif->config_data & 0xff00) >> 8;
+	u8 config = QD_CONFIG(hwif);
 
 	hwif->drives[0].drive_data = QD6500_DEF_DATA;
 	hwif->drives[1].drive_data = QD6500_DEF_DATA;
@@ -322,9 +291,10 @@ static void __init qd6500_port_init_devs(ide_hwif_t *hwif)
 static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
 {
 	u16 t1, t2;
-	u8 base = hwif->select_data, config = QD_CONFIG(hwif);
+	u8 base = (hwif->config_data & 0xff00) >> 8;
+	u8 config = QD_CONFIG(hwif);
 
-	if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
+	if (hwif->host_flags & IDE_HFLAG_SINGLE) {
 		t1 = QD6580_DEF_DATA;
 		t2 = QD6580_DEF_DATA2;
 	} else
@@ -355,14 +325,18 @@ static int __init qd_probe(int base)
 	u8 config, unit;
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	hw_regs_t hw[2];
+	struct ide_port_info d = qd65xx_port_info;
 
 	config = inb(QD_CONFIG_PORT);
 
 	if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) )
-		return 1;
+		return -ENODEV;
 
 	unit = ! (config & QD_CONFIG_IDE_BASEPORT);
 
+	if (unit)
+		d.host_flags |= IDE_HFLAG_QD_2ND_PORT;
+
 	memset(&hw, 0, sizeof(hw));
 
 	ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
@@ -373,30 +347,37 @@ static int __init qd_probe(int base)
 
 	if ((config & 0xf0) == QD_CONFIG_QD6500) {
 
-		if (qd_testreg(base)) return 1;		/* bad register */
+		if (qd_testreg(base))
+			 return -ENODEV;	/* bad register */
 
 		/* qd6500 found */
 
-		hwif = &ide_hwifs[unit];
-		printk(KERN_NOTICE "%s: qd6500 at %#x\n", hwif->name, base);
-		printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
-			config, QD_ID3);
-		
 		if (config & QD_CONFIG_DISABLED) {
 			printk(KERN_WARNING "qd6500 is disabled !\n");
-			return 1;
+			return -ENODEV;
 		}
 
+		printk(KERN_NOTICE "qd6500 at %#x\n", base);
+		printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
+			config, QD_ID3);
+
+		d.host_flags |= IDE_HFLAG_SINGLE;
+
+		hwif = ide_find_port_slot(&d);
+		if (hwif == NULL)
+			return -ENOENT;
+
 		ide_init_port_hw(hwif, &hw[unit]);
 
-		qd_setup(hwif, base, config);
+		hwif->config_data = (base << 8) | config;
 
 		hwif->port_init_devs = qd6500_port_init_devs;
-		hwif->set_pio_mode = &qd6500_set_pio_mode;
+		hwif->set_pio_mode   = qd6500_set_pio_mode;
+		hwif->selectproc     = qd65xx_select;
 
-		idx[unit] = unit;
+		idx[unit] = hwif->index;
 
-		ide_device_add(idx, &qd65xx_port_info);
+		ide_device_add(idx, &d);
 
 		return 1;
 	}
@@ -406,8 +387,8 @@ static int __init qd_probe(int base)
 
 		u8 control;
 
-		if (qd_testreg(base) || qd_testreg(base+0x02)) return 1;
-			/* bad registers */
+		if (qd_testreg(base) || qd_testreg(base + 0x02))
+			return -ENODEV;	/* bad registers */
 
 		/* qd6580 found */
 
@@ -422,46 +403,52 @@ static int __init qd_probe(int base)
 		if (control & QD_CONTR_SEC_DISABLED) {
 			/* secondary disabled */
 
-			hwif = &ide_hwifs[unit];
-			printk(KERN_INFO "%s: qd6580: single IDE board\n",
-					 hwif->name);
+			printk(KERN_INFO "qd6580: single IDE board\n");
+
+			d.host_flags |= IDE_HFLAG_SINGLE;
+
+			hwif = ide_find_port_slot(&d);
+			if (hwif == NULL)
+				return -ENOENT;
 
 			ide_init_port_hw(hwif, &hw[unit]);
 
-			qd_setup(hwif, base, config | (control << 8));
+			hwif->config_data = (base << 8) | config;
 
 			hwif->port_init_devs = qd6580_port_init_devs;
-			hwif->set_pio_mode = &qd6580_set_pio_mode;
+			hwif->set_pio_mode   = qd6580_set_pio_mode;
+			hwif->selectproc     = qd65xx_select;
 
-			idx[unit] = unit;
+			idx[unit] = hwif->index;
 
-			ide_device_add(idx, &qd65xx_port_info);
+			ide_device_add(idx, &d);
 
 			return 1;
 		} else {
 			ide_hwif_t *mate;
 
-			hwif = &ide_hwifs[0];
-			mate = &ide_hwifs[1];
 			/* secondary enabled */
-			printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n",
-					hwif->name, mate->name);
-
-			ide_init_port_hw(hwif, &hw[0]);
-			ide_init_port_hw(mate, &hw[1]);
-
-			qd_setup(hwif, base, config | (control << 8));
-
-			hwif->port_init_devs = qd6580_port_init_devs;
-			hwif->set_pio_mode = &qd6580_set_pio_mode;
-
-			qd_setup(mate, base, config | (control << 8));
-
-			mate->port_init_devs = qd6580_port_init_devs;
-			mate->set_pio_mode = &qd6580_set_pio_mode;
-
-			idx[0] = 0;
-			idx[1] = 1;
+			printk(KERN_INFO "qd6580: dual IDE board\n");
+
+			hwif = ide_find_port();
+			if (hwif) {
+				ide_init_port_hw(hwif, &hw[0]);
+				hwif->config_data = (base << 8) | config;
+				hwif->port_init_devs = qd6580_port_init_devs;
+				hwif->set_pio_mode   = qd6580_set_pio_mode;
+				hwif->selectproc     = qd65xx_select;
+				idx[0] = hwif->index;
+			}
+
+			mate = ide_find_port();
+			if (mate) {
+				ide_init_port_hw(mate, &hw[1]);
+				mate->config_data = (base << 8) | config;
+				mate->port_init_devs = qd6580_port_init_devs;
+				mate->set_pio_mode   = qd6580_set_pio_mode;
+				mate->selectproc     = qd65xx_select;
+				idx[1] = mate->index;
+			}
 
 			ide_device_add(idx, &qd65xx_port_info);
 
@@ -469,7 +456,7 @@ static int __init qd_probe(int base)
 		}
 	}
 	/* no qd65xx found */
-	return 1;
+	return -ENODEV;
 }
 
 int probe_qd65xx = 0;
@@ -479,14 +466,18 @@ MODULE_PARM_DESC(probe, "probe for QD65xx chipsets");
 
 static int __init qd65xx_init(void)
 {
+	int rc1, rc2 = -ENODEV;
+
 	if (probe_qd65xx == 0)
 		return -ENODEV;
 
-	if (qd_probe(0x30))
-		qd_probe(0xb0);
-	if (ide_hwifs[0].chipset != ide_qd65xx &&
-	    ide_hwifs[1].chipset != ide_qd65xx)
+	rc1 = qd_probe(0x30);
+	if (rc1)
+		rc2 = qd_probe(0xb0);
+
+	if (rc1 < 0 && rc2 < 0)
 		return -ENODEV;
+
 	return 0;
 }
 
diff --git a/drivers/ide/legacy/qd65xx.h b/drivers/ide/legacy/qd65xx.h
index 28dd50a..c83dea8 100644
--- a/drivers/ide/legacy/qd65xx.h
+++ b/drivers/ide/legacy/qd65xx.h
@@ -30,7 +30,6 @@
 #define QD_ID3			((config & QD_CONFIG_ID3)!=0)
 
 #define QD_CONFIG(hwif)		((hwif)->config_data & 0x00ff)
-#define QD_CONTROL(hwif)	(((hwif)->config_data & 0xff00) >> 8)
 
 #define QD_TIMING(drive)	(byte)(((drive)->drive_data) & 0x00ff)
 #define QD_TIMREG(drive)	(byte)((((drive)->drive_data) & 0xff00) >> 8)
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
index bc19448..4d90bad 100644
--- a/drivers/ide/legacy/umc8672.c
+++ b/drivers/ide/legacy/umc8672.c
@@ -19,7 +19,7 @@
  */
 
 /*
- * VLB Controller Support from 
+ * VLB Controller Support from
  * Wolfram Podien
  * Rohoefe 3
  * D28832 Achim
@@ -32,7 +32,7 @@
  * #define UMC_DRIVE0 11
  * in the beginning of the driver, which sets the speed of drive 0 to 11 (there
  * are some lines present). 0 - 11 are allowed speed values. These values are
- * the results from the DOS speed test program supplied from UMC. 11 is the 
+ * the results from the DOS speed test program supplied from UMC. 11 is the
  * highest speed (about PIO mode 3)
  */
 #define REALLY_SLOW_IO		/* some systems can safely undef this */
@@ -60,62 +60,62 @@
 #define UMC_DRIVE3      1              /* In case of crash reduce speed */
 
 static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3};
-static const u8 pio_to_umc [5] = {0,3,7,10,11};	/* rough guesses */
+static const u8 pio_to_umc [5] = {0, 3, 7, 10, 11};	/* rough guesses */
 
 /*       0    1    2    3    4    5    6    7    8    9    10   11      */
 static const u8 speedtab [3][12] = {
-	{0xf, 0xb, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
-	{0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 },
-	{0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}};
+	{0x0f, 0x0b, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1},
+	{0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1},
+	{0xff, 0xcb, 0xc0, 0x58, 0x36, 0x33, 0x23, 0x22, 0x21, 0x11, 0x10, 0x0}
+};
 
-static void out_umc (char port,char wert)
+static void out_umc(char port, char wert)
 {
-	outb_p(port,0x108);
-	outb_p(wert,0x109);
+	outb_p(port, 0x108);
+	outb_p(wert, 0x109);
 }
 
-static inline u8 in_umc (char port)
+static inline u8 in_umc(char port)
 {
-	outb_p(port,0x108);
+	outb_p(port, 0x108);
 	return inb_p(0x109);
 }
 
-static void umc_set_speeds (u8 speeds[])
+static void umc_set_speeds(u8 speeds[])
 {
 	int i, tmp;
 
-	outb_p(0x5A,0x108); /* enable umc */
+	outb_p(0x5A, 0x108); /* enable umc */
 
-	out_umc (0xd7,(speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4)));
-	out_umc (0xd6,(speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4)));
+	out_umc(0xd7, (speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4)));
+	out_umc(0xd6, (speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4)));
 	tmp = 0;
-	for (i = 3; i >= 0; i--) {
+	for (i = 3; i >= 0; i--)
 		tmp = (tmp << 2) | speedtab[1][speeds[i]];
+	out_umc(0xdc, tmp);
+	for (i = 0; i < 4; i++) {
+		out_umc(0xd0 + i, speedtab[2][speeds[i]]);
+		out_umc(0xd8 + i, speedtab[2][speeds[i]]);
 	}
-	out_umc (0xdc,tmp);
-	for (i = 0;i < 4; i++) {
-		out_umc (0xd0+i,speedtab[2][speeds[i]]);
-		out_umc (0xd8+i,speedtab[2][speeds[i]]);
-	}
-	outb_p(0xa5,0x108); /* disable umc */
+	outb_p(0xa5, 0x108); /* disable umc */
 
-	printk ("umc8672: drive speeds [0 to 11]: %d %d %d %d\n",
+	printk("umc8672: drive speeds [0 to 11]: %d %d %d %d\n",
 		speeds[0], speeds[1], speeds[2], speeds[3]);
 }
 
 static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	unsigned long flags;
-	ide_hwgroup_t *hwgroup = ide_hwifs[HWIF(drive)->index^1].hwgroup;
 
 	printk("%s: setting umc8672 to PIO mode%d (speed %d)\n",
 		drive->name, pio, pio_to_umc[pio]);
 	spin_lock_irqsave(&ide_lock, flags);
-	if (hwgroup && hwgroup->handler != NULL) {
+	if (hwif->mate && hwif->mate->hwgroup->handler) {
 		printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n");
 	} else {
 		current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio];
-		umc_set_speeds (current_speeds);
+		umc_set_speeds(current_speeds);
 	}
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
@@ -128,8 +128,9 @@ static const struct ide_port_info umc8672_port_info __initdata = {
 
 static int __init umc8672_probe(void)
 {
+	ide_hwif_t *hwif, *mate;
 	unsigned long flags;
-	static u8 idx[4] = { 0, 1, 0xff, 0xff };
+	static u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	hw_regs_t hw[2];
 
 	if (!request_region(0x108, 2, "umc8672")) {
@@ -137,16 +138,16 @@ static int __init umc8672_probe(void)
 		return 1;
 	}
 	local_irq_save(flags);
-	outb_p(0x5A,0x108); /* enable umc */
+	outb_p(0x5A, 0x108); /* enable umc */
 	if (in_umc (0xd5) != 0xa0) {
 		local_irq_restore(flags);
 		printk(KERN_ERR "umc8672: not found\n");
 		release_region(0x108, 2);
-		return 1;  
+		return 1;
 	}
-	outb_p(0xa5,0x108); /* disable umc */
+	outb_p(0xa5, 0x108); /* disable umc */
 
-	umc_set_speeds (current_speeds);
+	umc_set_speeds(current_speeds);
 	local_irq_restore(flags);
 
 	memset(&hw, 0, sizeof(hw));
@@ -157,18 +158,26 @@ static int __init umc8672_probe(void)
 	ide_std_init_ports(&hw[1], 0x170, 0x376);
 	hw[1].irq = 15;
 
-	ide_init_port_hw(&ide_hwifs[0], &hw[0]);
-	ide_init_port_hw(&ide_hwifs[1], &hw[1]);
+	hwif = ide_find_port();
+	if (hwif) {
+		ide_init_port_hw(hwif, &hw[0]);
+		hwif->set_pio_mode = umc_set_pio_mode;
+		idx[0] = hwif->index;
+	}
 
-	ide_hwifs[0].set_pio_mode = &umc_set_pio_mode;
-	ide_hwifs[1].set_pio_mode = &umc_set_pio_mode;
+	mate = ide_find_port();
+	if (mate) {
+		ide_init_port_hw(mate, &hw[1]);
+		mate->set_pio_mode = umc_set_pio_mode;
+		idx[1] = mate->index;
+	}
 
 	ide_device_add(idx, &umc8672_port_info);
 
 	return 0;
 }
 
-int probe_umc8672 = 0;
+int probe_umc8672;
 
 module_param_named(probe, probe_umc8672, bool, 0);
 MODULE_PARM_DESC(probe, "probe for UMC8672 chipset");
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 9b62824..a8cd003 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -599,9 +599,11 @@ static int au_ide_probe(struct device *dev)
 		goto out;
 	}
 
-	/* FIXME:  This might possibly break PCMCIA IDE devices */
-
-	hwif                            = &ide_hwifs[pdev->id];
+	hwif = ide_find_port();
+	if (hwif == NULL) {
+		ret = -ENOENT;
+		goto out;
+	}
 
 	memset(&hw, 0, sizeof(hw));
 	auide_setup_ports(&hw, ahwif);
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index 956259f..bbe8d58 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -76,17 +76,12 @@ static int __devinit swarm_ide_probe(struct device *dev)
 	if (!SIBYTE_HAVE_IDE)
 		return -ENODEV;
 
-	/* Find an empty slot.  */
-	for (i = 0; i < MAX_HWIFS; i++)
-		if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET])
-			break;
-	if (i >= MAX_HWIFS) {
+	hwif = ide_find_port();
+	if (hwif == NULL) {
 		printk(KERN_ERR DRV_NAME ": no free slot for interface\n");
 		return -ENOMEM;
 	}
 
-	hwif = ide_hwifs + i;
-
 	base = ioremap(A_IO_EXT_BASE, 0x800);
 	offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
 	size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index cfb3265..c9ba15a 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -220,7 +220,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
 		.init_hwif	= init_hwif_aec62xx,
 		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
 		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA |
-				  IDE_HFLAG_ABUSE_SET_DMA_MODE,
+				  IDE_HFLAG_ABUSE_SET_DMA_MODE |
+				  IDE_HFLAG_NON_BOOTABLE,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA4,
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index b3b6f51..3fa2d9f 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -750,7 +750,6 @@ static const struct ide_port_info ali15x3_chipset __devinitdata = {
 	.init_chipset	= init_chipset_ali15x3,
 	.init_hwif	= init_hwif_ali15x3,
 	.init_dma	= init_dma_ali15x3,
-	.host_flags	= IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO5,
 	.swdma_mask	= ATA_SWDMA2,
 	.mwdma_mask	= ATA_MWDMA2,
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 2ef890c..ff684d3 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -219,12 +219,10 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
 
 #define IDE_HFLAGS_AMD \
 	(IDE_HFLAG_PIO_NO_BLACKLIST | \
-	 IDE_HFLAG_PIO_NO_DOWNGRADE | \
 	 IDE_HFLAG_ABUSE_SET_DMA_MODE | \
 	 IDE_HFLAG_POST_SET_MODE | \
 	 IDE_HFLAG_IO_32BIT | \
-	 IDE_HFLAG_UNMASK_IRQS | \
-	 IDE_HFLAG_BOOTABLE)
+	 IDE_HFLAG_UNMASK_IRQS)
 
 #define DECLARE_AMD_DEV(name_str, swdma, udma)				\
 	{								\
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 7e037c8..91722f8 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -151,7 +151,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
 		.name		= "ATIIXP",
 		.init_hwif	= init_hwif_atiixp,
 		.enablebits	= {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
-		.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
+		.host_flags	= IDE_HFLAG_LEGACY_IRQS,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
@@ -159,8 +159,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
 		.name		= "SB600_PATA",
 		.init_hwif	= init_hwif_atiixp,
 		.enablebits	= {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
- 		.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS |
-				  IDE_HFLAG_BOOTABLE,
+		.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS,
 		.pio_mask	= ATA_PIO4,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index a1cfe03..b076dbf 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -4,7 +4,7 @@
 
 /*
  *  Original authors:	abramov@cecmow.enet.dec.com (Igor Abramov)
- *  			mlord@pobox.com (Mark Lord)
+ *			mlord@pobox.com (Mark Lord)
  *
  *  See linux/MAINTAINERS for address of current maintainer.
  *
@@ -98,7 +98,7 @@
 
 #define CMD640_PREFETCH_MASKS 1
 
-//#define CMD640_DUMP_REGS
+/*#define CMD640_DUMP_REGS */
 
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -112,7 +112,7 @@
 /*
  * This flag is set in ide.c by the parameter:  ide0=cmd640_vlb
  */
-int cmd640_vlb = 0;
+int cmd640_vlb;
 
 /*
  * CMD640 specific registers definition.
@@ -185,7 +185,6 @@ static DEFINE_SPINLOCK(cmd640_lock);
  * These are initialized to point at the devices we control
  */
 static ide_hwif_t  *cmd_hwif0, *cmd_hwif1;
-static ide_drive_t *cmd_drives[4];
 
 /*
  * Interface to access cmd640x registers
@@ -207,13 +206,13 @@ static unsigned int cmd640_chip_version;
 
 /* PCI method 1 access */
 
-static void put_cmd640_reg_pci1 (u16 reg, u8 val)
+static void put_cmd640_reg_pci1(u16 reg, u8 val)
 {
 	outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
 	outb_p(val, (reg & 3) | 0xcfc);
 }
 
-static u8 get_cmd640_reg_pci1 (u16 reg)
+static u8 get_cmd640_reg_pci1(u16 reg)
 {
 	outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
 	return inb_p((reg & 3) | 0xcfc);
@@ -221,14 +220,14 @@ static u8 get_cmd640_reg_pci1 (u16 reg)
 
 /* PCI method 2 access (from CMD datasheet) */
 
-static void put_cmd640_reg_pci2 (u16 reg, u8 val)
+static void put_cmd640_reg_pci2(u16 reg, u8 val)
 {
 	outb_p(0x10, 0xcf8);
 	outb_p(val, cmd640_key + reg);
 	outb_p(0, 0xcf8);
 }
 
-static u8 get_cmd640_reg_pci2 (u16 reg)
+static u8 get_cmd640_reg_pci2(u16 reg)
 {
 	u8 b;
 
@@ -240,13 +239,13 @@ static u8 get_cmd640_reg_pci2 (u16 reg)
 
 /* VLB access */
 
-static void put_cmd640_reg_vlb (u16 reg, u8 val)
+static void put_cmd640_reg_vlb(u16 reg, u8 val)
 {
 	outb_p(reg, cmd640_key);
 	outb_p(val, cmd640_key + 4);
 }
 
-static u8 get_cmd640_reg_vlb (u16 reg)
+static u8 get_cmd640_reg_vlb(u16 reg)
 {
 	outb_p(reg, cmd640_key);
 	return inb_p(cmd640_key + 4);
@@ -268,11 +267,11 @@ static void put_cmd640_reg(u16 reg, u8 val)
 	unsigned long flags;
 
 	spin_lock_irqsave(&cmd640_lock, flags);
-	__put_cmd640_reg(reg,val);
+	__put_cmd640_reg(reg, val);
 	spin_unlock_irqrestore(&cmd640_lock, flags);
 }
 
-static int __init match_pci_cmd640_device (void)
+static int __init match_pci_cmd640_device(void)
 {
 	const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06};
 	unsigned int i;
@@ -292,7 +291,7 @@ static int __init match_pci_cmd640_device (void)
 /*
  * Probe for CMD640x -- pci method 1
  */
-static int __init probe_for_cmd640_pci1 (void)
+static int __init probe_for_cmd640_pci1(void)
 {
 	__get_cmd640_reg = get_cmd640_reg_pci1;
 	__put_cmd640_reg = put_cmd640_reg_pci1;
@@ -308,7 +307,7 @@ static int __init probe_for_cmd640_pci1 (void)
 /*
  * Probe for CMD640x -- pci method 2
  */
-static int __init probe_for_cmd640_pci2 (void)
+static int __init probe_for_cmd640_pci2(void)
 {
 	__get_cmd640_reg = get_cmd640_reg_pci2;
 	__put_cmd640_reg = put_cmd640_reg_pci2;
@@ -322,7 +321,7 @@ static int __init probe_for_cmd640_pci2 (void)
 /*
  * Probe for CMD640x -- vlb
  */
-static int __init probe_for_cmd640_vlb (void)
+static int __init probe_for_cmd640_vlb(void)
 {
 	u8 b;
 
@@ -343,7 +342,7 @@ static int __init probe_for_cmd640_vlb (void)
  *  Returns 1 if an IDE interface/drive exists at 0x170,
  *  Returns 0 otherwise.
  */
-static int __init secondary_port_responding (void)
+static int __init secondary_port_responding(void)
 {
 	unsigned long flags;
 
@@ -367,7 +366,7 @@ static int __init secondary_port_responding (void)
 /*
  * Dump out all cmd640 registers.  May be called from ide.c
  */
-static void cmd640_dump_regs (void)
+static void cmd640_dump_regs(void)
 {
 	unsigned int reg = cmd640_vlb ? 0x50 : 0x00;
 
@@ -386,9 +385,8 @@ static void cmd640_dump_regs (void)
  * Check whether prefetch is on for a drive,
  * and initialize the unmask flags for safe operation.
  */
-static void __init check_prefetch (unsigned int index)
+static void __init check_prefetch(ide_drive_t *drive, unsigned int index)
 {
-	ide_drive_t *drive = cmd_drives[index];
 	u8 b = get_cmd640_reg(prefetch_regs[index]);
 
 	if (b & prefetch_masks[index]) {	/* is prefetch off? */
@@ -404,28 +402,13 @@ static void __init check_prefetch (unsigned int index)
 	}
 }
 
-/*
- * Figure out which devices we control
- */
-static void __init setup_device_ptrs (void)
-{
-	cmd_hwif0 = &ide_hwifs[0];
-	cmd_hwif1 = &ide_hwifs[1];
-
-	cmd_drives[0] = &cmd_hwif0->drives[0];
-	cmd_drives[1] = &cmd_hwif0->drives[1];
-	cmd_drives[2] = &cmd_hwif1->drives[0];
-	cmd_drives[3] = &cmd_hwif1->drives[1];
-}
-
 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 
 /*
  * Sets prefetch mode for a drive.
  */
-static void set_prefetch_mode (unsigned int index, int mode)
+static void set_prefetch_mode(ide_drive_t *drive, unsigned int index, int mode)
 {
-	ide_drive_t *drive = cmd_drives[index];
 	unsigned long flags;
 	int reg = prefetch_regs[index];
 	u8 b;
@@ -452,7 +435,7 @@ static void set_prefetch_mode (unsigned int index, int mode)
 /*
  * Dump out current drive clocks settings
  */
-static void display_clocks (unsigned int index)
+static void display_clocks(unsigned int index)
 {
 	u8 active_count, recovery_count;
 
@@ -471,7 +454,7 @@ static void display_clocks (unsigned int index)
  * Pack active and recovery counts into single byte representation
  * used by controller
  */
-static inline u8 pack_nibbles (u8 upper, u8 lower)
+static inline u8 pack_nibbles(u8 upper, u8 lower)
 {
 	return ((upper & 0x0f) << 4) | (lower & 0x0f);
 }
@@ -479,7 +462,7 @@ static inline u8 pack_nibbles (u8 upper, u8 lower)
 /*
  * This routine retrieves the initial drive timings from the chipset.
  */
-static void __init retrieve_drive_counts (unsigned int index)
+static void __init retrieve_drive_counts(unsigned int index)
 {
 	u8 b;
 
@@ -488,10 +471,10 @@ static void __init retrieve_drive_counts (unsigned int index)
 	 */
 	b = get_cmd640_reg(arttim_regs[index]) & ~0x3f;
 	switch (b) {
-		case 0x00: b = 4; break;
-		case 0x80: b = 3; break;
-		case 0x40: b = 2; break;
-		default:   b = 5; break;
+	case 0x00: b = 4; break;
+	case 0x80: b = 3; break;
+	case 0x40: b = 2; break;
+	default:   b = 5; break;
 	}
 	setup_counts[index] = b;
 
@@ -508,7 +491,7 @@ static void __init retrieve_drive_counts (unsigned int index)
  * This routine writes the prepared setup/active/recovery counts
  * for a drive into the cmd640 chipset registers to active them.
  */
-static void program_drive_counts (unsigned int index)
+static void program_drive_counts(ide_drive_t *drive, unsigned int index)
 {
 	unsigned long flags;
 	u8 setup_count    = setup_counts[index];
@@ -522,8 +505,11 @@ static void program_drive_counts (unsigned int index)
 	 * so we merge the timings, using the slowest value for each timing.
 	 */
 	if (index > 1) {
-		unsigned int mate;
-		if (cmd_drives[mate = index ^ 1]->present) {
+		ide_hwif_t *hwif = drive->hwif;
+		ide_drive_t *peer = &hwif->drives[!drive->select.b.unit];
+		unsigned int mate = index ^ 1;
+
+		if (peer->present) {
 			if (setup_count < setup_counts[mate])
 				setup_count = setup_counts[mate];
 			if (active_count < active_counts[mate])
@@ -537,11 +523,11 @@ static void program_drive_counts (unsigned int index)
 	 * Convert setup_count to internal chipset representation
 	 */
 	switch (setup_count) {
-		case 4:	 setup_count = 0x00; break;
-		case 3:	 setup_count = 0x80; break;
-		case 1:
-		case 2:	 setup_count = 0x40; break;
-		default: setup_count = 0xc0; /* case 5 */
+	case 4:	 setup_count = 0x00; break;
+	case 3:	 setup_count = 0x80; break;
+	case 1:
+	case 2:	 setup_count = 0x40; break;
+	default: setup_count = 0xc0; /* case 5 */
 	}
 
 	/*
@@ -562,7 +548,8 @@ static void program_drive_counts (unsigned int index)
 /*
  * Set a specific pio_mode for a drive
  */
-static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle_time)
+static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
+			    u8 pio_mode, unsigned int cycle_time)
 {
 	int setup_time, active_time, recovery_time, clock_time;
 	u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
@@ -574,15 +561,15 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle
 	active_time = ide_pio_timings[pio_mode].active_time;
 	recovery_time = cycle_time - (setup_time + active_time);
 	clock_time = 1000 / bus_speed;
-	cycle_count = (cycle_time + clock_time - 1) / clock_time;
+	cycle_count = DIV_ROUND_UP(cycle_time, clock_time);
 
-	setup_count = (setup_time + clock_time - 1) / clock_time;
+	setup_count = DIV_ROUND_UP(setup_time, clock_time);
 
-	active_count = (active_time + clock_time - 1) / clock_time;
+	active_count = DIV_ROUND_UP(active_time, clock_time);
 	if (active_count < 2)
 		active_count = 2; /* minimum allowed by cmd640 */
 
-	recovery_count = (recovery_time + clock_time - 1) / clock_time;
+	recovery_count = DIV_ROUND_UP(recovery_time, clock_time);
 	recovery_count2 = cycle_count - (setup_count + active_count);
 	if (recovery_count2 > recovery_count)
 		recovery_count = recovery_count2;
@@ -611,7 +598,7 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle
 	 *	1) this is the wrong place to do it (proper is do_special() in ide.c)
 	 * 	2) in practice this is rarely, if ever, necessary
 	 */
-	program_drive_counts (index);
+	program_drive_counts(drive, index);
 }
 
 static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
@@ -619,32 +606,26 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	unsigned int index = 0, cycle_time;
 	u8 b;
 
-	while (drive != cmd_drives[index]) {
-		if (++index > 3) {
-			printk(KERN_ERR "%s: bad news in %s\n",
-					drive->name, __FUNCTION__);
-			return;
-		}
-	}
 	switch (pio) {
-		case 6: /* set fast-devsel off */
-		case 7: /* set fast-devsel on */
-			b = get_cmd640_reg(CNTRL) & ~0x27;
-			if (pio & 1)
-				b |= 0x27;
-			put_cmd640_reg(CNTRL, b);
-			printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, (pio & 1) ? "en" : "dis");
-			return;
-
-		case 8: /* set prefetch off */
-		case 9: /* set prefetch on */
-			set_prefetch_mode(index, pio & 1);
-			printk("%s: %sabled cmd640 prefetch\n", drive->name, (pio & 1) ? "en" : "dis");
-			return;
+	case 6: /* set fast-devsel off */
+	case 7: /* set fast-devsel on */
+		b = get_cmd640_reg(CNTRL) & ~0x27;
+		if (pio & 1)
+			b |= 0x27;
+		put_cmd640_reg(CNTRL, b);
+		printk("%s: %sabled cmd640 fast host timing (devsel)\n",
+			drive->name, (pio & 1) ? "en" : "dis");
+		return;
+	case 8: /* set prefetch off */
+	case 9: /* set prefetch on */
+		set_prefetch_mode(drive, index, pio & 1);
+		printk("%s: %sabled cmd640 prefetch\n",
+			drive->name, (pio & 1) ? "en" : "dis");
+		return;
 	}
 
 	cycle_time = ide_pio_cycle_time(drive, pio);
-	cmd640_set_mode(index, pio, cycle_time);
+	cmd640_set_mode(drive, index, pio, cycle_time);
 
 	printk("%s: selected cmd640 PIO mode%d (%dns)",
 		drive->name, pio, cycle_time);
@@ -749,7 +730,7 @@ static int __init cmd640x_init(void)
 	cfr = get_cmd640_reg(CFR);
 	cmd640_chip_version = cfr & CFR_DEVREV;
 	if (cmd640_chip_version == 0) {
-		printk ("ide: bad cmd640 revision: %d\n", cmd640_chip_version);
+		printk("ide: bad cmd640 revision: %d\n", cmd640_chip_version);
 		return 0;
 	}
 
@@ -764,17 +745,19 @@ static int __init cmd640x_init(void)
 	printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x"
 			 "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr);
 
+	cmd_hwif0 = ide_find_port();
+
 	/*
 	 * Initialize data for primary port
 	 */
-	setup_device_ptrs ();
-
-	ide_init_port_hw(cmd_hwif0, &hw[0]);
+	if (cmd_hwif0) {
+		ide_init_port_hw(cmd_hwif0, &hw[0]);
 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
-	cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode;
+		cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode;
 #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 
-	idx[0] = cmd_hwif0->index;
+		idx[0] = cmd_hwif0->index;
+	}
 
 	/*
 	 * Ensure compatibility by always using the slowest timings
@@ -786,10 +769,13 @@ static int __init cmd640x_init(void)
 	put_cmd640_reg(CMDTIM, 0);
 	put_cmd640_reg(BRST, 0x40);
 
+	cmd_hwif1 = ide_find_port();
+
 	/*
 	 * Try to enable the secondary interface, if not already enabled
 	 */
-	if (cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe) {
+	if (cmd_hwif1 &&
+	    cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe) {
 		port2 = "not probed";
 	} else {
 		b = get_cmd640_reg(CNTRL);
@@ -820,7 +806,7 @@ static int __init cmd640x_init(void)
 	/*
 	 * Initialize data for secondary cmd640 port, if enabled
 	 */
-	if (second_port_cmd640) {
+	if (second_port_cmd640 && cmd_hwif1) {
 		ide_init_port_hw(cmd_hwif1, &hw[1]);
 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 		cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode;
@@ -828,7 +814,7 @@ static int __init cmd640x_init(void)
 
 		idx[1] = cmd_hwif1->index;
 	}
-	printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name,
+	printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n",
 			 second_port_cmd640 ? "" : "not ", port2);
 
 	/*
@@ -836,18 +822,30 @@ static int __init cmd640x_init(void)
 	 * Do not unnecessarily disturb any prior BIOS setup of these.
 	 */
 	for (index = 0; index < (2 + (second_port_cmd640 << 1)); index++) {
-		ide_drive_t *drive = cmd_drives[index];
+		ide_drive_t *drive;
+
+		if (index > 1) {
+			if (cmd_hwif1 == NULL)
+				continue;
+			drive = &cmd_hwif1->drives[index & 1];
+		} else  {
+			if (cmd_hwif0 == NULL)
+				continue;
+			drive = &cmd_hwif0->drives[index & 1];
+		}
+
 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 		if (drive->autotune || ((index > 1) && second_port_toggled)) {
-	 		/*
-	 		 * Reset timing to the slowest speed and turn off prefetch.
-			 * This way, the drive identify code has a better chance.
+			/*
+			 * Reset timing to the slowest speed and turn off
+			 * prefetch.  This way, the drive identify code has
+			 * a better chance.
 			 */
 			setup_counts    [index] = 4;	/* max possible */
 			active_counts   [index] = 16;	/* max possible */
 			recovery_counts [index] = 16;	/* max possible */
-			program_drive_counts (index);
-			set_prefetch_mode (index, 0);
+			program_drive_counts(drive, index);
+			set_prefetch_mode(drive, index, 0);
 			printk("cmd640: drive%d timings/prefetch cleared\n", index);
 		} else {
 			/*
@@ -855,7 +853,7 @@ static int __init cmd640x_init(void)
 			 * This preserves any prior BIOS setup.
 			 */
 			retrieve_drive_counts (index);
-			check_prefetch (index);
+			check_prefetch(drive, index);
 			printk("cmd640: drive%d timings/prefetch(%s) preserved",
 				index, drive->no_io_32bit ? "off" : "on");
 			display_clocks(index);
@@ -864,7 +862,7 @@ static int __init cmd640x_init(void)
 		/*
 		 * Set the drive unmask flags to match the prefetch setting
 		 */
-		check_prefetch (index);
+		check_prefetch(drive, index);
 		printk("cmd640: drive%d timings/prefetch(%s) preserved\n",
 			index, drive->no_io_32bit ? "off" : "on");
 #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index edabe62..8baccfe 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -440,8 +440,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
 		.init_hwif	= init_hwif_cmd64x,
 		.enablebits	= {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
 		.host_flags	= IDE_HFLAG_CLEAR_SIMPLEX |
-				  IDE_HFLAG_ABUSE_PREFETCH |
-				  IDE_HFLAG_BOOTABLE,
+				  IDE_HFLAG_ABUSE_PREFETCH,
 		.pio_mask	= ATA_PIO5,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= 0x00, /* no udma */
@@ -451,7 +450,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
 		.init_hwif	= init_hwif_cmd64x,
 		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
 		.chipset	= ide_cmd646,
-		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH,
 		.pio_mask	= ATA_PIO5,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA2,
@@ -460,7 +459,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
 		.init_chipset	= init_chipset_cmd64x,
 		.init_hwif	= init_hwif_cmd64x,
 		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
-		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH,
 		.pio_mask	= ATA_PIO5,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA4,
@@ -469,7 +468,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
 		.init_chipset	= init_chipset_cmd64x,
 		.init_hwif	= init_hwif_cmd64x,
 		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
-		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH,
 		.pio_mask	= ATA_PIO5,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA5,
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index 1c163e4..01b37ec 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -122,8 +122,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
 				  IDE_HFLAG_CS5520 |		\
 				  IDE_HFLAG_VDMA |		\
 				  IDE_HFLAG_NO_ATAPI_DMA |	\
-				  IDE_HFLAG_ABUSE_SET_DMA_MODE |\
-				  IDE_HFLAG_BOOTABLE,		\
+				  IDE_HFLAG_ABUSE_SET_DMA_MODE, \
 		.pio_mask	= ATA_PIO4,			\
 	}
 
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 941a134..56a369c 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -249,8 +249,7 @@ static const struct ide_port_info cs5530_chipset __devinitdata = {
 	.init_chipset	= init_chipset_cs5530,
 	.init_hwif	= init_hwif_cs5530,
 	.host_flags	= IDE_HFLAG_SERIALIZE |
-			  IDE_HFLAG_POST_SET_MODE |
-			  IDE_HFLAG_BOOTABLE,
+			  IDE_HFLAG_POST_SET_MODE,
 	.pio_mask	= ATA_PIO4,
 	.mwdma_mask	= ATA_MWDMA2,
 	.udma_mask	= ATA_UDMA2,
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index d7b5ea9..c9685f2 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -186,7 +186,7 @@ static const struct ide_port_info cs5535_chipset __devinitdata = {
 	.name		= "CS5535",
 	.init_hwif	= init_hwif_cs5535,
 	.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
-			  IDE_HFLAG_ABUSE_SET_DMA_MODE | IDE_HFLAG_BOOTABLE,
+			  IDE_HFLAG_ABUSE_SET_DMA_MODE,
 	.pio_mask	= ATA_PIO4,
 	.mwdma_mask	= ATA_MWDMA2,
 	.udma_mask	= ATA_UDMA4,
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 724cbac..08eab7e 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -6,7 +6,7 @@
  *
  * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards.
  * Writing the driver was quite simple, since most of the job is
- * done by the generic pci-ide support. 
+ * done by the generic pci-ide support.
  * The hard part was finding the CY82C693's datasheet on Cypress's
  * web page :-(. But Altavista solved this problem :-).
  *
@@ -15,12 +15,12 @@
  * - I recently got a 16.8G IBM DTTA, so I was able to test it with
  *   a large and fast disk - the results look great, so I'd say the
  *   driver is working fine :-)
- *   hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA 
- * - this is my first linux driver, so there's probably a lot  of room 
+ *   hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA
+ * - this is my first linux driver, so there's probably a lot  of room
  *   for optimizations and bug fixing, so feel free to do it.
  * - use idebus=xx parameter to set PCI bus speed - needed to calc
  *   timings for PIO modes (default will be 40)
- * - if using PIO mode it's a good idea to set the PIO mode and 
+ * - if using PIO mode it's a good idea to set the PIO mode and
  *   32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda
  * - I had some problems with my IBM DHEA with PIO modes < 2
  *   (lost interrupts) ?????
@@ -110,11 +110,11 @@ typedef struct pio_clocks_s {
  * calc clocks using bus_speed
  * returns (rounded up) time in bus clocks for time in ns
  */
-static int calc_clk (int time, int bus_speed)
+static int calc_clk(int time, int bus_speed)
 {
 	int clocks;
 
-	clocks = (time*bus_speed+999)/1000 -1;
+	clocks = (time*bus_speed+999)/1000 - 1;
 
 	if (clocks < 0)
 		clocks = 0;
@@ -132,8 +132,8 @@ static int calc_clk (int time, int bus_speed)
  * NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used
  *       for mode 3 and 4 drives 8 and 16-bit timings are the same
  *
- */ 
-static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
+ */
+static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
 {
 	int clk1, clk2;
 	int bus_speed = system_bus_clock();	/* get speed of PCI bus */
@@ -158,7 +158,7 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
 	clk1 = (clk1<<4)|clk2;	/* combine active and recovery clocks */
 
 	/* note: we use the same values for 16bit IOR and IOW
-         *	those are all the same, since I don't have other
+	 *	those are all the same, since I don't have other
 	 *	timings than those from ide-lib.c
 	 */
 
@@ -186,7 +186,7 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
 	outb(index, CY82_INDEX_PORT);
 	data = inb(CY82_DATA_PORT);
 
-	printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n",
+	printk(KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n",
 		drive->name, HWIF(drive)->channel, drive->select.b.unit,
 		(data&0x3), ((data>>2)&1));
 #endif /* CY82C693_DEBUG_LOGS */
@@ -202,7 +202,7 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
 		mode & 3, single);
 #endif /* CY82C693_DEBUG_INFO */
 
-	/* 
+	/*
 	 * note: below we set the value for Bus Master IDE TimeOut Register
 	 * I'm not absolutly sure what this does, but it solved my problem
 	 * with IDE DMA and sound, so I now can play sound and work with
@@ -216,8 +216,8 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
 	outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
 	outb(data, CY82_DATA_PORT);
 
-#if CY82C693_DEBUG_INFO	
-	printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
+#if CY82C693_DEBUG_INFO
+	printk(KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
 		drive->name, data);
 #endif /* CY82C693_DEBUG_INFO */
 }
@@ -242,14 +242,14 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
 #if CY82C693_DEBUG_LOGS
 	/* for debug let's show the register values */
-	
-       	if (drive->select.b.unit == 0) {
+
+	if (drive->select.b.unit == 0) {
 		/*
-		 * get master drive registers               	
+		 * get master drive registers
 		 * address setup control register
 		 * is 32 bit !!!
-		 */ 
-	  	pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);                
+		 */
+		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 		addrCtrl &= 0x0F;
 
 		/* now let's get the remaining registers */
@@ -261,7 +261,7 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
 		 * set slave drive registers
 		 * address setup control register
 		 * is 32 bit !!!
-		 */ 
+		 */
 		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 
 		addrCtrl &= 0xF0;
@@ -288,9 +288,9 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
 		 * set master drive
 		 * address setup control register
 		 * is 32 bit !!!
-		 */ 
+		 */
 		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
-		
+
 		addrCtrl &= (~0xF);
 		addrCtrl |= (unsigned int)pclk.address_time;
 		pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
@@ -299,14 +299,14 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
 		pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
 		pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
 		pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
-		
+
 		addrCtrl &= 0xF;
 	} else {
 		/*
 		 * set slave drive
 		 * address setup control register
 		 * is 32 bit !!!
-		 */ 
+		 */
 		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 
 		addrCtrl &= (~0xF0);
@@ -320,7 +320,7 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
 		addrCtrl >>= 4;
 		addrCtrl &= 0xF;
-	}	
+	}
 
 #if CY82C693_DEBUG_INFO
 	printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to "
@@ -340,41 +340,41 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
 
 #ifdef CY82C693_SETDMA_CLOCK
 	u8 data = 0;
-#endif /* CY82C693_SETDMA_CLOCK */ 
+#endif /* CY82C693_SETDMA_CLOCK */
 
 	/* write info about this verion of the driver */
 	printk(KERN_INFO CY82_VERSION "\n");
 
 #ifdef CY82C693_SETDMA_CLOCK
        /* okay let's set the DMA clock speed */
-        
-        outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
-        data = inb(CY82_DATA_PORT);
+
+	outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
+	data = inb(CY82_DATA_PORT);
 
 #if CY82C693_DEBUG_INFO
 	printk(KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n",
 		name, data);
 #endif /* CY82C693_DEBUG_INFO */
 
-        /*
+	/*
 	 * for some reason sometimes the DMA controller
 	 * speed is set to ATCLK/2 ???? - we fix this here
-	 * 
+	 *
 	 * note: i don't know what causes this strange behaviour,
 	 *       but even changing the dma speed doesn't solve it :-(
-	 *       the ide performance is still only half the normal speed 
-	 * 
+	 *       the ide performance is still only half the normal speed
+	 *
 	 *       if anybody knows what goes wrong with my machine, please
 	 *       let me know - ASK
-         */
+	 */
 
 	data |= 0x03;
 
-        outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
-        outb(data, CY82_DATA_PORT);
+	outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
+	outb(data, CY82_DATA_PORT);
 
 #if CY82C693_DEBUG_INFO
-	printk (KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n",
+	printk(KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n",
 		name, data);
 #endif /* CY82C693_DEBUG_INFO */
 
@@ -410,8 +410,7 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = {
 	.init_iops	= init_iops_cy82c693,
 	.init_hwif	= init_hwif_cy82c693,
 	.chipset	= ide_cy82c693,
-	.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_CY82C693 |
-			  IDE_HFLAG_BOOTABLE,
+	.host_flags	= IDE_HFLAG_SINGLE,
 	.pio_mask	= ATA_PIO4,
 	.swdma_mask	= ATA_SWDMA2,
 	.mwdma_mask	= ATA_MWDMA2,
@@ -424,7 +423,7 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev
 
 	/* CY82C693 is more than only a IDE controller.
 	   Function 1 is primary IDE channel, function 2 - secondary. */
-        if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
+	if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
 	    PCI_FUNC(dev->devfn) == 1) {
 		dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
 		ret = ide_setup_pci_devices(dev, dev2, &cy82c693_chipset);
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 961698d..753b86f 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -71,14 +71,13 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
 		if (setup[i])
 			outb(setup[i], base + i);
 	}
-	pci_release_regions(dev);	/* IDE layer handles regions itself */
 
 	memset(&hw, 0, sizeof(hw));
 	ide_std_init_ports(&hw, base + 0x10, base + 0x1e);
 	hw.irq = dev->irq;
 	hw.chipset = ide_pci;		/* this enables IRQ sharing */
 
-	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
+	hwif = ide_find_port();
 	if (hwif == NULL)
 		goto out_disable;
 
@@ -90,6 +89,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
 		ide_init_port_data(hwif, i);
 
 	ide_init_port_hw(hwif, &hw);
+	hwif->mmio = 1;
 	hwif->quirkproc = &ide_undecoded_slave;
 
 	idx[0] = i;
@@ -110,6 +110,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
 
 out_disable:
 	printk(KERN_ERR "delkin_cb: no IDE devices found\n");
+	pci_release_regions(dev);
 	pci_disable_device(dev);
 	return -ENODEV;
 }
@@ -122,6 +123,7 @@ delkin_cb_remove (struct pci_dev *dev)
 	if (hwif)
 		ide_unregister(hwif->index);
 
+	pci_release_regions(dev);
 	pci_disable_device(dev);
 }
 
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index 7fd83a9..041720e 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -38,8 +38,7 @@ MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE st
 	{ \
 		.name		= name_str, \
 		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA | \
-				  extra_flags | \
-				  IDE_HFLAG_BOOTABLE, \
+				  extra_flags, \
 		.swdma_mask	= ATA_SWDMA2, \
 		.mwdma_mask	= ATA_MWDMA2, \
 		.udma_mask	= ATA_UDMA6, \
@@ -50,9 +49,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
 
 	{	/* 1 */
 		.name		= "NS87410",
-		.enablebits	= {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
-				  IDE_HFLAG_BOOTABLE,
+		.enablebits	= { {0x43, 0x08, 0x08}, {0x47, 0x08, 0x08} },
+		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
 		.swdma_mask	= ATA_SWDMA2,
 		.mwdma_mask	= ATA_MWDMA2,
 		.udma_mask	= ATA_UDMA6,
@@ -99,7 +97,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
  *	Called when the PCI registration layer (or the IDE initialization)
  *	finds a device matching our IDE device tables.
  */
- 
+
 static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	const struct ide_port_info *d = &generic_chipsets[id->driver_data];
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index 9f01da4..9f2fc30 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -133,7 +133,7 @@ static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
 		.init_chipset	= init_chipset_hpt34x,
 		.init_hwif	= init_hwif_hpt34x,
 		.extra		= 16,
-		.host_flags	= IDE_HFLAGS_HPT34X,
+		.host_flags	= IDE_HFLAGS_HPT34X | IDE_HFLAG_NON_BOOTABLE,
 		.pio_mask	= ATA_PIO5,
 	},
 	{ /* 1 */
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 82d0e31..a490906 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1557,7 +1557,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
 			hpt374_init(dev, dev2);
 		else {
 			if (hpt36x_init(dev, dev2))
-				d.host_flags |= IDE_HFLAG_BOOTABLE;
+				d.host_flags &= ~IDE_HFLAG_NON_BOOTABLE;
 		}
 
 		ret = ide_setup_pci_devices(dev, dev2, &d);
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index e3427ea..5b5b0cc 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -35,7 +35,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	static DEFINE_SPINLOCK(tune_lock);
 	int control = 0;
 
-	static const u8 timings[][2]= {
+	static const u8 timings[][2] = {
 					{ 0, 0 },
 					{ 0, 0 },
 					{ 1, 0 },
@@ -105,11 +105,10 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
 
 		if (!(reg48 & u_flag))
 			pci_write_config_byte(dev, 0x48, reg48 | u_flag);
-		if (speed >= XFER_UDMA_5) {
+		if (speed >= XFER_UDMA_5)
 			pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
-		} else {
+		else
 			pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
-		}
 
 		if ((reg4a & a_speed) != u_speed)
 			pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
@@ -170,9 +169,8 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
 	{						\
 		.name		= name_str,		\
 		.init_hwif	= init_hwif_it8213,	\
-		.enablebits	= {{0x41,0x80,0x80}}, \
-		.host_flags	= IDE_HFLAG_SINGLE |	\
-				  IDE_HFLAG_BOOTABLE,	\
+		.enablebits	= { {0x41, 0x80, 0x80} }, \
+		.host_flags	= IDE_HFLAG_SINGLE,	\
 		.pio_mask	= ATA_PIO4,		\
 		.swdma_mask	= ATA_SWDMA2_ONLY,	\
 		.mwdma_mask	= ATA_MWDMA12_ONLY,	\
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index d8a1674..a38ec47 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -523,16 +523,12 @@ static void __devinit it821x_quirkproc(ide_drive_t *drive)
 static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
-	struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
+	struct it821x_dev **itdevs = (struct it821x_dev **)pci_get_drvdata(dev);
+	struct it821x_dev *idev = itdevs[hwif->channel];
 	u8 conf;
 
 	hwif->quirkproc = &it821x_quirkproc;
 
-	if (idev == NULL) {
-		printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
-		return;
-	}
-
 	ide_set_hwifdata(hwif, idev);
 
 	pci_read_config_byte(dev, 0x50, &conf);
@@ -623,7 +619,6 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
 		.name		= name_str,		\
 		.init_chipset	= init_chipset_it821x,	\
 		.init_hwif	= init_hwif_it821x,	\
-		.host_flags	= IDE_HFLAG_BOOTABLE,	\
 		.pio_mask	= ATA_PIO4,		\
 	}
 
@@ -642,6 +637,22 @@ static const struct ide_port_info it821x_chipsets[] __devinitdata = {
 
 static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
+	struct it821x_dev *itdevs[2] = { NULL, NULL} , *itdev;
+	unsigned int i;
+
+	for (i = 0; i < 2; i++) {
+		itdev = kzalloc(sizeof(*itdev), GFP_KERNEL);
+		if (itdev == NULL) {
+			kfree(itdevs[0]);
+			printk(KERN_ERR "it821x: out of memory\n");
+			return -ENOMEM;
+		}
+
+		itdevs[i] = itdev;
+	}
+
+	pci_set_drvdata(dev, itdevs);
+
 	return ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]);
 }
 
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index a56bcb4..673f7dc 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -63,8 +63,7 @@ static u8 __devinit ata66_jmicron(ide_hwif_t *hwif)
 	 *	actually do our cable checking etc. Thankfully we don't need
 	 *	to do the plumbing for other cases.
 	 */
-	switch (port_map[port])
-	{
+	switch (port_map[port]) {
 	case PORT_PATA0:
 		if (control & (1 << 3))	/* 40/80 pin primary */
 			return ATA_CBL_PATA40;
@@ -114,7 +113,6 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
 static const struct ide_port_info jmicron_chipset __devinitdata = {
 	.name		= "JMB",
 	.init_hwif	= init_hwif_jmicron,
-	.host_flags	= IDE_HFLAG_BOOTABLE,
 	.enablebits	= { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } },
 	.pio_mask	= ATA_PIO5,
 	.mwdma_mask	= ATA_MWDMA2,
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index 7551332..3015d69 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -265,8 +265,7 @@ static const struct ide_port_info ns87415_chipset __devinitdata = {
 #endif
 	.init_hwif	= init_hwif_ns87415,
 	.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
-			  IDE_HFLAG_NO_ATAPI_DMA |
-			  IDE_HFLAG_BOOTABLE,
+			  IDE_HFLAG_NO_ATAPI_DMA,
 };
 
 static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index 46e8748..88a4dd9 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -57,9 +57,9 @@
  * (use idebus=xx to select PCI bus speed).
  *
  * Version 0.1, Nov 8, 1996
- * by Jaromir Koutek, for 2.1.8. 
+ * by Jaromir Koutek, for 2.1.8.
  * Initial version of driver.
- * 
+ *
  * Version 0.2
  * Number 0.2 skipped.
  *
@@ -75,7 +75,7 @@
  * by Jaromir Koutek
  * Updates for use with (again) new IDE block driver.
  * Update of documentation.
- * 
+ *
  * Version 0.6, Jan 2, 1999
  * by Jaromir Koutek
  * Reversed to version 0.3 of the driver, because
@@ -208,29 +208,34 @@ typedef struct pio_clocks_s {
 
 static void compute_clocks(int pio, pio_clocks_t *clks)
 {
-        if (pio != PIO_NOT_EXIST) {
-        	int adr_setup, data_pls;
+	if (pio != PIO_NOT_EXIST) {
+		int adr_setup, data_pls;
 		int bus_speed = system_bus_clock();
 
- 	       	adr_setup = ide_pio_timings[pio].setup_time;
-  	      	data_pls = ide_pio_timings[pio].active_time;
-	  	clks->address_time = cmpt_clk(adr_setup, bus_speed);
-	     	clks->data_time = cmpt_clk(data_pls, bus_speed);
-     		clks->recovery_time = cmpt_clk(ide_pio_timings[pio].cycle_time
-     			- adr_setup-data_pls, bus_speed);
-     		if (clks->address_time<1) clks->address_time = 1;
-     		if (clks->address_time>4) clks->address_time = 4;
-     		if (clks->data_time<1) clks->data_time = 1;
-     		if (clks->data_time>16) clks->data_time = 16;
-     		if (clks->recovery_time<2) clks->recovery_time = 2;
-     		if (clks->recovery_time>17) clks->recovery_time = 17;
+		adr_setup = ide_pio_timings[pio].setup_time;
+		data_pls = ide_pio_timings[pio].active_time;
+		clks->address_time = cmpt_clk(adr_setup, bus_speed);
+		clks->data_time = cmpt_clk(data_pls, bus_speed);
+		clks->recovery_time = cmpt_clk(ide_pio_timings[pio].cycle_time
+			- adr_setup-data_pls, bus_speed);
+		if (clks->address_time < 1)
+			clks->address_time = 1;
+		if (clks->address_time > 4)
+			clks->address_time = 4;
+		if (clks->data_time < 1)
+			clks->data_time = 1;
+		if (clks->data_time > 16)
+			clks->data_time = 16;
+		if (clks->recovery_time < 2)
+			clks->recovery_time = 2;
+		if (clks->recovery_time > 17)
+			clks->recovery_time = 17;
 	} else {
 		clks->address_time = 1;
 		clks->data_time = 1;
 		clks->recovery_time = 2;
 		/* minimal values */
 	}
- 
 }
 
 static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
@@ -247,8 +252,8 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
 	/* sets drive->drive_data for both drives */
 	compute_pios(drive, pio);
- 	pio1 = hwif->drives[0].drive_data;
- 	pio2 = hwif->drives[1].drive_data;
+	pio1 = hwif->drives[0].drive_data;
+	pio2 = hwif->drives[1].drive_data;
 
 	compute_clocks(pio1, &first);
 	compute_clocks(pio2, &second);
@@ -275,7 +280,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
 	spin_lock_irqsave(&opti621_lock, flags);
 
-     	reg_base = hwif->io_ports[IDE_DATA_OFFSET];
+	reg_base = hwif->io_ports[IDE_DATA_OFFSET];
 
 	/* allow Register-B */
 	outb(0xc0, reg_base + CNTRL_REG);
@@ -324,7 +329,7 @@ static void __devinit opti621_port_init_devs(ide_hwif_t *hwif)
 /*
  * init_hwif_opti621() is called once for each hwif found at boot.
  */
-static void __devinit init_hwif_opti621 (ide_hwif_t *hwif)
+static void __devinit init_hwif_opti621(ide_hwif_t *hwif)
 {
 	hwif->port_init_devs = opti621_port_init_devs;
 	hwif->set_pio_mode = &opti621_set_pio_mode;
@@ -334,18 +339,16 @@ static const struct ide_port_info opti621_chipsets[] __devinitdata = {
 	{	/* 0 */
 		.name		= "OPTI621",
 		.init_hwif	= init_hwif_opti621,
-		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
-				  IDE_HFLAG_BOOTABLE,
+		.enablebits	= { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} },
+		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
 		.pio_mask	= ATA_PIO3,
 		.swdma_mask	= ATA_SWDMA2,
 		.mwdma_mask	= ATA_MWDMA2,
-	},{	/* 1 */
+	}, {	/* 1 */
 		.name		= "OPTI621X",
 		.init_hwif	= init_hwif_opti621,
-		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
-				  IDE_HFLAG_BOOTABLE,
+		.enablebits	= { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} },
+		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
 		.pio_mask	= ATA_PIO3,
 		.swdma_mask	= ATA_SWDMA2,
 		.mwdma_mask	= ATA_MWDMA2,
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index decef0f..89d74ff 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -307,9 +307,9 @@ static void __devinit init_hwif_ich(ide_hwif_t *hwif)
 }
 
 #ifndef CONFIG_IA64
- #define IDE_HFLAGS_PIIX (IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE)
+ #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS
 #else
- #define IDE_HFLAGS_PIIX IDE_HFLAG_BOOTABLE
+ #define IDE_HFLAGS_PIIX 0
 #endif
 
 #define DECLARE_PIIX_DEV(name_str, udma) \
diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c
index 5167661..532154a 100644
--- a/drivers/ide/pci/rz1000.c
+++ b/drivers/ide/pci/rz1000.c
@@ -43,7 +43,7 @@ static const struct ide_port_info rz1000_chipset __devinitdata = {
 	.name		= "RZ100x",
 	.init_hwif	= init_hwif_rz1000,
 	.chipset	= ide_rz1000,
-	.host_flags	= IDE_HFLAG_NO_DMA | IDE_HFLAG_BOOTABLE,
+	.host_flags	= IDE_HFLAG_NO_DMA,
 };
 
 static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 561aa47..44985c8 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -307,8 +307,7 @@ static const struct ide_port_info sc1200_chipset __devinitdata = {
 	.init_hwif	= init_hwif_sc1200,
 	.host_flags	= IDE_HFLAG_SERIALIZE |
 			  IDE_HFLAG_POST_SET_MODE |
-			  IDE_HFLAG_ABUSE_DMA_MODES |
-			  IDE_HFLAG_BOOTABLE,
+			  IDE_HFLAG_ABUSE_DMA_MODES,
 	.pio_mask	= ATA_PIO4,
 	.mwdma_mask	= ATA_MWDMA2,
 	.udma_mask	= ATA_UDMA2,
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index ef07c7a..5214579 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -65,7 +65,7 @@
 
 static struct scc_ports {
 	unsigned long ctl, dma;
-	unsigned char hwif_id;  /* for removing hwif from system */
+	ide_hwif_t *hwif;  /* for removing port from system */
 } scc_ports[MAX_HWIFS];
 
 /* PIO transfer mode  table */
@@ -534,12 +534,8 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	int i;
 
-	for (i = 0; i < MAX_HWIFS; i++) {
-		hwif = &ide_hwifs[i];
-		if (hwif->chipset == ide_unknown)
-			break; /* pick an unused entry */
-	}
-	if (i == MAX_HWIFS) {
+	hwif = ide_find_port();
+	if (hwif == NULL) {
 		printk(KERN_ERR "%s: too many IDE interfaces, "
 				"no room in table\n", SCC_PATA_NAME);
 		return -ENOMEM;
@@ -696,7 +692,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
 {
 	struct scc_ports *ports = ide_get_hwifdata(hwif);
 
-	ports->hwif_id = hwif->index;
+	ports->hwif = hwif;
 
 	hwif->dma_command = hwif->dma_base;
 	hwif->dma_status = hwif->dma_base + 0x04;
@@ -725,8 +721,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
       .name		= name_str,			\
       .init_iops	= init_iops_scc,		\
       .init_hwif	= init_hwif_scc,		\
-      .host_flags	= IDE_HFLAG_SINGLE |		\
-			  IDE_HFLAG_BOOTABLE,		\
+      .host_flags	= IDE_HFLAG_SINGLE,		\
       .pio_mask		= ATA_PIO4,			\
   }
 
@@ -758,7 +753,7 @@ static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_i
 static void __devexit scc_remove(struct pci_dev *dev)
 {
 	struct scc_ports *ports = pci_get_drvdata(dev);
-	ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id];
+	ide_hwif_t *hwif = ports->hwif;
 	unsigned long ctl_base = pci_resource_start(dev, 0);
 	unsigned long dma_base = pci_resource_start(dev, 1);
 	unsigned long ctl_size = pci_resource_len(dev, 0);
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index c11880b..cfe9274 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -350,8 +350,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
 
 #define IDE_HFLAGS_SVWKS \
 	(IDE_HFLAG_LEGACY_IRQS | \
-	 IDE_HFLAG_ABUSE_SET_DMA_MODE | \
-	 IDE_HFLAG_BOOTABLE)
+	 IDE_HFLAG_ABUSE_SET_DMA_MODE)
 
 static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
 	{	/* 0 */
@@ -418,7 +417,7 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device
 	else if (idx == 2 || idx == 3) {
 		if ((PCI_FUNC(dev->devfn) & 1) == 0) {
 			if (pci_resource_start(dev, 0) != 0x01f1)
-				d.host_flags &= ~IDE_HFLAG_BOOTABLE;
+				d.host_flags |= IDE_HFLAG_NON_BOOTABLE;
 			d.host_flags |= IDE_HFLAG_SINGLE;
 		} else
 			d.host_flags &= ~IDE_HFLAG_SINGLE;
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 9d1a303..6bd9523 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -590,20 +590,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 	unsigned long bar0, cmd_phys_base, ctl;
 	void __iomem *virt_base;
 	ide_hwif_t *hwif;
-	int h;
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	hw_regs_t hw;
 	struct ide_port_info d = sgiioc4_port_info;
 
-	/*
-	 * Find an empty HWIF; if none available, return -ENOMEM.
-	 */
-	for (h = 0; h < MAX_HWIFS; ++h) {
-		hwif = &ide_hwifs[h];
-		if (hwif->chipset == ide_unknown)
-			break;
-	}
-	if (h == MAX_HWIFS) {
+	hwif = ide_find_port();
+	if (hwif == NULL) {
 		printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n",
 				DRV_NAME);
 		return -ENOMEM;
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index b6be1b4..c9ecab8 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -808,7 +808,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
 		.init_chipset	= init_chipset_siimage,	\
 		.init_iops	= init_iops_siimage,	\
 		.init_hwif	= init_hwif_siimage,	\
-		.host_flags	= IDE_HFLAG_BOOTABLE,	\
 		.pio_mask	= ATA_PIO4,		\
 		.mwdma_mask	= ATA_MWDMA2,		\
 		.udma_mask	= ATA_UDMA6,		\
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 512bb4c..181b647 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -59,10 +59,10 @@
 #define ATA_16		0x01
 #define ATA_33		0x02
 #define ATA_66		0x03
-#define ATA_100a	0x04 // SiS730/SiS550 is ATA100 with ATA66 layout
+#define ATA_100a	0x04 /* SiS730/SiS550 is ATA100 with ATA66 layout */
 #define ATA_100		0x05
-#define ATA_133a	0x06 // SiS961b with 133 support
-#define ATA_133		0x07 // SiS962/963
+#define ATA_133a	0x06 /* SiS961b with 133 support */
+#define ATA_133		0x07 /* SiS962/963 */
 
 static u8 chipset_family;
 
@@ -111,69 +111,70 @@ static const struct {
    Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */
 
 /* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */
-static u8 cycle_time_offset[] = {0,0,5,4,4,0,0};
-static u8 cycle_time_range[] = {0,0,2,3,3,4,4};
+static u8 cycle_time_offset[] = { 0, 0, 5, 4, 4, 0, 0 };
+static u8 cycle_time_range[]  = { 0, 0, 2, 3, 3, 4, 4 };
 static u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = {
-	{0,0,0,0,0,0,0}, /* no udma */
-	{0,0,0,0,0,0,0}, /* no udma */
-	{3,2,1,0,0,0,0}, /* ATA_33 */
-	{7,5,3,2,1,0,0}, /* ATA_66 */
-	{7,5,3,2,1,0,0}, /* ATA_100a (730 specific), differences are on cycle_time range and offset */
-	{11,7,5,4,2,1,0}, /* ATA_100 */
-	{15,10,7,5,3,2,1}, /* ATA_133a (earliest 691 southbridges) */
-	{15,10,7,5,3,2,1}, /* ATA_133 */
+	{  0,  0, 0, 0, 0, 0, 0 }, /* no UDMA */
+	{  0,  0, 0, 0, 0, 0, 0 }, /* no UDMA */
+	{  3,  2, 1, 0, 0, 0, 0 }, /* ATA_33 */
+	{  7,  5, 3, 2, 1, 0, 0 }, /* ATA_66 */
+	{  7,  5, 3, 2, 1, 0, 0 }, /* ATA_100a (730 specific),
+				      different cycle_time range and offset */
+	{ 11,  7, 5, 4, 2, 1, 0 }, /* ATA_100 */
+	{ 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133a (earliest 691 southbridges) */
+	{ 15, 10, 7, 5, 3, 2, 1 }, /* ATA_133 */
 };
 /* CRC Valid Setup Time vary across IDE clock setting 33/66/100/133
    See SiS962 data sheet for more detail */
 static u8 cvs_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = {
-	{0,0,0,0,0,0,0}, /* no udma */
-	{0,0,0,0,0,0,0}, /* no udma */
-	{2,1,1,0,0,0,0},
-	{4,3,2,1,0,0,0},
-	{4,3,2,1,0,0,0},
-	{6,4,3,1,1,1,0},
-	{9,6,4,2,2,2,2},
-	{9,6,4,2,2,2,2},
+	{ 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */
+	{ 0, 0, 0, 0, 0, 0, 0 }, /* no UDMA */
+	{ 2, 1, 1, 0, 0, 0, 0 },
+	{ 4, 3, 2, 1, 0, 0, 0 },
+	{ 4, 3, 2, 1, 0, 0, 0 },
+	{ 6, 4, 3, 1, 1, 1, 0 },
+	{ 9, 6, 4, 2, 2, 2, 2 },
+	{ 9, 6, 4, 2, 2, 2, 2 },
 };
 /* Initialize time, Active time, Recovery time vary across
    IDE clock settings. These 3 arrays hold the register value
    for PIO0/1/2/3/4 and DMA0/1/2 mode in order */
 static u8 ini_time_value[][8] = {
-	{0,0,0,0,0,0,0,0},
-	{0,0,0,0,0,0,0,0},
-	{2,1,0,0,0,1,0,0},
-	{4,3,1,1,1,3,1,1},
-	{4,3,1,1,1,3,1,1},
-	{6,4,2,2,2,4,2,2},
-	{9,6,3,3,3,6,3,3},
-	{9,6,3,3,3,6,3,3},
+	{ 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 2, 1, 0, 0, 0, 1, 0, 0 },
+	{ 4, 3, 1, 1, 1, 3, 1, 1 },
+	{ 4, 3, 1, 1, 1, 3, 1, 1 },
+	{ 6, 4, 2, 2, 2, 4, 2, 2 },
+	{ 9, 6, 3, 3, 3, 6, 3, 3 },
+	{ 9, 6, 3, 3, 3, 6, 3, 3 },
 };
 static u8 act_time_value[][8] = {
-	{0,0,0,0,0,0,0,0},
-	{0,0,0,0,0,0,0,0},
-	{9,9,9,2,2,7,2,2},
-	{19,19,19,5,4,14,5,4},
-	{19,19,19,5,4,14,5,4},
-	{28,28,28,7,6,21,7,6},
-	{38,38,38,10,9,28,10,9},
-	{38,38,38,10,9,28,10,9},
+	{  0,  0,  0,  0, 0,  0,  0, 0 },
+	{  0,  0,  0,  0, 0,  0,  0, 0 },
+	{  9,  9,  9,  2, 2,  7,  2, 2 },
+	{ 19, 19, 19,  5, 4, 14,  5, 4 },
+	{ 19, 19, 19,  5, 4, 14,  5, 4 },
+	{ 28, 28, 28,  7, 6, 21,  7, 6 },
+	{ 38, 38, 38, 10, 9, 28, 10, 9 },
+	{ 38, 38, 38, 10, 9, 28, 10, 9 },
 };
 static u8 rco_time_value[][8] = {
-	{0,0,0,0,0,0,0,0},
-	{0,0,0,0,0,0,0,0},
-	{9,2,0,2,0,7,1,1},
-	{19,5,1,5,2,16,3,2},
-	{19,5,1,5,2,16,3,2},
-	{30,9,3,9,4,25,6,4},
-	{40,12,4,12,5,34,12,5},
-	{40,12,4,12,5,34,12,5},
+	{  0,  0, 0,  0, 0,  0,  0, 0 },
+	{  0,  0, 0,  0, 0,  0,  0, 0 },
+	{  9,  2, 0,  2, 0,  7,  1, 1 },
+	{ 19,  5, 1,  5, 2, 16,  3, 2 },
+	{ 19,  5, 1,  5, 2, 16,  3, 2 },
+	{ 30,  9, 3,  9, 4, 25,  6, 4 },
+	{ 40, 12, 4, 12, 5, 34, 12, 5 },
+	{ 40, 12, 4, 12, 5, 34, 12, 5 },
 };
 
 /*
  * Printing configuration
  */
 /* Used for chipset type printing at boot time */
-static char* chipset_capability[] = {
+static char *chipset_capability[] = {
 	"ATA", "ATA 16",
 	"ATA 33", "ATA 66",
 	"ATA 100 (1st gen)", "ATA 100 (2nd gen)",
@@ -272,7 +273,7 @@ static void sis_program_timings(ide_drive_t *drive, const u8 mode)
 		sis_ata133_program_timings(drive, mode);
 }
 
-static void config_drive_art_rwp (ide_drive_t *drive)
+static void config_drive_art_rwp(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
@@ -358,8 +359,7 @@ static u8 sis5513_ata133_udma_filter(ide_drive_t *drive)
 	return (regdw & 0x08) ? ATA_UDMA6 : ATA_UDMA5;
 }
 
-/* Chip detection and general config */
-static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name)
+static int __devinit sis_find_family(struct pci_dev *dev)
 {
 	struct pci_dev *host;
 	int i = 0;
@@ -381,7 +381,7 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
 				chipset_family = ATA_100a;
 		}
 		pci_dev_put(host);
-	
+
 		printk(KERN_INFO "SIS5513: %s %s controller\n",
 			 SiSHostChipInfo[i].name, chipset_capability[chipset_family]);
 	}
@@ -440,63 +440,60 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
 			}
 	}
 
-	if (!chipset_family)
-		return -1;
+	return chipset_family;
+}
 
+static unsigned int __devinit init_chipset_sis5513(struct pci_dev *dev,
+						   const char *name)
+{
 	/* Make general config ops here
 	   1/ tell IDE channels to operate in Compatibility mode only
 	   2/ tell old chips to allow per drive IDE timings */
 
-	{
-		u8 reg;
-		u16 regw;
-
-		switch(chipset_family) {
-			case ATA_133:
-				/* SiS962 operation mode */
-				pci_read_config_word(dev, 0x50, &regw);
-				if (regw & 0x08)
-					pci_write_config_word(dev, 0x50, regw&0xfff7);
-				pci_read_config_word(dev, 0x52, &regw);
-				if (regw & 0x08)
-					pci_write_config_word(dev, 0x52, regw&0xfff7);
-				break;
-			case ATA_133a:
-			case ATA_100:
-				/* Fixup latency */
-				pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
-				/* Set compatibility bit */
-				pci_read_config_byte(dev, 0x49, &reg);
-				if (!(reg & 0x01)) {
-					pci_write_config_byte(dev, 0x49, reg|0x01);
-				}
-				break;
-			case ATA_100a:
-			case ATA_66:
-				/* Fixup latency */
-				pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10);
-
-				/* On ATA_66 chips the bit was elsewhere */
-				pci_read_config_byte(dev, 0x52, &reg);
-				if (!(reg & 0x04)) {
-					pci_write_config_byte(dev, 0x52, reg|0x04);
-				}
-				break;
-			case ATA_33:
-				/* On ATA_33 we didn't have a single bit to set */
-				pci_read_config_byte(dev, 0x09, &reg);
-				if ((reg & 0x0f) != 0x00) {
-					pci_write_config_byte(dev, 0x09, reg&0xf0);
-				}
-			case ATA_16:
-				/* force per drive recovery and active timings
-				   needed on ATA_33 and below chips */
-				pci_read_config_byte(dev, 0x52, &reg);
-				if (!(reg & 0x08)) {
-					pci_write_config_byte(dev, 0x52, reg|0x08);
-				}
-				break;
-		}
+	u8 reg;
+	u16 regw;
+
+	switch (chipset_family) {
+	case ATA_133:
+		/* SiS962 operation mode */
+		pci_read_config_word(dev, 0x50, &regw);
+		if (regw & 0x08)
+			pci_write_config_word(dev, 0x50, regw&0xfff7);
+		pci_read_config_word(dev, 0x52, &regw);
+		if (regw & 0x08)
+			pci_write_config_word(dev, 0x52, regw&0xfff7);
+		break;
+	case ATA_133a:
+	case ATA_100:
+		/* Fixup latency */
+		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
+		/* Set compatibility bit */
+		pci_read_config_byte(dev, 0x49, &reg);
+		if (!(reg & 0x01))
+			pci_write_config_byte(dev, 0x49, reg|0x01);
+		break;
+	case ATA_100a:
+	case ATA_66:
+		/* Fixup latency */
+		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10);
+
+		/* On ATA_66 chips the bit was elsewhere */
+		pci_read_config_byte(dev, 0x52, &reg);
+		if (!(reg & 0x04))
+			pci_write_config_byte(dev, 0x52, reg|0x04);
+		break;
+	case ATA_33:
+		/* On ATA_33 we didn't have a single bit to set */
+		pci_read_config_byte(dev, 0x09, &reg);
+		if ((reg & 0x0f) != 0x00)
+			pci_write_config_byte(dev, 0x09, reg&0xf0);
+	case ATA_16:
+		/* force per drive recovery and active timings
+		   needed on ATA_33 and below chips */
+		pci_read_config_byte(dev, 0x52, &reg);
+		if (!(reg & 0x08))
+			pci_write_config_byte(dev, 0x52, reg|0x08);
+		break;
 	}
 
 	return 0;
@@ -546,10 +543,8 @@ static u8 __devinit ata66_sis5513(ide_hwif_t *hwif)
 	return ata66 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
 }
 
-static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
+static void __devinit init_hwif_sis5513(ide_hwif_t *hwif)
 {
-	u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
-
 	hwif->set_pio_mode = &sis_set_pio_mode;
 	hwif->set_dma_mode = &sis_set_dma_mode;
 
@@ -557,27 +552,29 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
 		hwif->udma_filter = sis5513_ata133_udma_filter;
 
 	hwif->cable_detect = ata66_sis5513;
-
-	if (hwif->dma_base == 0)
-		return;
-
-	hwif->ultra_mask = udma_rates[chipset_family];
 }
 
 static const struct ide_port_info sis5513_chipset __devinitdata = {
 	.name		= "SIS5513",
 	.init_chipset	= init_chipset_sis5513,
 	.init_hwif	= init_hwif_sis5513,
-	.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-	.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA |
-			  IDE_HFLAG_BOOTABLE,
+	.enablebits	= { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} },
+	.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA,
 	.pio_mask	= ATA_PIO4,
 	.mwdma_mask	= ATA_MWDMA2,
 };
 
 static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	return ide_setup_pci_device(dev, &sis5513_chipset);
+	struct ide_port_info d = sis5513_chipset;
+	u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
+
+	if (sis_find_family(dev) == 0)
+		return -ENOTSUPP;
+
+	d.udma_mask = udma_rates[chipset_family];
+
+	return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id sis5513_pci_tbl[] = {
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 1f00251..40b3eeb 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -332,8 +332,7 @@ static const struct ide_port_info sl82c105_chipset __devinitdata = {
 #if defined(CONFIG_LOPEC) || defined(CONFIG_SANDPOINT)
 			  IDE_HFLAG_FORCE_LEGACY_IRQS |
 #endif
-			  IDE_HFLAG_NO_AUTODMA |
-			  IDE_HFLAG_BOOTABLE,
+			  IDE_HFLAG_NO_AUTODMA,
 	.pio_mask	= ATA_PIO5,
 };
 
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index 65f4c2f..eab557c 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -27,9 +27,9 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	unsigned long flags;
 	u16 master_data;
 	u8 slave_data;
- 	int control = 0;
+	int control = 0;
 				     /* ISP  RTC */
-	static const u8 timings[][2]= {
+	static const u8 timings[][2] = {
 					{ 0, 0 },
 					{ 0, 0 },
 					{ 1, 0 },
@@ -136,8 +136,8 @@ static void __devinit init_hwif_slc90e66(ide_hwif_t *hwif)
 static const struct ide_port_info slc90e66_chipset __devinitdata = {
 	.name		= "SLC90E66",
 	.init_hwif	= init_hwif_slc90e66,
-	.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
-	.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
+	.enablebits	= { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} },
+	.host_flags	= IDE_HFLAG_LEGACY_IRQS,
 	.pio_mask	= ATA_PIO4,
 	.swdma_mask	= ATA_SWDMA2_ONLY,
 	.mwdma_mask	= ATA_MWDMA12_ONLY,
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index 1e4a626..c154351 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -18,20 +18,20 @@ static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
 	u16 mode, scr		= inw(scr_port);
 
 	switch (speed) {
-		case XFER_UDMA_4:	mode = 0x00c0; break;
-		case XFER_UDMA_3:	mode = 0x00b0; break;
-		case XFER_UDMA_2:	mode = 0x00a0; break;
-		case XFER_UDMA_1:	mode = 0x0090; break;
-		case XFER_UDMA_0:	mode = 0x0080; break;
-		case XFER_MW_DMA_2:	mode = 0x0070; break;
-		case XFER_MW_DMA_1:	mode = 0x0060; break;
-		case XFER_MW_DMA_0:	mode = 0x0050; break;
-		case XFER_PIO_4:	mode = 0x0400; break;
-		case XFER_PIO_3:	mode = 0x0300; break;
-		case XFER_PIO_2:	mode = 0x0200; break;
-		case XFER_PIO_1:	mode = 0x0100; break;
-		case XFER_PIO_0:
-		default:		mode = 0x0000; break;
+	case XFER_UDMA_4:	mode = 0x00c0; break;
+	case XFER_UDMA_3:	mode = 0x00b0; break;
+	case XFER_UDMA_2:	mode = 0x00a0; break;
+	case XFER_UDMA_1:	mode = 0x0090; break;
+	case XFER_UDMA_0:	mode = 0x0080; break;
+	case XFER_MW_DMA_2:	mode = 0x0070; break;
+	case XFER_MW_DMA_1:	mode = 0x0060; break;
+	case XFER_MW_DMA_0:	mode = 0x0050; break;
+	case XFER_PIO_4:	mode = 0x0400; break;
+	case XFER_PIO_3:	mode = 0x0300; break;
+	case XFER_PIO_2:	mode = 0x0200; break;
+	case XFER_PIO_1:	mode = 0x0100; break;
+	case XFER_PIO_0:
+	default:		mode = 0x0000; break;
 	}
 
 	scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index a67d02a..3316b19 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -97,7 +97,6 @@ static const struct ide_port_info triflex_device __devinitdata = {
 	.name		= "TRIFLEX",
 	.init_hwif	= init_hwif_triflex,
 	.enablebits	= {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
-	.host_flags	= IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO4,
 	.swdma_mask	= ATA_SWDMA2,
 	.mwdma_mask	= ATA_MWDMA2,
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index de750f7..2b8f3a2 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -337,7 +337,6 @@ static const struct ide_port_info trm290_chipset __devinitdata = {
 			  IDE_HFLAG_TRUST_BIOS_FOR_DMA |
 #endif
 			  IDE_HFLAG_NO_AUTODMA |
-			  IDE_HFLAG_BOOTABLE |
 			  IDE_HFLAG_NO_LBA48,
 };
 
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 9004e75..cff3caf 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -429,11 +429,9 @@ static const struct ide_port_info via82cxxx_chipset __devinitdata = {
 	.init_hwif	= init_hwif_via82cxxx,
 	.enablebits	= { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
 	.host_flags	= IDE_HFLAG_PIO_NO_BLACKLIST |
-			  IDE_HFLAG_PIO_NO_DOWNGRADE |
 			  IDE_HFLAG_ABUSE_SET_DMA_MODE |
 			  IDE_HFLAG_POST_SET_MODE |
-			  IDE_HFLAG_IO_32BIT |
-			  IDE_HFLAG_BOOTABLE,
+			  IDE_HFLAG_IO_32BIT,
 	.pio_mask	= ATA_PIO5,
 	.swdma_mask	= ATA_SWDMA2,
 	.mwdma_mask	= ATA_MWDMA2,
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
index a784a97..467656f 100644
--- a/drivers/ide/ppc/mpc8xx.c
+++ b/drivers/ide/ppc/mpc8xx.c
@@ -36,6 +36,8 @@
 #include <asm/machdep.h>
 #include <asm/irq.h>
 
+#define DRV_NAME "ide-mpc8xx"
+
 static int identify  (volatile u8 *p);
 static void print_fixed (volatile u8 *p);
 static void print_funcid (int func);
@@ -127,7 +129,7 @@ static int pcmcia_schlvl = PCMCIA_SCHLVL;
  * MPC8xx's internal PCMCIA interface
  */
 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
-static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
+static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 {
 	unsigned long *p = hw->io_ports;
 	int i;
@@ -182,6 +184,13 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 			pcmcia_phy_base, pcmcia_phy_end,
 			pcmcia_phy_end - pcmcia_phy_base);
 
+		if (!request_mem_region(pcmcia_phy_base,
+					pcmcia_phy_end - pcmcia_phy_base,
+					DRV_NAME)) {
+			printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+			return -EBUSY;
+		}
+
 		pcmcia_base=(unsigned long)ioremap(pcmcia_phy_base,
 						   pcmcia_phy_end-pcmcia_phy_base);
 
@@ -236,7 +245,7 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 	if (pcmp->pcmc_pipr & (M8XX_PCMCIA_CD1(_slot_)|M8XX_PCMCIA_CD2(_slot_))) {
 		printk ("No card in slot %c: PIPR=%08x\n",
 			'A' + _slot_, (u32) pcmp->pcmc_pipr);
-		return;		/* No card in slot */
+		return -ENODEV;		/* No card in slot */
 	}
 
 	check_ide_device (pcmcia_base);
@@ -279,9 +288,6 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 	}
 #endif	/* CONFIG_IDE_8xx_PCCARD */
 
-	ide_hwifs[data_port].pio_mask = ATA_PIO4;
-	ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
-
 	/* Enable Harddisk Interrupt,
 	 * and make it edge sensitive
 	 */
@@ -296,6 +302,8 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 	/* Enable falling edge irq */
 	pcmp->pcmc_per = 0x100000 >> (16 * _slot_);
 #endif	/* CONFIG_IDE_8xx_PCCARD */
+
+	return 0;
 }
 #endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */
 
@@ -304,7 +312,7 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
  * MPC8xx's internal PCMCIA interface
  */
 #if defined(CONFIG_IDE_EXT_DIRECT)
-static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
+static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 {
 	unsigned long *p = hw->io_ports;
 	int i;
@@ -327,7 +335,12 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 		printk ("IDE phys mem : %08x...%08x (size %08x)\n",
 			ide_phy_base, ide_phy_end,
 			ide_phy_end - ide_phy_base);
-		
+
+		if (!request_mem_region(ide_phy_base, 0x200, DRV_NAME)) {
+			printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
+			return -EBUSY;
+		}
+
 		ide_base=(unsigned long)ioremap(ide_phy_base,
 						ide_phy_end-ide_phy_base);
 
@@ -357,15 +370,14 @@ static void __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
 	hw->irq = ioport_dsc[data_port].irq;
 	hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
 
-	ide_hwifs[data_port].pio_mask = ATA_PIO4;
-	ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
-
 	/* Enable Harddisk Interrupt,
 	 * and make it edge sensitive
 	 */
 	/* (11-18) Set edge detect for irq, no wakeup from low power mode */
 	((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |=
 			(0x80000000 >> ioport_dsc[data_port].irq);
+
+	return 0;
 }
 #endif	/* CONFIG_IDE_8xx_DIRECT */
 
@@ -794,14 +806,28 @@ static int __init mpc8xx_ide_probe(void)
 
 #ifdef IDE0_BASE_OFFSET
 	memset(&hw, 0, sizeof(hw));
-	m8xx_ide_init_ports(&hw, 0);
-	ide_init_port_hw(&ide_hwifs[0], &hw);
-	idx[0] = 0;
+	if (!m8xx_ide_init_ports(&hw, 0)) {
+		ide_hwif_t *hwif = &ide_hwifs[0];
+
+		ide_init_port_hw(hwif, &hw);
+		hwif->mmio = 1;
+		hwif->pio_mask = ATA_PIO4;
+		hwif->set_pio_mode = m8xx_ide_set_pio_mode;
+
+		idx[0] = 0;
+	}
 #ifdef IDE1_BASE_OFFSET
 	memset(&hw, 0, sizeof(hw));
-	m8xx_ide_init_ports(&hw, 1);
-	ide_init_port_hw(&ide_hwifs[1], &hw);
-	idx[1] = 1;
+	if (!m8xx_ide_init_ports(&hw, 1)) {
+		ide_hwif_t *mate = &ide_hwifs[1];
+
+		ide_init_port_hw(mate, &hw);
+		mate->mmio = 1;
+		mate->pio_mask = ATA_PIO4;
+		mate->set_pio_mode = m8xx_ide_set_pio_mode;
+
+		idx[1] = 1;
+	}
 #endif
 #endif
 
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 88619b5..177961e 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -79,8 +79,6 @@ typedef struct pmac_ide_hwif {
 	
 } pmac_ide_hwif_t;
 
-static pmac_ide_hwif_t pmac_ide[MAX_HWIFS];
-
 enum {
 	controller_ohare,	/* OHare based */
 	controller_heathrow,	/* Heathrow/Paddington */
@@ -923,7 +921,6 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
 static const struct ide_port_info pmac_port_info = {
 	.chipset		= ide_pmac,
 	.host_flags		= IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
-				  IDE_HFLAG_PIO_NO_DOWNGRADE |
 				  IDE_HFLAG_POST_SET_MODE |
 				  IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
 				  IDE_HFLAG_UNMASK_IRQS,
@@ -1088,35 +1085,36 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	void __iomem *base;
 	unsigned long regbase;
-	int irq;
 	ide_hwif_t *hwif;
 	pmac_ide_hwif_t *pmif;
-	int i, rc;
+	int irq, rc;
 	hw_regs_t hw;
 
-	i = 0;
-	while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0
-	    || pmac_ide[i].node != NULL))
-		++i;
-	if (i >= MAX_HWIFS) {
+	pmif = kzalloc(sizeof(*pmif), GFP_KERNEL);
+	if (pmif == NULL)
+		return -ENOMEM;
+
+	hwif = ide_find_port();
+	if (hwif == NULL) {
 		printk(KERN_ERR "ide-pmac: MacIO interface attach with no slot\n");
 		printk(KERN_ERR "          %s\n", mdev->ofdev.node->full_name);
-		return -ENODEV;
+		rc = -ENODEV;
+		goto out_free_pmif;
 	}
 
-	pmif = &pmac_ide[i];
-	hwif = &ide_hwifs[i];
-
 	if (macio_resource_count(mdev) == 0) {
-		printk(KERN_WARNING "ide%d: no address for %s\n",
-		       i, mdev->ofdev.node->full_name);
-		return -ENXIO;
+		printk(KERN_WARNING "ide-pmac: no address for %s\n",
+				    mdev->ofdev.node->full_name);
+		rc = -ENXIO;
+		goto out_free_pmif;
 	}
 
 	/* Request memory resource for IO ports */
 	if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) {
-		printk(KERN_ERR "ide%d: can't request mmio resource !\n", i);
-		return -EBUSY;
+		printk(KERN_ERR "ide-pmac: can't request MMIO resource for "
+				"%s!\n", mdev->ofdev.node->full_name);
+		rc = -EBUSY;
+		goto out_free_pmif;
 	}
 			
 	/* XXX This is bogus. Should be fixed in the registry by checking
@@ -1125,8 +1123,8 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	 * where that happens though...
 	 */
 	if (macio_irq_count(mdev) == 0) {
-		printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n",
-			i, mdev->ofdev.node->full_name);
+		printk(KERN_WARNING "ide-pmac: no intrs for device %s, using "
+				    "13\n", mdev->ofdev.node->full_name);
 		irq = irq_create_mapping(NULL, 13);
 	} else
 		irq = macio_irq(mdev, 0);
@@ -1144,7 +1142,9 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 	if (macio_resource_count(mdev) >= 2) {
 		if (macio_request_resource(mdev, 1, "ide-pmac (dma)"))
-			printk(KERN_WARNING "ide%d: can't request DMA resource !\n", i);
+			printk(KERN_WARNING "ide-pmac: can't request DMA "
+					    "resource for %s!\n",
+					    mdev->ofdev.node->full_name);
 		else
 			pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000);
 	} else
@@ -1166,11 +1166,15 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 			iounmap(pmif->dma_regs);
 			macio_release_resource(mdev, 1);
 		}
-		memset(pmif, 0, sizeof(*pmif));
 		macio_release_resource(mdev, 0);
+		kfree(pmif);
 	}
 
 	return rc;
+
+out_free_pmif:
+	kfree(pmif);
+	return rc;
 }
 
 static int
@@ -1215,7 +1219,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 	pmac_ide_hwif_t *pmif;
 	void __iomem *base;
 	unsigned long rbase, rlen;
-	int i, rc;
+	int rc;
 	hw_regs_t hw;
 
 	np = pci_device_to_OF_node(pdev);
@@ -1223,30 +1227,32 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 		printk(KERN_ERR "ide-pmac: cannot find MacIO node for Kauai ATA interface\n");
 		return -ENODEV;
 	}
-	i = 0;
-	while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0
-	    || pmac_ide[i].node != NULL))
-		++i;
-	if (i >= MAX_HWIFS) {
+
+	pmif = kzalloc(sizeof(*pmif), GFP_KERNEL);
+	if (pmif == NULL)
+		return -ENOMEM;
+
+	hwif = ide_find_port();
+	if (hwif == NULL) {
 		printk(KERN_ERR "ide-pmac: PCI interface attach with no slot\n");
 		printk(KERN_ERR "          %s\n", np->full_name);
-		return -ENODEV;
+		rc = -ENODEV;
+		goto out_free_pmif;
 	}
 
-	pmif = &pmac_ide[i];
-	hwif = &ide_hwifs[i];
-
 	if (pci_enable_device(pdev)) {
-		printk(KERN_WARNING "ide%i: Can't enable PCI device for %s\n",
-			i, np->full_name);
-		return -ENXIO;
+		printk(KERN_WARNING "ide-pmac: Can't enable PCI device for "
+				    "%s\n", np->full_name);
+		rc = -ENXIO;
+		goto out_free_pmif;
 	}
 	pci_set_master(pdev);
 			
 	if (pci_request_regions(pdev, "Kauai ATA")) {
-		printk(KERN_ERR "ide%d: Cannot obtain PCI resources for %s\n",
-			i, np->full_name);
-		return -ENXIO;
+		printk(KERN_ERR "ide-pmac: Cannot obtain PCI resources for "
+				"%s\n", np->full_name);
+		rc = -ENXIO;
+		goto out_free_pmif;
 	}
 
 	hwif->dev = &pdev->dev;
@@ -1276,11 +1282,15 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 		/* The inteface is released to the common IDE layer */
 		pci_set_drvdata(pdev, NULL);
 		iounmap(base);
-		memset(pmif, 0, sizeof(*pmif));
 		pci_release_regions(pdev);
+		kfree(pmif);
 	}
 
 	return rc;
+
+out_free_pmif:
+	kfree(pmif);
+	return rc;
 }
 
 static int
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index f7ede0e..6302010 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -20,73 +20,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-
-/**
- *	ide_match_hwif	-	match a PCI IDE against an ide_hwif
- *	@io_base: I/O base of device
- *	@bootable: set if its bootable
- *	@name: name of device
- *
- *	Match a PCI IDE port against an entry in ide_hwifs[],
- *	based on io_base port if possible. Return the matching hwif,
- *	or a new hwif. If we find an error (clashing, out of devices, etc)
- *	return NULL
- *
- *	FIXME: we need to handle mmio matches here too
- */
-
-static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char *name)
-{
-	int h;
-	ide_hwif_t *hwif;
-
-	/*
-	 * Look for a hwif with matching io_base default value.
-	 * If chipset is "ide_unknown", then claim that hwif slot.
-	 * Otherwise, some other chipset has already claimed it..  :(
-	 */
-	for (h = 0; h < MAX_HWIFS; ++h) {
-		hwif = &ide_hwifs[h];
-		if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) {
-			if (hwif->chipset == ide_unknown)
-				return hwif; /* match */
-			printk(KERN_ERR "%s: port 0x%04lx already claimed by %s\n",
-				name, io_base, hwif->name);
-			return NULL;	/* already claimed */
-		}
-	}
-	/*
-	 * Okay, there is no hwif matching our io_base,
-	 * so we'll just claim an unassigned slot.
-	 * Give preference to claiming other slots before claiming ide0/ide1,
-	 * just in case there's another interface yet-to-be-scanned
-	 * which uses ports 1f0/170 (the ide0/ide1 defaults).
-	 *
-	 * Unless there is a bootable card that does not use the standard
-	 * ports 1f0/170 (the ide0/ide1 defaults). The (bootable) flag.
-	 */
-	if (bootable) {
-		for (h = 0; h < MAX_HWIFS; ++h) {
-			hwif = &ide_hwifs[h];
-			if (hwif->chipset == ide_unknown)
-				return hwif;	/* pick an unused entry */
-		}
-	} else {
-		for (h = 2; h < MAX_HWIFS; ++h) {
-			hwif = ide_hwifs + h;
-			if (hwif->chipset == ide_unknown)
-				return hwif;	/* pick an unused entry */
-		}
-	}
-	for (h = 0; h < 2 && h < MAX_HWIFS; ++h) {
-		hwif = ide_hwifs + h;
-		if (hwif->chipset == ide_unknown)
-			return hwif;	/* pick an unused entry */
-	}
-	printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", name);
-	return NULL;
-}
-
 /**
  *	ide_setup_pci_baseregs	-	place a PCI IDE controller native
  *	@dev: PCI device of interface to switch native
@@ -94,13 +27,13 @@ static ide_hwif_t *ide_match_hwif(unsigned long io_base, u8 bootable, const char
  *
  *	We attempt to place the PCI interface into PCI native mode. If
  *	we succeed the BARs are ok and the controller is in PCI mode.
- *	Returns 0 on success or an errno code. 
+ *	Returns 0 on success or an errno code.
  *
  *	FIXME: if we program the interface and then fail to set the BARS
  *	we don't switch it back to legacy mode. Do we actually care ??
  */
- 
-static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
+
+static int ide_setup_pci_baseregs(struct pci_dev *dev, const char *name)
 {
 	u8 progif = 0;
 
@@ -207,7 +140,6 @@ void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d)
 			 " PCI slot %s\n", d->name, dev->vendor, dev->device,
 			 dev->revision, pci_name(dev));
 }
-
 EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
 
 
@@ -220,7 +152,7 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
  *	but if that fails then we only need IO space. The PCI code should
  *	have setup the proper resources for us already for controllers in
  *	legacy mode.
- *	
+ *
  *	Returns zero on success or an error code
  */
 
@@ -279,8 +211,8 @@ static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d)
 	 * Maybe the user deliberately *disabled* the device,
 	 * but we'll eventually ignore it again if no drives respond.
 	 */
-	if (ide_setup_pci_baseregs(dev, d->name) || pci_write_config_word(dev, PCI_COMMAND, pcicmd|PCI_COMMAND_IO)) 
-	{
+	if (ide_setup_pci_baseregs(dev, d->name) ||
+	    pci_write_config_word(dev, PCI_COMMAND, pcicmd | PCI_COMMAND_IO)) {
 		printk(KERN_INFO "%s: device disabled (BIOS)\n", d->name);
 		return -ENODEV;
 	}
@@ -301,26 +233,24 @@ static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d)
  *	@d: IDE port info
  *	@bar: BAR number
  *
- *	Checks if a BAR is configured and points to MMIO space. If so
- *	print an error and return an error code. Otherwise return 0
+ *	Checks if a BAR is configured and points to MMIO space. If so,
+ *	return an error code. Otherwise return 0
  */
 
-static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, int bar)
+static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d,
+			       int bar)
 {
 	ulong flags = pci_resource_flags(dev, bar);
-	
+
 	/* Unconfigured ? */
 	if (!flags || pci_resource_len(dev, bar) == 0)
 		return 0;
 
-	/* I/O space */		
-	if(flags & PCI_BASE_ADDRESS_IO_MASK)
+	/* I/O space */
+	if (flags & IORESOURCE_IO)
 		return 0;
-		
+
 	/* Bad */
-	printk(KERN_ERR "%s: IO baseregs (BIOS) are reported "
-			"as MEM, report to "
-			"<andre@linux-ide.org>.\n", d->name);
 	return -EINVAL;
 }
 
@@ -344,14 +274,16 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
 {
 	unsigned long ctl = 0, base = 0;
 	ide_hwif_t *hwif;
-	u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0;
 	struct hw_regs_s hw;
 
 	if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
-		/*  Possibly we should fail if these checks report true */
-		ide_pci_check_iomem(dev, d, 2*port);
-		ide_pci_check_iomem(dev, d, 2*port+1);
- 
+		if (ide_pci_check_iomem(dev, d, 2 * port) ||
+		    ide_pci_check_iomem(dev, d, 2 * port + 1)) {
+			printk(KERN_ERR "%s: I/O baseregs (BIOS) are reported "
+					"as MEM for port %d!\n", d->name, port);
+			return NULL;
+		}
+
 		ctl  = pci_resource_start(dev, 2*port+1);
 		base = pci_resource_start(dev, 2*port);
 		if ((ctl && !base) || (base && !ctl)) {
@@ -360,14 +292,18 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
 			return NULL;
 		}
 	}
-	if (!ctl)
-	{
+	if (!ctl) {
 		/* Use default values */
 		ctl = port ? 0x374 : 0x3f4;
 		base = port ? 0x170 : 0x1f0;
 	}
-	if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL)
-		return NULL;	/* no room in ide_hwifs[] */
+
+	hwif = ide_find_port_slot(d);
+	if (hwif == NULL) {
+		printk(KERN_ERR "%s: too many IDE interfaces, no room in "
+				"table\n", d->name);
+		return NULL;
+	}
 
 	memset(&hw, 0, sizeof(hw));
 	hw.irq = irq;
@@ -407,9 +343,9 @@ void ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
 		unsigned long dma_base = ide_get_or_set_dma_base(d, hwif);
 		if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {
 			/*
- 			 * Set up BM-DMA capability
+			 * Set up BM-DMA capability
 			 * (PnP BIOS should have done this)
- 			 */
+			 */
 			pci_set_master(dev);
 			if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) {
 				printk(KERN_ERR "%s: %s error updating PCICMD\n",
@@ -514,7 +450,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
 		*(idx + port) = hwif->index;
 	}
 }
-
 EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
 
 /*
@@ -597,7 +532,6 @@ int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d)
 
 	return ret;
 }
-
 EXPORT_SYMBOL_GPL(ide_setup_pci_device);
 
 int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
@@ -621,5 +555,4 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
 out:
 	return ret;
 }
-
 EXPORT_SYMBOL_GPL(ide_setup_pci_devices);
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index cbb5ccb..bda6f04 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -210,7 +210,6 @@ unifdef-y += hayesesp.h
 unifdef-y += hdlcdrv.h
 unifdef-y += hdlc.h
 unifdef-y += hdreg.h
-unifdef-y += hdsmart.h
 unifdef-y += hid.h
 unifdef-y += hiddev.h
 unifdef-y += hidraw.h
diff --git a/include/linux/hdsmart.h b/include/linux/hdsmart.h
deleted file mode 100644
index 4f4faf9..0000000
--- a/include/linux/hdsmart.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * linux/include/linux/hdsmart.h
- *
- * Copyright (C) 1999-2000	Michael Cornwell <cornwell@acm.org>
- * Copyright (C) 2000		Andre Hedrick <andre@linux-ide.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example /usr/src/linux/COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _LINUX_HDSMART_H
-#define _LINUX_HDSMART_H
-
-#ifndef __KERNEL__
-#define OFFLINE_FULL_SCAN		0
-#define SHORT_SELF_TEST			1
-#define EXTEND_SELF_TEST		2
-#define SHORT_CAPTIVE_SELF_TEST		129
-#define EXTEND_CAPTIVE_SELF_TEST	130
-
-/* smart_attribute is the vendor specific in SFF-8035 spec */
-typedef struct ata_smart_attribute_s {
-	unsigned char			id;
-	unsigned short			status_flag;
-	unsigned char			normalized;
-	unsigned char			worse_normal;
-	unsigned char			raw[6];
-	unsigned char			reserv;
-} __attribute__ ((packed)) ata_smart_attribute_t;
-
-/* smart_values is format of the read drive Atrribute command */
-typedef struct ata_smart_values_s {
-	unsigned short			revnumber;
-	ata_smart_attribute_t		vendor_attributes [30];
-        unsigned char			offline_data_collection_status;
-        unsigned char			self_test_exec_status;
-	unsigned short			total_time_to_complete_off_line;
-	unsigned char			vendor_specific_366;
-	unsigned char			offline_data_collection_capability;
-	unsigned short			smart_capability;
-	unsigned char			errorlog_capability;
-	unsigned char			vendor_specific_371;
-	unsigned char			short_test_completion_time;
-	unsigned char			extend_test_completion_time;
-	unsigned char			reserved_374_385 [12];
-	unsigned char			vendor_specific_386_509 [125];
-	unsigned char			chksum;
-} __attribute__ ((packed)) ata_smart_values_t;
-
-/* Smart Threshold data structures */
-/* Vendor attribute of SMART Threshold */
-typedef struct ata_smart_threshold_entry_s {
-	unsigned char			id;
-	unsigned char			normalized_threshold;
-	unsigned char			reserved[10];
-} __attribute__ ((packed)) ata_smart_threshold_entry_t;
-
-/* Format of Read SMART THreshold Command */
-typedef struct ata_smart_thresholds_s {
-	unsigned short			revnumber;
-	ata_smart_threshold_entry_t	thres_entries[30];
-	unsigned char			reserved[149];
-	unsigned char			chksum;
-} __attribute__ ((packed)) ata_smart_thresholds_t;
-
-typedef struct ata_smart_errorlog_command_struct_s {
-	unsigned char			devicecontrolreg;
-	unsigned char			featuresreg;
-	unsigned char			sector_count;
-	unsigned char			sector_number;
-	unsigned char			cylinder_low;
-	unsigned char			cylinder_high;
-	unsigned char			drive_head;
-	unsigned char			commandreg;
-	unsigned int			timestamp;
-} __attribute__ ((packed)) ata_smart_errorlog_command_struct_t;
-
-typedef struct ata_smart_errorlog_error_struct_s {
-	unsigned char			error_condition;
-	unsigned char			extended_error[14];
-	unsigned char			state;
-	unsigned short			timestamp;
-} __attribute__ ((packed)) ata_smart_errorlog_error_struct_t;
-
-typedef struct ata_smart_errorlog_struct_s {
-	ata_smart_errorlog_command_struct_t	commands[6];
-	ata_smart_errorlog_error_struct_t	error_struct;
-} __attribute__ ((packed)) ata_smart_errorlog_struct_t;
-
-typedef struct ata_smart_errorlog_s {
-	unsigned char			revnumber;
-	unsigned char			error_log_pointer;
-	ata_smart_errorlog_struct_t	errorlog_struct[5];
-	unsigned short			ata_error_count;
-	unsigned short			non_fatal_count;
-	unsigned short			drive_timeout_count;
-	unsigned char			reserved[53];
-	unsigned char			chksum;
-} __attribute__ ((packed)) ata_smart_errorlog_t;
-
-typedef struct ata_smart_selftestlog_struct_s {
-	unsigned char			selftestnumber;
-	unsigned char			selfteststatus;
-	unsigned short			timestamp;
-	unsigned char			selftestfailurecheckpoint;
-	unsigned int			lbafirstfailure;
-	unsigned char			vendorspecific[15];
-} __attribute__ ((packed)) ata_smart_selftestlog_struct_t;
-
-typedef struct ata_smart_selftestlog_s {
-	unsigned short			revnumber;
-	ata_smart_selftestlog_struct_t	selftest_struct[21];
-	unsigned char			vendorspecific[2];
-	unsigned char			mostrecenttest;
-	unsigned char			resevered[2];
-	unsigned char			chksum;
-} __attribute__ ((packed)) ata_smart_selftestlog_t;
-#endif /* __KERNEL__ */
-
-#endif	/* _LINUX_HDSMART_H */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 5f3e82a..f20410d 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -170,7 +170,6 @@ typedef struct hw_regs_s {
 	struct device	*dev;
 } hw_regs_t;
 
-struct hwif_s * ide_find_port(unsigned long);
 void ide_init_port_data(struct hwif_s *, unsigned int);
 void ide_init_port_hw(struct hwif_s *, hw_regs_t *);
 
@@ -522,7 +521,6 @@ typedef struct hwif_s {
 	unsigned	reset      : 1;	/* reset after probe */
 	unsigned	sg_mapped  : 1;	/* sg_table and sg_nents are ready */
 	unsigned	mmio       : 1; /* host uses MMIO */
-	unsigned	straight8  : 1;	/* Alan's straight 8 check */
 
 	struct device		gendev;
 	struct device		*portdev;
@@ -809,6 +807,13 @@ extern	ide_hwif_t	ide_hwifs[];		/* master data repository */
 #endif
 extern int noautodma;
 
+ide_hwif_t *ide_find_port_slot(const struct ide_port_info *);
+
+static inline ide_hwif_t *ide_find_port(void)
+{
+	return ide_find_port_slot(NULL);
+}
+
 extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);
 int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
 			     int uptodate, int nr_sectors);
@@ -1027,8 +1032,8 @@ enum {
 	IDE_HFLAG_SINGLE		= (1 << 1),
 	/* don't use legacy PIO blacklist */
 	IDE_HFLAG_PIO_NO_BLACKLIST	= (1 << 2),
-	/* don't use conservative PIO "downgrade" */
-	IDE_HFLAG_PIO_NO_DOWNGRADE	= (1 << 3),
+	/* set for the second port of QD65xx */
+	IDE_HFLAG_QD_2ND_PORT		= (1 << 3),
 	/* use PIO8/9 for prefetch off/on */
 	IDE_HFLAG_ABUSE_PREFETCH	= (1 << 4),
 	/* use PIO6/7 for fast-devsel off/on */
@@ -1050,8 +1055,8 @@ enum {
 	IDE_HFLAG_VDMA			= (1 << 11),
 	/* ATAPI DMA is unsupported */
 	IDE_HFLAG_NO_ATAPI_DMA		= (1 << 12),
-	/* set if host is a "bootable" controller */
-	IDE_HFLAG_BOOTABLE		= (1 << 13),
+	/* set if host is a "non-bootable" controller */
+	IDE_HFLAG_NON_BOOTABLE		= (1 << 13),
 	/* host doesn't support DMA */
 	IDE_HFLAG_NO_DMA		= (1 << 14),
 	/* check if host is PCI IDE device before allowing DMA */
@@ -1079,8 +1084,6 @@ enum {
 	/* unmask IRQs */
 	IDE_HFLAG_UNMASK_IRQS		= (1 << 25),
 	IDE_HFLAG_ABUSE_SET_DMA_MODE	= (1 << 26),
-	/* host is CY82C693 */
-	IDE_HFLAG_CY82C693		= (1 << 27),
 	/* force host out of "simplex" mode */
 	IDE_HFLAG_CLEAR_SIMPLEX		= (1 << 28),
 	/* DSC overlap is unsupported */
@@ -1092,9 +1095,9 @@ enum {
 };
 
 #ifdef CONFIG_BLK_DEV_OFFBOARD
-# define IDE_HFLAG_OFF_BOARD	IDE_HFLAG_BOOTABLE
-#else
 # define IDE_HFLAG_OFF_BOARD	0
+#else
+# define IDE_HFLAG_OFF_BOARD	IDE_HFLAG_NON_BOOTABLE
 #endif
 
 struct ide_port_info {
diff --git a/kernel/fork.c b/kernel/fork.c
index efb618f..cb46bef 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1787,7 +1787,7 @@ bad_unshare_out:
 int unshare_files(struct files_struct **displaced)
 {
 	struct task_struct *task = current;
-	struct files_struct *copy;
+	struct files_struct *copy = NULL;
 	int error;
 
 	error = unshare_fd(CLONE_FILES, &copy);

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-04-26 16:09 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-26 19:43 [git patches] IDE updates part #2 Bartlomiej Zolnierkiewicz
2008-01-26 20:31 ` From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> (linux.* mail to news gateway) Frans Pop
2008-01-26 20:42   ` Jan Engelhardt
2008-01-26 21:08     ` Bartlomiej Zolnierkiewicz
2008-01-27 15:20       ` [PATCH] Use on-board instead of built-in in config options Frans Pop
2008-02-01 21:49         ` Bartlomiej Zolnierkiewicz
2008-04-26 16:12 [git patches] IDE updates part 2 Bartlomiej Zolnierkiewicz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).