Browse Source

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

* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (76 commits)
  IDE: Report errors during drive reset back to user space
  Update documentation of HDIO_DRIVE_RESET ioctl
  IDE: Remove unused code
  IDE: Fix HDIO_DRIVE_RESET handling
  hd.c: remove the #include <linux/mc146818rtc.h>
  update the BLK_DEV_HD help text
  move ide/legacy/hd.c to drivers/block/
  ide/legacy/hd.c: use late_initcall()
  remove BLK_DEV_HD_ONLY
  ide: endian annotations in ide-floppy.c
  ide-floppy: zero out the whole struct ide_atapi_pc on init
  ide-floppy: fold idefloppy_create_test_unit_ready_cmd into idefloppy_open
  ide-cd: move request prep chunk from cdrom_do_newpc_cont to rq issue path
  ide-cd: move request prep from cdrom_start_rw_cont to rq issue path
  ide-cd: move request prep from cdrom_start_seek_continuation to rq issue path
  ide-cd: fold cdrom_start_seek into ide_cd_do_request
  ide-cd: simplify request issuing path
  ide-cd: mv ide_do_rw_cdrom ide_cd_do_request
  ide-cd: cdrom_start_seek: remove unused argument block
  ide-cd: ide_do_rw_cdrom: add the catch-all bad request case to the if-else block
  ...
Linus Torvalds 17 years ago
parent
commit
42fdd144a4
58 changed files with 695 additions and 1871 deletions
  1. 4 3
      Documentation/ioctl/hdio.txt
  2. 12 0
      drivers/block/Kconfig
  3. 1 0
      drivers/block/Makefile
  4. 1 2
      drivers/block/hd.c
  5. 15 73
      drivers/ide/Kconfig
  6. 3 7
      drivers/ide/Makefile
  7. 0 1
      drivers/ide/arm/Makefile
  8. 0 90
      drivers/ide/arm/bast-ide.c
  9. 55 50
      drivers/ide/arm/icside.c
  10. 0 3
      drivers/ide/arm/palm_bk3710.c
  11. 19 14
      drivers/ide/arm/rapide.c
  12. 11 8
      drivers/ide/h8300/ide-h8300.c
  13. 77 83
      drivers/ide/ide-cd.c
  14. 0 1
      drivers/ide/ide-disk.c
  15. 12 20
      drivers/ide/ide-floppy.c
  16. 22 50
      drivers/ide/ide-io.c
  17. 18 6
      drivers/ide/ide-iops.c
  18. 0 151
      drivers/ide/ide-lib.c
  19. 94 0
      drivers/ide/ide-pio-blacklist.c
  20. 2 2
      drivers/ide/ide-pnp.c
  21. 15 6
      drivers/ide/ide-probe.c
  22. 0 1
      drivers/ide/ide-tape.c
  23. 1 32
      drivers/ide/ide-taskfile.c
  24. 96 108
      drivers/ide/ide-timings.c
  25. 19 57
      drivers/ide/ide.c
  26. 2 1
      drivers/ide/legacy/ali14xx.c
  27. 0 1
      drivers/ide/legacy/buddha.c
  28. 0 1
      drivers/ide/legacy/falconide.c
  29. 0 1
      drivers/ide/legacy/gayle.c
  30. 7 8
      drivers/ide/legacy/ht6560b.c
  31. 16 9
      drivers/ide/legacy/ide-4drives.c
  32. 6 3
      drivers/ide/legacy/ide-cs.c
  33. 7 2
      drivers/ide/legacy/ide_platform.c
  34. 0 1
      drivers/ide/legacy/macide.c
  35. 0 1
      drivers/ide/legacy/q40ide.c
  36. 10 9
      drivers/ide/legacy/qd65xx.c
  37. 3 10
      drivers/ide/mips/au1xxx-ide.c
  38. 17 11
      drivers/ide/mips/swarm.c
  39. 2 4
      drivers/ide/pci/alim15x3.c
  40. 0 2
      drivers/ide/pci/amd74xx.c
  41. 57 74
      drivers/ide/pci/cmd640.c
  42. 3 3
      drivers/ide/pci/cmd64x.c
  43. 1 5
      drivers/ide/pci/cs5535.c
  44. 4 5
      drivers/ide/pci/cy82c693.c
  45. 0 1
      drivers/ide/pci/delkin_cb.c
  46. 6 0
      drivers/ide/pci/it821x.c
  47. 2 6
      drivers/ide/pci/scc_pata.c
  48. 12 11
      drivers/ide/pci/sgiioc4.c
  49. 1 2
      drivers/ide/pci/siimage.c
  50. 0 3
      drivers/ide/pci/sis5513.c
  51. 2 1
      drivers/ide/pci/sl82c105.c
  52. 0 2
      drivers/ide/pci/via82cxxx.c
  53. 0 1
      drivers/ide/ppc/Makefile
  54. 0 851
      drivers/ide/ppc/mpc8xx.c
  55. 8 13
      drivers/ide/ppc/pmac.c
  56. 8 17
      drivers/ide/setup-pci.c
  57. 0 14
      drivers/scsi/ide-scsi.c
  58. 44 30
      include/linux/ide.h

+ 4 - 3
Documentation/ioctl/hdio.txt

@@ -508,12 +508,13 @@ HDIO_DRIVE_RESET		execute a device reset
 
 
 	error returns:
 	error returns:
 	  EACCES	Access denied:  requires CAP_SYS_ADMIN
 	  EACCES	Access denied:  requires CAP_SYS_ADMIN
+	  ENXIO		No such device:	phy dead or ctl_addr == 0
+	  EIO		I/O error:	reset timed out or hardware error
 
 
 	notes:
 	notes:
 
 
-	  Abort any current command, prevent anything else from being
-	  queued, execute a reset on the device, and issue BLKRRPART
-	  ioctl on the block device.
+	  Execute a reset on the device as soon as the current IO
+	  operation has completed.
 
 
 	  Executes an ATAPI soft reset if applicable, otherwise
 	  Executes an ATAPI soft reset if applicable, otherwise
 	  executes an ATA soft reset on the controller.
 	  executes an ATA soft reset on the controller.

+ 12 - 0
drivers/block/Kconfig

@@ -433,4 +433,16 @@ config VIRTIO_BLK
 	  This is the virtual block driver for virtio.  It can be used with
 	  This is the virtual block driver for virtio.  It can be used with
           lguest or QEMU based VMMs (like KVM or Xen).  Say Y or M.
           lguest or QEMU based VMMs (like KVM or Xen).  Say Y or M.
 
 
+config BLK_DEV_HD
+	bool "Very old hard disk (MFM/RLL/IDE) driver"
+	depends on HAVE_IDE
+	depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN
+	help
+	  This is a very old hard disk driver that lacks the enhanced
+	  functionality of the newer ones.
+
+	  It is required for systems with ancient MFM/RLL/ESDI drives.
+
+	  If unsure, say N.
+
 endif # BLK_DEV
 endif # BLK_DEV

+ 1 - 0
drivers/block/Makefile

@@ -29,5 +29,6 @@ obj-$(CONFIG_VIRTIO_BLK)	+= virtio_blk.o
 obj-$(CONFIG_VIODASD)		+= viodasd.o
 obj-$(CONFIG_VIODASD)		+= viodasd.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o
 obj-$(CONFIG_BLK_DEV_UB)	+= ub.o
 obj-$(CONFIG_BLK_DEV_UB)	+= ub.o
+obj-$(CONFIG_BLK_DEV_HD)	+= hd.o
 
 
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= xen-blkfront.o
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= xen-blkfront.o

+ 1 - 2
drivers/ide/legacy/hd.c → drivers/block/hd.c

@@ -37,7 +37,6 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/ioport.h>
-#include <linux/mc146818rtc.h> /* CMOS defines */
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/blkpg.h>
 #include <linux/blkpg.h>
 #include <linux/hdreg.h>
 #include <linux/hdreg.h>
@@ -812,4 +811,4 @@ static int __init parse_hd_setup(char *line)
 }
 }
 __setup("hd=", parse_hd_setup);
 __setup("hd=", parse_hd_setup);
 
 
-module_init(hd_init);
+late_initcall(hd_init);

+ 15 - 73
drivers/ide/Kconfig

@@ -98,6 +98,9 @@ if BLK_DEV_IDE
 
 
 comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"
 comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"
 
 
+config IDE_TIMINGS
+	bool
+
 config IDE_ATAPI
 config IDE_ATAPI
 	bool
 	bool
 
 
@@ -326,6 +329,7 @@ config BLK_DEV_PLATFORM
 config BLK_DEV_CMD640
 config BLK_DEV_CMD640
 	tristate "CMD640 chipset bugfix/support"
 	tristate "CMD640 chipset bugfix/support"
 	depends on X86
 	depends on X86
+	select IDE_TIMINGS
 	---help---
 	---help---
 	  The CMD-Technologies CMD640 IDE chip is used on many common 486 and
 	  The CMD-Technologies CMD640 IDE chip is used on many common 486 and
 	  Pentium motherboards, usually in combination with a "Neptune" or
 	  Pentium motherboards, usually in combination with a "Neptune" or
@@ -455,6 +459,7 @@ config BLK_DEV_AEC62XX
 
 
 config BLK_DEV_ALI15X3
 config BLK_DEV_ALI15X3
 	tristate "ALI M15x3 chipset support"
 	tristate "ALI M15x3 chipset support"
+	select IDE_TIMINGS
 	select BLK_DEV_IDEDMA_PCI
 	select BLK_DEV_IDEDMA_PCI
 	help
 	help
 	  This driver ensures (U)DMA support for ALI 1533, 1543 and 1543C
 	  This driver ensures (U)DMA support for ALI 1533, 1543 and 1543C
@@ -469,6 +474,7 @@ config BLK_DEV_ALI15X3
 config BLK_DEV_AMD74XX
 config BLK_DEV_AMD74XX
 	tristate "AMD and nVidia IDE support"
 	tristate "AMD and nVidia IDE support"
 	depends on !ARM
 	depends on !ARM
+	select IDE_TIMINGS
 	select BLK_DEV_IDEDMA_PCI
 	select BLK_DEV_IDEDMA_PCI
 	help
 	help
 	  This driver adds explicit support for AMD-7xx and AMD-8111 chips
 	  This driver adds explicit support for AMD-7xx and AMD-8111 chips
@@ -489,6 +495,7 @@ config BLK_DEV_ATIIXP
 
 
 config BLK_DEV_CMD64X
 config BLK_DEV_CMD64X
 	tristate "CMD64{3|6|8|9} chipset support"
 	tristate "CMD64{3|6|8|9} chipset support"
+	select IDE_TIMINGS
 	select BLK_DEV_IDEDMA_PCI
 	select BLK_DEV_IDEDMA_PCI
 	help
 	help
 	  Say Y here if you have an IDE controller which uses any of these
 	  Say Y here if you have an IDE controller which uses any of these
@@ -503,6 +510,7 @@ config BLK_DEV_TRIFLEX
 
 
 config BLK_DEV_CY82C693
 config BLK_DEV_CY82C693
 	tristate "CY82C693 chipset support"
 	tristate "CY82C693 chipset support"
+	select IDE_TIMINGS
 	select BLK_DEV_IDEDMA_PCI
 	select BLK_DEV_IDEDMA_PCI
 	help
 	help
 	  This driver adds detection and support for the CY82C693 chipset
 	  This driver adds detection and support for the CY82C693 chipset
@@ -695,6 +703,7 @@ config BLK_DEV_SIS5513
 config BLK_DEV_SL82C105
 config BLK_DEV_SL82C105
 	tristate "Winbond SL82c105 support"
 	tristate "Winbond SL82c105 support"
 	depends on (PPC || ARM)
 	depends on (PPC || ARM)
+	select IDE_TIMINGS
 	select BLK_DEV_IDEDMA_PCI
 	select BLK_DEV_IDEDMA_PCI
 	help
 	help
 	  If you have a Winbond SL82c105 IDE controller, say Y here to enable
 	  If you have a Winbond SL82c105 IDE controller, say Y here to enable
@@ -725,6 +734,7 @@ config BLK_DEV_TRM290
 
 
 config BLK_DEV_VIA82CXXX
 config BLK_DEV_VIA82CXXX
 	tristate "VIA82CXXX chipset support"
 	tristate "VIA82CXXX chipset support"
+	select IDE_TIMINGS
 	select BLK_DEV_IDEDMA_PCI
 	select BLK_DEV_IDEDMA_PCI
 	help
 	help
 	  This driver adds explicit support for VIA BusMastering IDE chips.
 	  This driver adds explicit support for VIA BusMastering IDE chips.
@@ -751,6 +761,7 @@ endif
 config BLK_DEV_IDE_PMAC
 config BLK_DEV_IDE_PMAC
 	tristate "PowerMac on-board IDE support"
 	tristate "PowerMac on-board IDE support"
 	depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y
 	depends on PPC_PMAC && IDE=y && BLK_DEV_IDE=y
+	select IDE_TIMINGS
 	help
 	help
 	  This driver provides support for the on-board IDE controller on
 	  This driver provides support for the on-board IDE controller on
 	  most of the recent Apple Power Macintoshes and PowerBooks.
 	  most of the recent Apple Power Macintoshes and PowerBooks.
@@ -829,13 +840,6 @@ config BLK_DEV_IDE_RAPIDE
 	  Say Y here if you want to support the Yellowstone RapIDE controller
 	  Say Y here if you want to support the Yellowstone RapIDE controller
 	  manufactured for use with Acorn computers.
 	  manufactured for use with Acorn computers.
 
 
-config BLK_DEV_IDE_BAST
-	tristate "Simtec BAST / Thorcom VR1000 IDE support"
-	depends on ARM && (ARCH_BAST || MACH_VR1000)
-	help
-	  Say Y here if you want to support the onboard IDE channels on the
-	  Simtec BAST or the Thorcom VR1000
-
 config IDE_H8300
 config IDE_H8300
 	tristate "H8300 IDE support"
 	tristate "H8300 IDE support"
 	depends on H8300
 	depends on H8300
@@ -919,51 +923,12 @@ config BLK_DEV_Q40IDE
 config BLK_DEV_PALMCHIP_BK3710
 config BLK_DEV_PALMCHIP_BK3710
 	tristate "Palmchip bk3710 IDE controller support"
 	tristate "Palmchip bk3710 IDE controller support"
 	depends on ARCH_DAVINCI
 	depends on ARCH_DAVINCI
+	select IDE_TIMINGS
 	select BLK_DEV_IDEDMA_SFF
 	select BLK_DEV_IDEDMA_SFF
 	help
 	help
 	  Say Y here if you want to support the onchip IDE controller on the
 	  Say Y here if you want to support the onchip IDE controller on the
 	  TI DaVinci SoC
 	  TI DaVinci SoC
 
 
-
-config BLK_DEV_MPC8xx_IDE
-	tristate "MPC8xx IDE support"
-	depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE
-	help
-	  This option provides support for IDE on Motorola MPC8xx Systems.
-	  Please see 'Type of MPC8xx IDE interface' for details.
-
-	  If unsure, say N.
-
-choice
-	prompt "Type of MPC8xx IDE interface"
-	depends on BLK_DEV_MPC8xx_IDE
-	default IDE_8xx_PCCARD
-
-config IDE_8xx_PCCARD
-	bool "8xx_PCCARD"
-	---help---
-	  Select how the IDE devices are connected to the MPC8xx system:
-
-	  8xx_PCCARD uses the 8xx internal PCMCIA interface in combination
-	  with a PC Card (e.g. ARGOSY portable Hard Disk Adapter),
-	  ATA PC Card HDDs or ATA PC Flash Cards (example: TQM8xxL
-	  systems)
-
-	  8xx_DIRECT is used for directly connected IDE devices using the 8xx
-	  internal PCMCIA interface (example: IVMS8 systems)
-
-	  EXT_DIRECT is used for IDE devices directly connected to the 8xx
-	  bus using some glue logic, but _not_ the 8xx internal
-	  PCMCIA interface (example: IDIF860 systems)
-
-config IDE_8xx_DIRECT
-	bool "8xx_DIRECT"
-
-config IDE_EXT_DIRECT
-	bool "EXT_DIRECT"
-
-endchoice
-
 # no isa -> no vlb
 # no isa -> no vlb
 if ISA && (ALPHA || X86 || MIPS)
 if ISA && (ALPHA || X86 || MIPS)
 
 
@@ -981,6 +946,7 @@ config BLK_DEV_4DRIVES
 
 
 config BLK_DEV_ALI14XX
 config BLK_DEV_ALI14XX
 	tristate "ALI M14xx support"
 	tristate "ALI M14xx support"
+	select IDE_TIMINGS
 	help
 	help
 	  This driver is enabled at runtime using the "ali14xx.probe" kernel
 	  This driver is enabled at runtime using the "ali14xx.probe" kernel
 	  boot parameter.  It enables support for the secondary IDE interface
 	  boot parameter.  It enables support for the secondary IDE interface
@@ -1000,6 +966,7 @@ config BLK_DEV_DTC2278
 
 
 config BLK_DEV_HT6560B
 config BLK_DEV_HT6560B
 	tristate "Holtek HT6560B support"
 	tristate "Holtek HT6560B support"
+	select IDE_TIMINGS
 	help
 	help
 	  This driver is enabled at runtime using the "ht6560b.probe" kernel
 	  This driver is enabled at runtime using the "ht6560b.probe" kernel
 	  boot parameter. It enables support for the secondary IDE interface
 	  boot parameter. It enables support for the secondary IDE interface
@@ -1009,6 +976,7 @@ config BLK_DEV_HT6560B
 
 
 config BLK_DEV_QD65XX
 config BLK_DEV_QD65XX
 	tristate "QDI QD65xx support"
 	tristate "QDI QD65xx support"
+	select IDE_TIMINGS
 	help
 	help
 	  This driver is enabled at runtime using the "qd65xx.probe" kernel
 	  This driver is enabled at runtime using the "qd65xx.probe" kernel
 	  boot parameter.  It permits faster I/O speeds to be set.  See the
 	  boot parameter.  It permits faster I/O speeds to be set.  See the
@@ -1032,30 +1000,4 @@ config BLK_DEV_IDEDMA
 
 
 endif
 endif
 
 
-config BLK_DEV_HD_ONLY
-	bool "Old hard disk (MFM/RLL/IDE) driver"
-	depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN
-	help
-	  There are two drivers for MFM/RLL/IDE hard disks. Most people use
-	  the newer enhanced driver, but this old one is still around for two
-	  reasons. Some older systems have strange timing problems and seem to
-	  work only with the old driver (which itself does not work with some
-	  newer systems). The other reason is that the old driver is smaller,
-	  since it lacks the enhanced functionality of the new one. This makes
-	  it a good choice for systems with very tight memory restrictions, or
-	  for systems with only older MFM/RLL/ESDI drives. Choosing the old
-	  driver can save 13 KB or so of kernel memory.
-
-	  If you want to use this driver together with the new one you have
-	  to use "hda=noprobe hdb=noprobe" kernel parameters to prevent the new
-	  driver from probing the primary interface.
-
-	  If you are unsure, then just choose the Enhanced IDE/MFM/RLL driver
-	  instead of this one. For more detailed information, read the
-	  Disk-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-config BLK_DEV_HD
-	def_bool BLK_DEV_HD_ONLY
-
 endif # IDE
 endif # IDE

+ 3 - 7
drivers/ide/Makefile

@@ -11,9 +11,11 @@
 
 
 EXTRA_CFLAGS				+= -Idrivers/ide
 EXTRA_CFLAGS				+= -Idrivers/ide
 
 
-ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o
+ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o \
+	      ide-pio-blacklist.o
 
 
 # core IDE code
 # core IDE code
+ide-core-$(CONFIG_IDE_TIMINGS)		+= ide-timings.o
 ide-core-$(CONFIG_IDE_ATAPI)		+= ide-atapi.o
 ide-core-$(CONFIG_IDE_ATAPI)		+= ide-atapi.o
 ide-core-$(CONFIG_BLK_DEV_IDEPCI)	+= setup-pci.o
 ide-core-$(CONFIG_BLK_DEV_IDEPCI)	+= setup-pci.o
 ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
 ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
@@ -59,9 +61,3 @@ ifeq ($(CONFIG_BLK_DEV_PLATFORM), y)
 endif
 endif
 
 
 obj-$(CONFIG_BLK_DEV_IDE)		+= arm/ mips/
 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

+ 0 - 1
drivers/ide/arm/Makefile

@@ -1,7 +1,6 @@
 
 
 obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)	+= icside.o
 obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)	+= icside.o
 obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)	+= rapide.o
 obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)	+= rapide.o
-obj-$(CONFIG_BLK_DEV_IDE_BAST)		+= bast-ide.o
 obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710)	+= palm_bk3710.o
 obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710)	+= palm_bk3710.o
 
 
 ifeq ($(CONFIG_IDE_ARM), m)
 ifeq ($(CONFIG_IDE_ARM), m)

+ 0 - 90
drivers/ide/arm/bast-ide.c

@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2003-2004 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/arch/map.h>
-#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;
-	hw_regs_t hw;
-	int i;
-	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-
-	memset(&hw, 0, sizeof(hw));
-
-	base += BAST_IDE_CS;
-	aux  += BAST_IDE_CS;
-
-	for (i = 0; i <= 7; i++) {
-		hw.io_ports_array[i] = (unsigned long)base;
-		base += 0x20;
-	}
-
-	hw.io_ports.ctl_addr = aux + (6 * 0x20);
-	hw.irq = irq;
-	hw.chipset = ide_generic;
-
-	hwif = ide_find_port();
-	if (hwif == NULL)
-		goto out;
-
-	i = hwif->index;
-
-	ide_init_port_data(hwif, i);
-	ide_init_port_hw(hwif, &hw);
-	hwif->port_ops = NULL;
-
-	idx[0] = i;
-
-	ide_device_add(idx, NULL);
-out:
-	return 0;
-}
-
-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()))
-		return 0;
-
-	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);
-
-	return 0;
-}
-
-module_init(bastide_init);
-
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Simtec BAST / Thorcom VR1000 IDE driver");

+ 55 - 50
drivers/ide/arm/icside.c

@@ -21,6 +21,8 @@
 #include <asm/dma.h>
 #include <asm/dma.h>
 #include <asm/ecard.h>
 #include <asm/ecard.h>
 
 
+#define DRV_NAME "icside"
+
 #define ICS_IDENT_OFFSET		0x2280
 #define ICS_IDENT_OFFSET		0x2280
 
 
 #define ICS_ARCIN_V5_INTRSTAT		0x0000
 #define ICS_ARCIN_V5_INTRSTAT		0x0000
@@ -68,6 +70,7 @@ struct icside_state {
 	unsigned int enabled;
 	unsigned int enabled;
 	void __iomem *irq_port;
 	void __iomem *irq_port;
 	void __iomem *ioc_base;
 	void __iomem *ioc_base;
+	unsigned int sel;
 	unsigned int type;
 	unsigned int type;
 	ide_hwif_t *hwif[2];
 	ide_hwif_t *hwif[2];
 };
 };
@@ -165,7 +168,8 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = {
 static void icside_maskproc(ide_drive_t *drive, int mask)
 static void icside_maskproc(ide_drive_t *drive, int mask)
 {
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_hwif_t *hwif = HWIF(drive);
-	struct icside_state *state = hwif->hwif_data;
+	struct expansion_card *ec = ECARD_DEV(hwif->dev);
+	struct icside_state *state = ecard_get_drvdata(ec);
 	unsigned long flags;
 	unsigned long flags;
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
@@ -308,6 +312,7 @@ static int icside_dma_setup(ide_drive_t *drive)
 {
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_hwif_t *hwif = HWIF(drive);
 	struct expansion_card *ec = ECARD_DEV(hwif->dev);
 	struct expansion_card *ec = ECARD_DEV(hwif->dev);
+	struct icside_state *state = ecard_get_drvdata(ec);
 	struct request *rq = hwif->hwgroup->rq;
 	struct request *rq = hwif->hwgroup->rq;
 	unsigned int dma_mode;
 	unsigned int dma_mode;
 
 
@@ -331,7 +336,7 @@ static int icside_dma_setup(ide_drive_t *drive)
 	/*
 	/*
 	 * Route the DMA signals to the correct interface.
 	 * Route the DMA signals to the correct interface.
 	 */
 	 */
-	writeb(hwif->select_data, hwif->config_data);
+	writeb(state->sel | hwif->channel, state->ioc_base);
 
 
 	/*
 	/*
 	 * Select the correct timing for this drive.
 	 * Select the correct timing for this drive.
@@ -359,7 +364,8 @@ static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
 static int icside_dma_test_irq(ide_drive_t *drive)
 static int icside_dma_test_irq(ide_drive_t *drive)
 {
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_hwif_t *hwif = HWIF(drive);
-	struct icside_state *state = hwif->hwif_data;
+	struct expansion_card *ec = ECARD_DEV(hwif->dev);
+	struct icside_state *state = ecard_get_drvdata(ec);
 
 
 	return readb(state->irq_port +
 	return readb(state->irq_port +
 		     (hwif->channel ?
 		     (hwif->channel ?
@@ -411,36 +417,24 @@ static int icside_dma_off_init(ide_hwif_t *hwif, const struct ide_port_info *d)
 	return -EOPNOTSUPP;
 	return -EOPNOTSUPP;
 }
 }
 
 
-static ide_hwif_t *
-icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec)
+static void icside_setup_ports(hw_regs_t *hw, void __iomem *base,
+			       struct cardinfo *info, struct expansion_card *ec)
 {
 {
 	unsigned long port = (unsigned long)base + info->dataoffset;
 	unsigned long port = (unsigned long)base + info->dataoffset;
-	ide_hwif_t *hwif;
 
 
-	hwif = ide_find_port();
-	if (hwif) {
-		/*
-		 * Ensure we're using MMIO
-		 */
-		default_hwif_mmiops(hwif);
-
-		hwif->io_ports.data_addr = port;
-		hwif->io_ports.error_addr = port + (1 << info->stepping);
-		hwif->io_ports.nsect_addr = port + (2 << info->stepping);
-		hwif->io_ports.lbal_addr = port + (3 << info->stepping);
-		hwif->io_ports.lbam_addr = port + (4 << info->stepping);
-		hwif->io_ports.lbah_addr = port + (5 << info->stepping);
-		hwif->io_ports.device_addr = port + (6 << info->stepping);
-		hwif->io_ports.status_addr = port + (7 << info->stepping);
-		hwif->io_ports.ctl_addr =
-			(unsigned long)base + info->ctrloffset;
-		hwif->irq     = ec->irq;
-		hwif->chipset = ide_acorn;
-		hwif->gendev.parent = &ec->dev;
-		hwif->dev = &ec->dev;
-	}
-
-	return hwif;
+	hw->io_ports.data_addr	 = port;
+	hw->io_ports.error_addr	 = port + (1 << info->stepping);
+	hw->io_ports.nsect_addr	 = port + (2 << info->stepping);
+	hw->io_ports.lbal_addr	 = port + (3 << info->stepping);
+	hw->io_ports.lbam_addr	 = port + (4 << info->stepping);
+	hw->io_ports.lbah_addr	 = port + (5 << info->stepping);
+	hw->io_ports.device_addr = port + (6 << info->stepping);
+	hw->io_ports.status_addr = port + (7 << info->stepping);
+	hw->io_ports.ctl_addr	 = (unsigned long)base + info->ctrloffset;
+
+	hw->irq = ec->irq;
+	hw->dev = &ec->dev;
+	hw->chipset = ide_acorn;
 }
 }
 
 
 static int __init
 static int __init
@@ -449,6 +443,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
 	ide_hwif_t *hwif;
 	ide_hwif_t *hwif;
 	void __iomem *base;
 	void __iomem *base;
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+	hw_regs_t hw;
 
 
 	base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
 	base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
 	if (!base)
 	if (!base)
@@ -466,12 +461,19 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
 	 */
 	 */
 	icside_irqdisable_arcin_v5(ec, 0);
 	icside_irqdisable_arcin_v5(ec, 0);
 
 
-	hwif = icside_setup(base, &icside_cardinfo_v5, ec);
+	icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec);
+
+	hwif = ide_find_port();
 	if (!hwif)
 	if (!hwif)
 		return -ENODEV;
 		return -ENODEV;
 
 
+	ide_init_port_hw(hwif, &hw);
+	default_hwif_mmiops(hwif);
+
 	state->hwif[0] = hwif;
 	state->hwif[0] = hwif;
 
 
+	ecard_set_drvdata(ec, state);
+
 	idx[0] = hwif->index;
 	idx[0] = hwif->index;
 
 
 	ide_device_add(idx, NULL);
 	ide_device_add(idx, NULL);
@@ -497,6 +499,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
 	int ret;
 	int ret;
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	struct ide_port_info d = icside_v6_port_info;
 	struct ide_port_info d = icside_v6_port_info;
+	hw_regs_t hw[2];
 
 
 	ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
 	ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
 	if (!ioc_base) {
 	if (!ioc_base) {
@@ -525,43 +528,47 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
 
 
 	state->irq_port   = easi_base;
 	state->irq_port   = easi_base;
 	state->ioc_base   = ioc_base;
 	state->ioc_base   = ioc_base;
+	state->sel	  = sel;
 
 
 	/*
 	/*
 	 * Be on the safe side - disable interrupts
 	 * Be on the safe side - disable interrupts
 	 */
 	 */
 	icside_irqdisable_arcin_v6(ec, 0);
 	icside_irqdisable_arcin_v6(ec, 0);
 
 
+	icside_setup_ports(&hw[0], easi_base, &icside_cardinfo_v6_1, ec);
+	icside_setup_ports(&hw[1], easi_base, &icside_cardinfo_v6_2, ec);
+
 	/*
 	/*
 	 * Find and register the interfaces.
 	 * Find and register the interfaces.
 	 */
 	 */
-	hwif = icside_setup(easi_base, &icside_cardinfo_v6_1, ec);
-	mate = icside_setup(easi_base, &icside_cardinfo_v6_2, ec);
+	hwif = ide_find_port();
+	if (hwif == NULL)
+		return -ENODEV;
 
 
-	if (!hwif || !mate) {
-		ret = -ENODEV;
-		goto out;
+	ide_init_port_hw(hwif, &hw[0]);
+	default_hwif_mmiops(hwif);
+
+	idx[0] = hwif->index;
+
+	mate = ide_find_port();
+	if (mate) {
+		ide_init_port_hw(mate, &hw[1]);
+		default_hwif_mmiops(mate);
+
+		idx[1] = mate->index;
 	}
 	}
 
 
 	state->hwif[0]    = hwif;
 	state->hwif[0]    = hwif;
 	state->hwif[1]    = mate;
 	state->hwif[1]    = mate;
 
 
-	hwif->hwif_data   = state;
-	hwif->config_data = (unsigned long)ioc_base;
-	hwif->select_data = sel;
-
-	mate->hwif_data   = state;
-	mate->config_data = (unsigned long)ioc_base;
-	mate->select_data = sel | 1;
+	ecard_set_drvdata(ec, state);
 
 
-	if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
+	if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
 		d.init_dma = icside_dma_init;
 		d.init_dma = icside_dma_init;
 		d.port_ops = &icside_v6_port_ops;
 		d.port_ops = &icside_v6_port_ops;
 		d.dma_ops = NULL;
 		d.dma_ops = NULL;
 	}
 	}
 
 
-	idx[0] = hwif->index;
-	idx[1] = mate->index;
-
 	ide_device_add(idx, &d);
 	ide_device_add(idx, &d);
 
 
 	return 0;
 	return 0;
@@ -627,10 +634,8 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id)
 		break;
 		break;
 	}
 	}
 
 
-	if (ret == 0) {
-		ecard_set_drvdata(ec, state);
+	if (ret == 0)
 		goto out;
 		goto out;
-	}
 
 
 	kfree(state);
 	kfree(state);
  release:
  release:

+ 0 - 3
drivers/ide/arm/palm_bk3710.c

@@ -74,8 +74,6 @@ struct palm_bk3710_udmatiming {
 #define BK3710_IORDYTMP		0x78
 #define BK3710_IORDYTMP		0x78
 #define BK3710_IORDYTMS		0x7C
 #define BK3710_IORDYTMS		0x7C
 
 
-#include "../ide-timing.h"
-
 static unsigned ideclk_period; /* in nanoseconds */
 static unsigned ideclk_period; /* in nanoseconds */
 
 
 static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
 static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
@@ -402,7 +400,6 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
 
 
 	i = hwif->index;
 	i = hwif->index;
 
 
-	ide_init_port_data(hwif, i);
 	ide_init_port_hw(hwif, &hw);
 	ide_init_port_hw(hwif, &hw);
 
 
 	default_hwif_mmiops(hwif);
 	default_hwif_mmiops(hwif);

+ 19 - 14
drivers/ide/arm/rapide.c

@@ -11,6 +11,10 @@
 
 
 #include <asm/ecard.h>
 #include <asm/ecard.h>
 
 
+static struct const ide_port_info rapide_port_info = {
+	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+};
+
 static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base,
 static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base,
 			       void __iomem *ctrl, unsigned int sz, int irq)
 			       void __iomem *ctrl, unsigned int sz, int irq)
 {
 {
@@ -44,25 +48,26 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
 		goto release;
 		goto release;
 	}
 	}
 
 
-	hwif = ide_find_port();
-	if (hwif) {
-		memset(&hw, 0, sizeof(hw));
-		rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq);
-		hw.chipset = ide_generic;
-		hw.dev = &ec->dev;
+	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 = ide_find_port();
+	if (hwif == NULL) {
+		ret = -ENOENT;
+		goto release;
+	}
 
 
-		hwif->host_flags = IDE_HFLAG_MMIO;
-		default_hwif_mmiops(hwif);
+	ide_init_port_hw(hwif, &hw);
+	default_hwif_mmiops(hwif);
 
 
-		idx[0] = hwif->index;
+	idx[0] = hwif->index;
 
 
-		ide_device_add(idx, NULL);
+	ide_device_add(idx, &rapide_port_info);
 
 
-		ecard_set_drvdata(ec, hwif);
-		goto out;
-	}
+	ecard_set_drvdata(ec, hwif);
+	goto out;
 
 
  release:
  release:
 	ecard_release_resources(ec);
 	ecard_release_resources(ec);

+ 11 - 8
drivers/ide/h8300/ide-h8300.c

@@ -8,6 +8,8 @@
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/irq.h>
 
 
+#define DRV_NAME "ide-h8300"
+
 #define bswap(d) \
 #define bswap(d) \
 ({					\
 ({					\
 	u16 r;				\
 	u16 r;				\
@@ -176,6 +178,10 @@ static inline void hwif_setup(ide_hwif_t *hwif)
 	hwif->output_data = h8300_output_data;
 	hwif->output_data = h8300_output_data;
 }
 }
 
 
+static const struct ide_port_info h8300_port_info = {
+	.host_flags		= IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA,
+};
+
 static int __init h8300_ide_init(void)
 static int __init h8300_ide_init(void)
 {
 {
 	hw_regs_t hw;
 	hw_regs_t hw;
@@ -183,6 +189,8 @@ static int __init h8300_ide_init(void)
 	int index;
 	int index;
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 
+	printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n");
+
 	if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300"))
 	if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300"))
 		goto out_busy;
 		goto out_busy;
 	if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) {
 	if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) {
@@ -192,22 +200,17 @@ static int __init h8300_ide_init(void)
 
 
 	hw_setup(&hw);
 	hw_setup(&hw);
 
 
-	hwif = ide_find_port();
-	if (hwif == NULL) {
-		printk(KERN_ERR "ide-h8300: IDE I/F register failed\n");
+	hwif = ide_find_port_slot(&h8300_port_info);
+	if (hwif == NULL)
 		return -ENOENT;
 		return -ENOENT;
-	}
 
 
 	index = hwif->index;
 	index = hwif->index;
-	ide_init_port_data(hwif, index);
 	ide_init_port_hw(hwif, &hw);
 	ide_init_port_hw(hwif, &hw);
 	hwif_setup(hwif);
 	hwif_setup(hwif);
-	hwif->host_flags = IDE_HFLAG_NO_IO_32BIT;
-	printk(KERN_INFO "ide%d: H8/300 generic IDE interface\n", index);
 
 
 	idx[0] = index;
 	idx[0] = index;
 
 
-	ide_device_add(idx, NULL);
+	ide_device_add(idx, &h8300_port_info);
 
 
 	return 0;
 	return 0;
 
 

+ 77 - 83
drivers/ide/ide-cd.c

@@ -517,14 +517,9 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
 						  int xferlen,
 						  int xferlen,
 						  ide_handler_t *handler)
 						  ide_handler_t *handler)
 {
 {
-	ide_startstop_t startstop;
 	struct cdrom_info *info = drive->driver_data;
 	struct cdrom_info *info = drive->driver_data;
 	ide_hwif_t *hwif = drive->hwif;
 	ide_hwif_t *hwif = drive->hwif;
 
 
-	/* wait for the controller to be idle */
-	if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
-		return startstop;
-
 	/* FIXME: for Virtual DMA we must check harder */
 	/* FIXME: for Virtual DMA we must check harder */
 	if (info->dma)
 	if (info->dma)
 		info->dma = !hwif->dma_ops->dma_setup(drive);
 		info->dma = !hwif->dma_ops->dma_setup(drive);
@@ -603,28 +598,6 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
 	return ide_started;
 	return ide_started;
 }
 }
 
 
-/*
- * Block read functions.
- */
-static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len)
-{
-	while (len > 0) {
-		int dum = 0;
-		xf(drive, NULL, &dum, sizeof(dum));
-		len -= sizeof(dum);
-	}
-}
-
-static void ide_cd_drain_data(ide_drive_t *drive, int nsects)
-{
-	while (nsects > 0) {
-		static char dum[SECTOR_SIZE];
-
-		drive->hwif->input_data(drive, NULL, dum, sizeof(dum));
-		nsects--;
-	}
-}
-
 /*
 /*
  * Check the contents of the interrupt reason register from the cdrom
  * Check the contents of the interrupt reason register from the cdrom
  * and attempt to recover if there are problems.  Returns  0 if everything's
  * and attempt to recover if there are problems.  Returns  0 if everything's
@@ -640,15 +613,12 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
 	if (ireason == (!rw << 1))
 	if (ireason == (!rw << 1))
 		return 0;
 		return 0;
 	else if (ireason == (rw << 1)) {
 	else if (ireason == (rw << 1)) {
-		ide_hwif_t *hwif = drive->hwif;
-		xfer_func_t *xf;
 
 
 		/* whoops... */
 		/* whoops... */
 		printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
 		printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
 				drive->name, __func__);
 				drive->name, __func__);
 
 
-		xf = rw ? hwif->output_data : hwif->input_data;
-		ide_cd_pad_transfer(drive, xf, len);
+		ide_pad_transfer(drive, rw, len);
 	} else  if (rw == 0 && ireason == 1) {
 	} else  if (rw == 0 && ireason == 1) {
 		/*
 		/*
 		 * Some drives (ASUS) seem to tell us that status info is
 		 * Some drives (ASUS) seem to tell us that status info is
@@ -696,16 +666,9 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
 
 
 static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
 static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
 
 
-/*
- * Routine to send a read/write packet command to the drive. This is usually
- * called directly from cdrom_start_{read,write}(). However, for drq_interrupt
- * devices, it is called from an interrupt when the drive is ready to accept
- * the command.
- */
-static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
+static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
+						 struct request *rq)
 {
 {
-	struct request *rq = HWGROUP(drive)->rq;
-
 	if (rq_data_dir(rq) == READ) {
 	if (rq_data_dir(rq) == READ) {
 		unsigned short sectors_per_frame =
 		unsigned short sectors_per_frame =
 			queue_hardsect_size(drive->queue) >> SECTOR_BITS;
 			queue_hardsect_size(drive->queue) >> SECTOR_BITS;
@@ -742,6 +705,19 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
 	/* set up the command */
 	/* set up the command */
 	rq->timeout = ATAPI_WAIT_PC;
 	rq->timeout = ATAPI_WAIT_PC;
 
 
+	return ide_started;
+}
+
+/*
+ * Routine to send a read/write packet command to the drive. This is usually
+ * called directly from cdrom_start_{read,write}(). However, for drq_interrupt
+ * devices, it is called from an interrupt when the drive is ready to accept
+ * the command.
+ */
+static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
+{
+	struct request *rq = drive->hwif->hwgroup->rq;
+
 	/* send the command to the drive and return */
 	/* send the command to the drive and return */
 	return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
 	return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
 }
 }
@@ -768,9 +744,8 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive)
 	return ide_stopped;
 	return ide_stopped;
 }
 }
 
 
-static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive)
+static void ide_cd_prepare_seek_request(ide_drive_t *drive, struct request *rq)
 {
 {
-	struct request *rq = HWGROUP(drive)->rq;
 	sector_t frame = rq->sector;
 	sector_t frame = rq->sector;
 
 
 	sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
 	sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
@@ -780,17 +755,13 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive)
 	put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
 	put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
 
 
 	rq->timeout = ATAPI_WAIT_PC;
 	rq->timeout = ATAPI_WAIT_PC;
-	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_continuation(ide_drive_t *drive)
 {
 {
-	struct cdrom_info *info = drive->driver_data;
+	struct request *rq = drive->hwif->hwgroup->rq;
 
 
-	info->dma = 0;
-	info->start_seek = jiffies;
-	return cdrom_start_packet_command(drive, 0,
-					  cdrom_start_seek_continuation);
+	return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
 }
 }
 
 
 /*
 /*
@@ -1011,7 +982,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 					   - bio_cur_sectors(rq->bio),
 					   - bio_cur_sectors(rq->bio),
 					   thislen >> 9);
 					   thislen >> 9);
 			if (nskip > 0) {
 			if (nskip > 0) {
-				ide_cd_drain_data(drive, nskip);
+				ide_pad_transfer(drive, write, nskip << 9);
 				rq->current_nr_sectors -= nskip;
 				rq->current_nr_sectors -= nskip;
 				thislen -= (nskip << 9);
 				thislen -= (nskip << 9);
 			}
 			}
@@ -1048,7 +1019,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 				 * If the buffers are full, pipe the rest into
 				 * If the buffers are full, pipe the rest into
 				 * oblivion.
 				 * oblivion.
 				 */
 				 */
-				ide_cd_drain_data(drive, thislen >> 9);
+				ide_pad_transfer(drive, 0, thislen);
 			else {
 			else {
 				printk(KERN_ERR "%s: confused, missing data\n",
 				printk(KERN_ERR "%s: confused, missing data\n",
 						drive->name);
 						drive->name);
@@ -1096,7 +1067,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 
 
 	/* pad, if necessary */
 	/* pad, if necessary */
 	if (!blk_fs_request(rq) && len > 0)
 	if (!blk_fs_request(rq) && len > 0)
-		ide_cd_pad_transfer(drive, xferfunc, len);
+		ide_pad_transfer(drive, write, len);
 
 
 	if (blk_pc_request(rq)) {
 	if (blk_pc_request(rq)) {
 		timeout = rq->timeout;
 		timeout = rq->timeout;
@@ -1165,21 +1136,17 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
 	if (write)
 	if (write)
 		cd->devinfo.media_written = 1;
 		cd->devinfo.media_written = 1;
 
 
-	/* start sending the read/write request to the drive */
-	return cdrom_start_packet_command(drive, 32768, cdrom_start_rw_cont);
+	return ide_started;
 }
 }
 
 
 static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
 static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
 {
 {
 	struct request *rq = HWGROUP(drive)->rq;
 	struct request *rq = HWGROUP(drive)->rq;
 
 
-	if (!rq->timeout)
-		rq->timeout = ATAPI_WAIT_PC;
-
 	return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
 	return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
 }
 }
 
 
-static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
+static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 {
 {
 	struct cdrom_info *info = drive->driver_data;
 	struct cdrom_info *info = drive->driver_data;
 
 
@@ -1191,10 +1158,16 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 	info->dma = 0;
 	info->dma = 0;
 
 
 	/* sg request */
 	/* sg request */
-	if (rq->bio) {
-		int mask = drive->queue->dma_alignment;
-		unsigned long addr =
-			(unsigned long)page_address(bio_page(rq->bio));
+	if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) {
+		struct request_queue *q = drive->queue;
+		unsigned int alignment;
+		unsigned long addr;
+		unsigned long stack_mask = ~(THREAD_SIZE - 1);
+
+		if (rq->bio)
+			addr = (unsigned long)bio_data(rq->bio);
+		else
+			addr = (unsigned long)rq->data;
 
 
 		info->dma = drive->using_dma;
 		info->dma = drive->using_dma;
 
 
@@ -1204,23 +1177,25 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 		 * NOTE! The "len" and "addr" checks should possibly have
 		 * NOTE! The "len" and "addr" checks should possibly have
 		 * separate masks.
 		 * separate masks.
 		 */
 		 */
-		if ((rq->data_len & 15) || (addr & mask))
+		alignment = queue_dma_alignment(q) | q->dma_pad_mask;
+		if (addr & alignment || rq->data_len & alignment)
 			info->dma = 0;
 			info->dma = 0;
-	}
 
 
-	/* start sending the command to the drive */
-	return cdrom_start_packet_command(drive, rq->data_len,
-					  cdrom_do_newpc_cont);
+		if (!((addr & stack_mask) ^
+		      ((unsigned long)current->stack & stack_mask)))
+			info->dma = 0;
+	}
 }
 }
 
 
 /*
 /*
  * cdrom driver request routine.
  * cdrom driver request routine.
  */
  */
-static ide_startstop_t ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq,
+static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
 					sector_t block)
 					sector_t block)
 {
 {
-	ide_startstop_t action;
 	struct cdrom_info *info = drive->driver_data;
 	struct cdrom_info *info = drive->driver_data;
+	ide_handler_t *fn;
+	int xferlen;
 
 
 	if (blk_fs_request(rq)) {
 	if (blk_fs_request(rq)) {
 		if (info->cd_flags & IDE_CD_FLAG_SEEKING) {
 		if (info->cd_flags & IDE_CD_FLAG_SEEKING) {
@@ -1240,29 +1215,48 @@ static ide_startstop_t ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq,
 		}
 		}
 		if (rq_data_dir(rq) == READ &&
 		if (rq_data_dir(rq) == READ &&
 		    IDE_LARGE_SEEK(info->last_block, block,
 		    IDE_LARGE_SEEK(info->last_block, block,
-				   IDECD_SEEK_THRESHOLD) &&
-		    drive->dsc_overlap)
-			action = cdrom_start_seek(drive, block);
-		else
-			action = cdrom_start_rw(drive, rq);
+			    IDECD_SEEK_THRESHOLD) &&
+		    drive->dsc_overlap) {
+			xferlen = 0;
+			fn = cdrom_start_seek_continuation;
+
+			info->dma = 0;
+			info->start_seek = jiffies;
+
+			ide_cd_prepare_seek_request(drive, rq);
+		} else {
+			xferlen = 32768;
+			fn = cdrom_start_rw_cont;
+
+			if (cdrom_start_rw(drive, rq) == ide_stopped)
+				return ide_stopped;
+
+			if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
+				return ide_stopped;
+		}
 		info->last_block = block;
 		info->last_block = block;
-		return action;
 	} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
 	} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
 		   rq->cmd_type == REQ_TYPE_ATA_PC) {
 		   rq->cmd_type == REQ_TYPE_ATA_PC) {
-		return cdrom_do_block_pc(drive, rq);
+		xferlen = rq->data_len;
+		fn = cdrom_do_newpc_cont;
+
+		if (!rq->timeout)
+			rq->timeout = ATAPI_WAIT_PC;
+
+		cdrom_do_block_pc(drive, rq);
 	} else if (blk_special_request(rq)) {
 	} else if (blk_special_request(rq)) {
 		/* right now this can only be a reset... */
 		/* right now this can only be a reset... */
 		cdrom_end_request(drive, 1);
 		cdrom_end_request(drive, 1);
 		return ide_stopped;
 		return ide_stopped;
+	} else {
+		blk_dump_rq_flags(rq, "ide-cd bad flags");
+		cdrom_end_request(drive, 0);
+		return ide_stopped;
 	}
 	}
 
 
-	blk_dump_rq_flags(rq, "ide-cd bad flags");
-	cdrom_end_request(drive, 0);
-	return ide_stopped;
+	return cdrom_start_packet_command(drive, xferlen, fn);
 }
 }
 
 
-
-
 /*
 /*
  * Ioctl handling.
  * Ioctl handling.
  *
  *
@@ -1872,6 +1866,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
 
 
 	blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
 	blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
 	blk_queue_dma_alignment(drive->queue, 31);
 	blk_queue_dma_alignment(drive->queue, 31);
+	blk_queue_update_dma_pad(drive->queue, 15);
 	drive->queue->unplug_delay = (1 * HZ) / 1000;
 	drive->queue->unplug_delay = (1 * HZ) / 1000;
 	if (!drive->queue->unplug_delay)
 	if (!drive->queue->unplug_delay)
 		drive->queue->unplug_delay = 1;
 		drive->queue->unplug_delay = 1;
@@ -1954,10 +1949,9 @@ static ide_driver_t ide_cdrom_driver = {
 	.version		= IDECD_VERSION,
 	.version		= IDECD_VERSION,
 	.media			= ide_cdrom,
 	.media			= ide_cdrom,
 	.supports_dsc_overlap	= 1,
 	.supports_dsc_overlap	= 1,
-	.do_request		= ide_do_rw_cdrom,
+	.do_request		= ide_cd_do_request,
 	.end_request		= ide_end_request,
 	.end_request		= ide_end_request,
 	.error			= __ide_error,
 	.error			= __ide_error,
-	.abort			= __ide_abort,
 #ifdef CONFIG_IDE_PROC_FS
 #ifdef CONFIG_IDE_PROC_FS
 	.proc			= idecd_proc,
 	.proc			= idecd_proc,
 #endif
 #endif

+ 0 - 1
drivers/ide/ide-disk.c

@@ -985,7 +985,6 @@ static ide_driver_t idedisk_driver = {
 	.do_request		= ide_do_rw_disk,
 	.do_request		= ide_do_rw_disk,
 	.end_request		= ide_end_request,
 	.end_request		= ide_end_request,
 	.error			= __ide_error,
 	.error			= __ide_error,
-	.abort			= __ide_abort,
 #ifdef CONFIG_IDE_PROC_FS
 #ifdef CONFIG_IDE_PROC_FS
 	.proc			= idedisk_proc,
 	.proc			= idedisk_proc,
 #endif
 #endif

+ 12 - 20
drivers/ide/ide-floppy.c

@@ -351,10 +351,7 @@ static void ide_floppy_callback(ide_drive_t *drive)
 
 
 static void idefloppy_init_pc(struct ide_atapi_pc *pc)
 static void idefloppy_init_pc(struct ide_atapi_pc *pc)
 {
 {
-	memset(pc->c, 0, 12);
-	pc->retries = 0;
-	pc->flags = 0;
-	pc->req_xfer = 0;
+	memset(pc, 0, sizeof(*pc));
 	pc->buf = pc->pc_buf;
 	pc->buf = pc->pc_buf;
 	pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE;
 	pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE;
 	pc->callback = ide_floppy_callback;
 	pc->callback = ide_floppy_callback;
@@ -561,12 +558,6 @@ static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start)
 	pc->c[4] = start;
 	pc->c[4] = start;
 }
 }
 
 
-static void idefloppy_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
-{
-	idefloppy_init_pc(pc);
-	pc->c[0] = GPCMD_TEST_UNIT_READY;
-}
-
 static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
 static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
 				    struct ide_atapi_pc *pc, struct request *rq,
 				    struct ide_atapi_pc *pc, struct request *rq,
 				    unsigned long sector)
 				    unsigned long sector)
@@ -711,10 +702,10 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
 	set_disk_ro(floppy->disk, floppy->wp);
 	set_disk_ro(floppy->disk, floppy->wp);
 	page = &pc.buf[8];
 	page = &pc.buf[8];
 
 
-	transfer_rate = be16_to_cpu(*(u16 *)&pc.buf[8 + 2]);
-	sector_size   = be16_to_cpu(*(u16 *)&pc.buf[8 + 6]);
-	cyls          = be16_to_cpu(*(u16 *)&pc.buf[8 + 8]);
-	rpm           = be16_to_cpu(*(u16 *)&pc.buf[8 + 28]);
+	transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]);
+	sector_size   = be16_to_cpup((__be16 *)&pc.buf[8 + 6]);
+	cyls          = be16_to_cpup((__be16 *)&pc.buf[8 + 8]);
+	rpm           = be16_to_cpup((__be16 *)&pc.buf[8 + 28]);
 	heads         = pc.buf[8 + 4];
 	heads         = pc.buf[8 + 4];
 	sectors       = pc.buf[8 + 5];
 	sectors       = pc.buf[8 + 5];
 
 
@@ -789,8 +780,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
 	for (i = 0; i < desc_cnt; i++) {
 	for (i = 0; i < desc_cnt; i++) {
 		unsigned int desc_start = 4 + i*8;
 		unsigned int desc_start = 4 + i*8;
 
 
-		blocks = be32_to_cpu(*(u32 *)&pc.buf[desc_start]);
-		length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]);
+		blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);
+		length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
 
 
 		debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n",
 		debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n",
 				i, blocks * length / 1024, blocks, length);
 				i, blocks * length / 1024, blocks, length);
@@ -911,8 +902,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
 		if (u_index >= u_array_size)
 		if (u_index >= u_array_size)
 			break;	/* User-supplied buffer too small */
 			break;	/* User-supplied buffer too small */
 
 
-		blocks = be32_to_cpu(*(u32 *)&pc.buf[desc_start]);
-		length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]);
+		blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);
+		length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
 
 
 		if (put_user(blocks, argp))
 		if (put_user(blocks, argp))
 			return(-EFAULT);
 			return(-EFAULT);
@@ -1138,7 +1129,6 @@ static ide_driver_t idefloppy_driver = {
 	.do_request		= idefloppy_do_request,
 	.do_request		= idefloppy_do_request,
 	.end_request		= idefloppy_end_request,
 	.end_request		= idefloppy_end_request,
 	.error			= __ide_error,
 	.error			= __ide_error,
-	.abort			= __ide_abort,
 #ifdef CONFIG_IDE_PROC_FS
 #ifdef CONFIG_IDE_PROC_FS
 	.proc			= idefloppy_proc,
 	.proc			= idefloppy_proc,
 #endif
 #endif
@@ -1166,7 +1156,9 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
 		floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
 		floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
 		/* Just in case */
 		/* Just in case */
 
 
-		idefloppy_create_test_unit_ready_cmd(&pc);
+		idefloppy_init_pc(&pc);
+		pc.c[0] = GPCMD_TEST_UNIT_READY;
+
 		if (idefloppy_queue_pc_tail(drive, &pc)) {
 		if (idefloppy_queue_pc_tail(drive, &pc)) {
 			idefloppy_create_start_stop_cmd(&pc, 1);
 			idefloppy_create_start_stop_cmd(&pc, 1);
 			(void) idefloppy_queue_pc_tail(drive, &pc);
 			(void) idefloppy_queue_pc_tail(drive, &pc);

+ 22 - 50
drivers/ide/ide-io.c

@@ -504,55 +504,6 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
 
 
 EXPORT_SYMBOL_GPL(ide_error);
 EXPORT_SYMBOL_GPL(ide_error);
 
 
-ide_startstop_t __ide_abort(ide_drive_t *drive, struct request *rq)
-{
-	if (drive->media != ide_disk)
-		rq->errors |= ERROR_RESET;
-
-	ide_kill_rq(drive, rq);
-
-	return ide_stopped;
-}
-
-EXPORT_SYMBOL_GPL(__ide_abort);
-
-/**
- *	ide_abort	-	abort pending IDE operations
- *	@drive: drive the error occurred on
- *	@msg: message to report
- *
- *	ide_abort kills and cleans up when we are about to do a 
- *	host initiated reset on active commands. Longer term we
- *	want handlers to have sensible abort handling themselves
- *
- *	This differs fundamentally from ide_error because in 
- *	this case the command is doing just fine when we
- *	blow it away.
- */
- 
-ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
-{
-	struct request *rq;
-
-	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
-		return ide_stopped;
-
-	/* retry only "normal" I/O: */
-	if (!blk_fs_request(rq)) {
-		rq->errors = 1;
-		ide_end_drive_cmd(drive, BUSY_STAT, 0);
-		return ide_stopped;
-	}
-
-	if (rq->rq_disk) {
-		ide_driver_t *drv;
-
-		drv = *(ide_driver_t **)rq->rq_disk->private_data;
-		return drv->abort(drive, rq);
-	} else
-		return __ide_abort(drive, rq);
-}
-
 static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
 static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
 {
 {
 	tf->nsect   = drive->sect;
 	tf->nsect   = drive->sect;
@@ -766,6 +717,18 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
  	return ide_stopped;
  	return ide_stopped;
 }
 }
 
 
+static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
+{
+	switch (rq->cmd[0]) {
+	case REQ_DRIVE_RESET:
+		return ide_do_reset(drive);
+	default:
+		blk_dump_rq_flags(rq, "ide_special_rq - bad request");
+		ide_end_request(drive, 0, 0);
+		return ide_stopped;
+	}
+}
+
 static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
 static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
 {
 {
 	struct request_pm_state *pm = rq->data;
 	struct request_pm_state *pm = rq->data;
@@ -869,7 +832,16 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
 			    pm->pm_step == ide_pm_state_completed)
 			    pm->pm_step == ide_pm_state_completed)
 				ide_complete_pm_request(drive, rq);
 				ide_complete_pm_request(drive, rq);
 			return startstop;
 			return startstop;
-		}
+		} else if (!rq->rq_disk && blk_special_request(rq))
+			/*
+			 * TODO: Once all ULDs have been modified to
+			 * check for specific op codes rather than
+			 * blindly accepting any special request, the
+			 * check for ->rq_disk above may be replaced
+			 * by a more suitable mechanism or even
+			 * dropped entirely.
+			 */
+			return ide_special_rq(drive, rq);
 
 
 		drv = *(ide_driver_t **)rq->rq_disk->private_data;
 		drv = *(ide_driver_t **)rq->rq_disk->private_data;
 		return drv->do_request(drive, rq, block);
 		return drv->do_request(drive, rq, block);

+ 18 - 6
drivers/ide/ide-iops.c

@@ -905,6 +905,14 @@ void ide_execute_pkt_cmd(ide_drive_t *drive)
 }
 }
 EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
 EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
 
 
+static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
+{
+	struct request *rq = drive->hwif->hwgroup->rq;
+
+	if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
+		ide_end_request(drive, err ? err : 1, 0);
+}
+
 /* needed below */
 /* needed below */
 static ide_startstop_t do_reset1 (ide_drive_t *, int);
 static ide_startstop_t do_reset1 (ide_drive_t *, int);
 
 
@@ -940,7 +948,7 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
 	}
 	}
 	/* done polling */
 	/* done polling */
 	hwgroup->polling = 0;
 	hwgroup->polling = 0;
-	hwgroup->resetting = 0;
+	ide_complete_drive_reset(drive, 0);
 	return ide_stopped;
 	return ide_stopped;
 }
 }
 
 
@@ -956,12 +964,14 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
 	ide_hwif_t *hwif	= HWIF(drive);
 	ide_hwif_t *hwif	= HWIF(drive);
 	const struct ide_port_ops *port_ops = hwif->port_ops;
 	const struct ide_port_ops *port_ops = hwif->port_ops;
 	u8 tmp;
 	u8 tmp;
+	int err = 0;
 
 
 	if (port_ops && port_ops->reset_poll) {
 	if (port_ops && port_ops->reset_poll) {
-		if (port_ops->reset_poll(drive)) {
+		err = port_ops->reset_poll(drive);
+		if (err) {
 			printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
 			printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
 				hwif->name, drive->name);
 				hwif->name, drive->name);
-			return ide_stopped;
+			goto out;
 		}
 		}
 	}
 	}
 
 
@@ -975,6 +985,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
 		}
 		}
 		printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
 		printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
 		drive->failures++;
 		drive->failures++;
+		err = -EIO;
 	} else  {
 	} else  {
 		printk("%s: reset: ", hwif->name);
 		printk("%s: reset: ", hwif->name);
 		tmp = ide_read_error(drive);
 		tmp = ide_read_error(drive);
@@ -1001,10 +1012,12 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
 			if (tmp & 0x80)
 			if (tmp & 0x80)
 				printk("; slave: failed");
 				printk("; slave: failed");
 			printk("\n");
 			printk("\n");
+			err = -EIO;
 		}
 		}
 	}
 	}
+out:
 	hwgroup->polling = 0;	/* done polling */
 	hwgroup->polling = 0;	/* done polling */
-	hwgroup->resetting = 0; /* done reset attempt */
+	ide_complete_drive_reset(drive, err);
 	return ide_stopped;
 	return ide_stopped;
 }
 }
 
 
@@ -1090,7 +1103,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
 
 
 	/* For an ATAPI device, first try an ATAPI SRST. */
 	/* For an ATAPI device, first try an ATAPI SRST. */
 	if (drive->media != ide_disk && !do_not_try_atapi) {
 	if (drive->media != ide_disk && !do_not_try_atapi) {
-		hwgroup->resetting = 1;
 		pre_reset(drive);
 		pre_reset(drive);
 		SELECT_DRIVE(drive);
 		SELECT_DRIVE(drive);
 		udelay (20);
 		udelay (20);
@@ -1112,10 +1124,10 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
 
 
 	if (io_ports->ctl_addr == 0) {
 	if (io_ports->ctl_addr == 0) {
 		spin_unlock_irqrestore(&ide_lock, flags);
 		spin_unlock_irqrestore(&ide_lock, flags);
+		ide_complete_drive_reset(drive, -ENXIO);
 		return ide_stopped;
 		return ide_stopped;
 	}
 	}
 
 
-	hwgroup->resetting = 1;
 	/*
 	/*
 	 * Note that we also set nIEN while resetting the device,
 	 * Note that we also set nIEN while resetting the device,
 	 * to mask unwanted interrupts from the interface during the reset.
 	 * to mask unwanted interrupts from the interface during the reset.

+ 0 - 151
drivers/ide/ide-lib.c

@@ -1,26 +1,11 @@
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
-#include <linux/major.h>
-#include <linux/errno.h>
-#include <linux/genhd.h>
-#include <linux/blkpg.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
 #include <linux/hdreg.h>
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 
 
-#include <asm/byteorder.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
 static const char *udma_str[] =
 static const char *udma_str[] =
 	 { "UDMA/16", "UDMA/25",  "UDMA/33",  "UDMA/44",
 	 { "UDMA/16", "UDMA/25",  "UDMA/33",  "UDMA/44",
 	   "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
 	   "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
@@ -90,142 +75,6 @@ static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
 	return min(speed, mode);
 	return min(speed, mode);
 }
 }
 
 
-/*
- * Standard (generic) timings for PIO modes, from ATA2 specification.
- * These timings are for access to the IDE data port register *only*.
- * Some drives may specify a mode, while also specifying a different
- * value for cycle_time (from drive identification data).
- */
-const ide_pio_timings_t ide_pio_timings[6] = {
-	{ 70,	165,	600 },	/* PIO Mode 0 */
-	{ 50,	125,	383 },	/* PIO Mode 1 */
-	{ 30,	100,	240 },	/* PIO Mode 2 */
-	{ 30,	80,	180 },	/* PIO Mode 3 with IORDY */
-	{ 25,	70,	120 },	/* PIO Mode 4 with IORDY */
-	{ 20,	50,	100 }	/* PIO Mode 5 with IORDY (nonstandard) */
-};
-
-EXPORT_SYMBOL_GPL(ide_pio_timings);
-
-/*
- * Shared data/functions for determining best PIO mode for an IDE drive.
- * Most of this stuff originally lived in cmd640.c, and changes to the
- * ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid
- * breaking the fragile cmd640.c support.
- */
-
-/*
- * Black list. Some drives incorrectly report their maximal PIO mode,
- * at least in respect to CMD640. Here we keep info on some known drives.
- */
-static struct ide_pio_info {
-	const char	*name;
-	int		pio;
-} ide_pio_blacklist [] = {
-	{ "Conner Peripherals 540MB - CFS540A", 3 },
-
-	{ "WDC AC2700",  3 },
-	{ "WDC AC2540",  3 },
-	{ "WDC AC2420",  3 },
-	{ "WDC AC2340",  3 },
-	{ "WDC AC2250",  0 },
-	{ "WDC AC2200",  0 },
-	{ "WDC AC21200", 4 },
-	{ "WDC AC2120",  0 },
-	{ "WDC AC2850",  3 },
-	{ "WDC AC1270",  3 },
-	{ "WDC AC1170",  1 },
-	{ "WDC AC1210",  1 },
-	{ "WDC AC280",   0 },
-	{ "WDC AC31000", 3 },
-	{ "WDC AC31200", 3 },
-
-	{ "Maxtor 7131 AT", 1 },
-	{ "Maxtor 7171 AT", 1 },
-	{ "Maxtor 7213 AT", 1 },
-	{ "Maxtor 7245 AT", 1 },
-	{ "Maxtor 7345 AT", 1 },
-	{ "Maxtor 7546 AT", 3 },
-	{ "Maxtor 7540 AV", 3 },
-
-	{ "SAMSUNG SHD-3121A", 1 },
-	{ "SAMSUNG SHD-3122A", 1 },
-	{ "SAMSUNG SHD-3172A", 1 },
-
-	{ "ST5660A",  3 },
-	{ "ST3660A",  3 },
-	{ "ST3630A",  3 },
-	{ "ST3655A",  3 },
-	{ "ST3391A",  3 },
-	{ "ST3390A",  1 },
-	{ "ST3600A",  1 },
-	{ "ST3290A",  0 },
-	{ "ST3144A",  0 },
-	{ "ST3491A",  1 },	/* reports 3, should be 1 or 2 (depending on */	
-				/* drive) according to Seagates FIND-ATA program */
-
-	{ "QUANTUM ELS127A", 0 },
-	{ "QUANTUM ELS170A", 0 },
-	{ "QUANTUM LPS240A", 0 },
-	{ "QUANTUM LPS210A", 3 },
-	{ "QUANTUM LPS270A", 3 },
-	{ "QUANTUM LPS365A", 3 },
-	{ "QUANTUM LPS540A", 3 },
-	{ "QUANTUM LIGHTNING 540A", 3 },
-	{ "QUANTUM LIGHTNING 730A", 3 },
-
-        { "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
-        { "QUANTUM FIREBALL_640", 3 }, 
-        { "QUANTUM FIREBALL_1080", 3 },
-        { "QUANTUM FIREBALL_1280", 3 },
-	{ NULL,	0 }
-};
-
-/**
- *	ide_scan_pio_blacklist 	-	check for a blacklisted drive
- *	@model: Drive model string
- *
- *	This routine searches the ide_pio_blacklist for an entry
- *	matching the start/whole of the supplied model name.
- *
- *	Returns -1 if no match found.
- *	Otherwise returns the recommended PIO mode from ide_pio_blacklist[].
- */
-
-static int ide_scan_pio_blacklist (char *model)
-{
-	struct ide_pio_info *p;
-
-	for (p = ide_pio_blacklist; p->name != NULL; p++) {
-		if (strncmp(p->name, model, strlen(p->name)) == 0)
-			return p->pio;
-	}
-	return -1;
-}
-
-unsigned int ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
-{
-	struct hd_driveid *id = drive->id;
-	int cycle_time = 0;
-
-	if (id->field_valid & 2) {
-		if (id->capability & 8)
-			cycle_time = id->eide_pio_iordy;
-		else
-			cycle_time = id->eide_pio;
-	}
-
-	/* conservative "downgrade" for all pre-ATA2 drives */
-	if (pio < 3) {
-		if (cycle_time && cycle_time < ide_pio_timings[pio].cycle_time)
-			cycle_time = 0; /* use standard timing */
-	}
-
-	return cycle_time ? cycle_time : ide_pio_timings[pio].cycle_time;
-}
-
-EXPORT_SYMBOL_GPL(ide_pio_cycle_time);
-
 /**
 /**
  *	ide_get_best_pio_mode	-	get PIO mode from drive
  *	ide_get_best_pio_mode	-	get PIO mode from drive
  *	@drive: drive to consider
  *	@drive: drive to consider

+ 94 - 0
drivers/ide/ide-pio-blacklist.c

@@ -0,0 +1,94 @@
+/*
+ * PIO blacklist.  Some drives incorrectly report their maximal PIO mode,
+ * at least in respect to CMD640.  Here we keep info on some known drives.
+ *
+ * Changes to the ide_pio_blacklist[] should be made with EXTREME CAUTION
+ * to avoid breaking the fragile cmd640.c support.
+ */
+
+#include <linux/string.h>
+
+static struct ide_pio_info {
+	const char	*name;
+	int		pio;
+} ide_pio_blacklist [] = {
+	{ "Conner Peripherals 540MB - CFS540A", 3 },
+
+	{ "WDC AC2700",  3 },
+	{ "WDC AC2540",  3 },
+	{ "WDC AC2420",  3 },
+	{ "WDC AC2340",  3 },
+	{ "WDC AC2250",  0 },
+	{ "WDC AC2200",  0 },
+	{ "WDC AC21200", 4 },
+	{ "WDC AC2120",  0 },
+	{ "WDC AC2850",  3 },
+	{ "WDC AC1270",  3 },
+	{ "WDC AC1170",  1 },
+	{ "WDC AC1210",  1 },
+	{ "WDC AC280",   0 },
+	{ "WDC AC31000", 3 },
+	{ "WDC AC31200", 3 },
+
+	{ "Maxtor 7131 AT", 1 },
+	{ "Maxtor 7171 AT", 1 },
+	{ "Maxtor 7213 AT", 1 },
+	{ "Maxtor 7245 AT", 1 },
+	{ "Maxtor 7345 AT", 1 },
+	{ "Maxtor 7546 AT", 3 },
+	{ "Maxtor 7540 AV", 3 },
+
+	{ "SAMSUNG SHD-3121A", 1 },
+	{ "SAMSUNG SHD-3122A", 1 },
+	{ "SAMSUNG SHD-3172A", 1 },
+
+	{ "ST5660A",  3 },
+	{ "ST3660A",  3 },
+	{ "ST3630A",  3 },
+	{ "ST3655A",  3 },
+	{ "ST3391A",  3 },
+	{ "ST3390A",  1 },
+	{ "ST3600A",  1 },
+	{ "ST3290A",  0 },
+	{ "ST3144A",  0 },
+	{ "ST3491A",  1 }, /* reports 3, should be 1 or 2 (depending on drive)
+			      according to Seagate's FIND-ATA program */
+
+	{ "QUANTUM ELS127A", 0 },
+	{ "QUANTUM ELS170A", 0 },
+	{ "QUANTUM LPS240A", 0 },
+	{ "QUANTUM LPS210A", 3 },
+	{ "QUANTUM LPS270A", 3 },
+	{ "QUANTUM LPS365A", 3 },
+	{ "QUANTUM LPS540A", 3 },
+	{ "QUANTUM LIGHTNING 540A", 3 },
+	{ "QUANTUM LIGHTNING 730A", 3 },
+
+	{ "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
+	{ "QUANTUM FIREBALL_640", 3 },
+	{ "QUANTUM FIREBALL_1080", 3 },
+	{ "QUANTUM FIREBALL_1280", 3 },
+	{ NULL, 0 }
+};
+
+/**
+ *	ide_scan_pio_blacklist 	-	check for a blacklisted drive
+ *	@model: Drive model string
+ *
+ *	This routine searches the ide_pio_blacklist for an entry
+ *	matching the start/whole of the supplied model name.
+ *
+ *	Returns -1 if no match found.
+ *	Otherwise returns the recommended PIO mode from ide_pio_blacklist[].
+ */
+
+int ide_scan_pio_blacklist(char *model)
+{
+	struct ide_pio_info *p;
+
+	for (p = ide_pio_blacklist; p->name != NULL; p++) {
+		if (strncmp(p->name, model, strlen(p->name)) == 0)
+			return p->pio;
+	}
+	return -1;
+}

+ 2 - 2
drivers/ide/ide-pnp.c

@@ -33,6 +33,8 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 	ide_hwif_t *hwif;
 	ide_hwif_t *hwif;
 	unsigned long base, ctl;
 	unsigned long base, ctl;
 
 
+	printk(KERN_INFO DRV_NAME ": generic PnP IDE interface\n");
+
 	if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0)))
 	if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0)))
 		return -1;
 		return -1;
 
 
@@ -62,10 +64,8 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 		u8 index = hwif->index;
 		u8 index = hwif->index;
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
 
 
-		ide_init_port_data(hwif, index);
 		ide_init_port_hw(hwif, &hw);
 		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);
 		ide_device_add(idx, NULL);

+ 15 - 6
drivers/ide/ide-probe.c

@@ -39,6 +39,8 @@
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/io.h>
 
 
+static ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
+
 /**
 /**
  *	generic_id		-	add a generic drive id
  *	generic_id		-	add a generic drive id
  *	@drive:	drive to make an ID block for
  *	@drive:	drive to make an ID block for
@@ -1318,10 +1320,10 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
 			drive->unmask = 1;
 			drive->unmask = 1;
 		if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
 		if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
 			drive->no_unmask = 1;
 			drive->no_unmask = 1;
-	}
 
 
-	if (port_ops && port_ops->port_init_devs)
-		port_ops->port_init_devs(hwif);
+		if (port_ops && port_ops->init_dev)
+			port_ops->init_dev(drive);
+	}
 }
 }
 
 
 static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
 static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
@@ -1473,22 +1475,29 @@ ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d)
 		for (; i < MAX_HWIFS; i++) {
 		for (; i < MAX_HWIFS; i++) {
 			hwif = &ide_hwifs[i];
 			hwif = &ide_hwifs[i];
 			if (hwif->chipset == ide_unknown)
 			if (hwif->chipset == ide_unknown)
-				return hwif;
+				goto out_found;
 		}
 		}
 	} else {
 	} else {
 		for (i = 2; i < MAX_HWIFS; i++) {
 		for (i = 2; i < MAX_HWIFS; i++) {
 			hwif = &ide_hwifs[i];
 			hwif = &ide_hwifs[i];
 			if (hwif->chipset == ide_unknown)
 			if (hwif->chipset == ide_unknown)
-				return hwif;
+				goto out_found;
 		}
 		}
 		for (i = 0; i < 2 && i < MAX_HWIFS; i++) {
 		for (i = 0; i < 2 && i < MAX_HWIFS; i++) {
 			hwif = &ide_hwifs[i];
 			hwif = &ide_hwifs[i];
 			if (hwif->chipset == ide_unknown)
 			if (hwif->chipset == ide_unknown)
-				return hwif;
+				goto out_found;
 		}
 		}
 	}
 	}
 
 
+	printk(KERN_ERR "%s: no free slot for interface\n",
+			d ? d->name : "ide");
+
 	return NULL;
 	return NULL;
+
+out_found:
+	ide_init_port_data(hwif, i);
+	return hwif;
 }
 }
 EXPORT_SYMBOL_GPL(ide_find_port_slot);
 EXPORT_SYMBOL_GPL(ide_find_port_slot);
 
 

+ 0 - 1
drivers/ide/ide-tape.c

@@ -2591,7 +2591,6 @@ static ide_driver_t idetape_driver = {
 	.do_request		= idetape_do_request,
 	.do_request		= idetape_do_request,
 	.end_request		= idetape_end_request,
 	.end_request		= idetape_end_request,
 	.error			= __ide_error,
 	.error			= __ide_error,
-	.abort			= __ide_abort,
 #ifdef CONFIG_IDE_PROC_FS
 #ifdef CONFIG_IDE_PROC_FS
 	.proc			= idetape_proc,
 	.proc			= idetape_proc,
 #endif
 #endif

+ 1 - 32
drivers/ide/ide-taskfile.c

@@ -8,28 +8,18 @@
  *  The big the bad and the ugly.
  *  The big the bad and the ugly.
  */
  */
 
 
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
-#include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
-#include <linux/genhd.h>
-#include <linux/blkpg.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/hdreg.h>
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
-#include <linux/bitops.h>
 #include <linux/scatterlist.h>
 #include <linux/scatterlist.h>
 
 
-#include <asm/byteorder.h>
-#include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/io.h>
 
 
@@ -62,25 +52,6 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
 	return ide_raw_taskfile(drive, &args, buf, 1);
 	return ide_raw_taskfile(drive, &args, buf, 1);
 }
 }
 
 
-static int inline task_dma_ok(ide_task_t *task)
-{
-	if (blk_fs_request(task->rq) || (task->tf_flags & IDE_TFLAG_FLAGGED))
-		return 1;
-
-	switch (task->tf.command) {
-		case WIN_WRITEDMA_ONCE:
-		case WIN_WRITEDMA:
-		case WIN_WRITEDMA_EXT:
-		case WIN_READDMA_ONCE:
-		case WIN_READDMA:
-		case WIN_READDMA_EXT:
-		case WIN_IDENTIFY_DMA:
-			return 1;
-	}
-
-	return 0;
-}
-
 static ide_startstop_t task_no_data_intr(ide_drive_t *);
 static ide_startstop_t task_no_data_intr(ide_drive_t *);
 static ide_startstop_t set_geometry_intr(ide_drive_t *);
 static ide_startstop_t set_geometry_intr(ide_drive_t *);
 static ide_startstop_t recal_intr(ide_drive_t *);
 static ide_startstop_t recal_intr(ide_drive_t *);
@@ -139,8 +110,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
 				    WAIT_WORSTCASE, NULL);
 				    WAIT_WORSTCASE, NULL);
 		return ide_started;
 		return ide_started;
 	default:
 	default:
-		if (task_dma_ok(task) == 0 || drive->using_dma == 0 ||
-		    dma_ops->dma_setup(drive))
+		if (drive->using_dma == 0 || dma_ops->dma_setup(drive))
 			return ide_stopped;
 			return ide_stopped;
 		dma_ops->dma_exec_cmd(drive, tf->command);
 		dma_ops->dma_exec_cmd(drive, tf->command);
 		dma_ops->dma_start(drive);
 		dma_ops->dma_start(drive);
@@ -183,7 +153,6 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
 	if (stat & (ERR_STAT|DRQ_STAT))
 	if (stat & (ERR_STAT|DRQ_STAT))
 		return ide_error(drive, "set_geometry_intr", stat);
 		return ide_error(drive, "set_geometry_intr", stat);
 
 
-	BUG_ON(HWGROUP(drive)->handler != NULL);
 	ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL);
 	ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL);
 	return ide_started;
 	return ide_started;
 }
 }

+ 96 - 108
drivers/ide/ide-timing.h → drivers/ide/ide-timings.c

@@ -1,11 +1,7 @@
-#ifndef _IDE_TIMING_H
-#define _IDE_TIMING_H
-
 /*
 /*
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *  Copyright (c) 1999-2001 Vojtech Pavlik
- */
-
-/*
+ *  Copyright (c) 2007-2008 Bartlomiej Zolnierkiewicz
+ *
  * This program is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * the Free Software Foundation; either version 2 of the License, or
@@ -27,27 +23,14 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/hdreg.h>
 #include <linux/hdreg.h>
-
-#define XFER_PIO_5		0x0d
-#define XFER_UDMA_SLOW		0x4f
-
-struct ide_timing {
-	short mode;
-	short setup;	/* t1 */
-	short act8b;	/* t2 for 8-bit io */
-	short rec8b;	/* t2i for 8-bit io */
-	short cyc8b;	/* t0 for 8-bit io */
-	short active;	/* t2 or tD */
-	short recover;	/* t2i or tK */
-	short cycle;	/* t0 */
-	short udma;	/* t2CYCTYP/2 */
-};
+#include <linux/ide.h>
+#include <linux/module.h>
 
 
 /*
 /*
  * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
  * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds).
  * These were taken from ATA/ATAPI-6 standard, rev 0a, except
  * These were taken from ATA/ATAPI-6 standard, rev 0a, except
  * for PIO 5, which is a nonstandard extension and UDMA6, which
  * for PIO 5, which is a nonstandard extension and UDMA6, which
- * is currently supported only by Maxtor drives. 
+ * is currently supported only by Maxtor drives.
  */
  */
 
 
 static struct ide_timing ide_timing[] = {
 static struct ide_timing ide_timing[] = {
@@ -61,12 +44,10 @@ static struct ide_timing ide_timing[] = {
 	{ XFER_UDMA_1,     0,   0,   0,   0,   0,   0,   0,  80 },
 	{ XFER_UDMA_1,     0,   0,   0,   0,   0,   0,   0,  80 },
 	{ XFER_UDMA_0,     0,   0,   0,   0,   0,   0,   0, 120 },
 	{ XFER_UDMA_0,     0,   0,   0,   0,   0,   0,   0, 120 },
 
 
-	{ XFER_UDMA_SLOW,  0,   0,   0,   0,   0,   0,   0, 150 },
-                                          
 	{ XFER_MW_DMA_2,  25,   0,   0,   0,  70,  25, 120,   0 },
 	{ XFER_MW_DMA_2,  25,   0,   0,   0,  70,  25, 120,   0 },
 	{ XFER_MW_DMA_1,  45,   0,   0,   0,  80,  50, 150,   0 },
 	{ XFER_MW_DMA_1,  45,   0,   0,   0,  80,  50, 150,   0 },
 	{ XFER_MW_DMA_0,  60,   0,   0,   0, 215, 215, 480,   0 },
 	{ XFER_MW_DMA_0,  60,   0,   0,   0, 215, 215, 480,   0 },
-                                          
+
 	{ XFER_SW_DMA_2,  60,   0,   0,   0, 120, 120, 240,   0 },
 	{ XFER_SW_DMA_2,  60,   0,   0,   0, 120, 120, 240,   0 },
 	{ XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 480,   0 },
 	{ XFER_SW_DMA_1,  90,   0,   0,   0, 240, 240, 480,   0 },
 	{ XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 960,   0 },
 	{ XFER_SW_DMA_0, 120,   0,   0,   0, 480, 480, 960,   0 },
@@ -81,29 +62,46 @@ static struct ide_timing ide_timing[] = {
 
 
 	{ XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960,   0 },
 	{ XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960,   0 },
 
 
-	{ -1 }
+	{ 0xff }
 };
 };
 
 
-#define IDE_TIMING_SETUP	0x01
-#define IDE_TIMING_ACT8B	0x02
-#define IDE_TIMING_REC8B	0x04
-#define IDE_TIMING_CYC8B	0x08
-#define IDE_TIMING_8BIT		0x0e
-#define IDE_TIMING_ACTIVE	0x10
-#define IDE_TIMING_RECOVER	0x20
-#define IDE_TIMING_CYCLE	0x40
-#define IDE_TIMING_UDMA		0x80
-#define IDE_TIMING_ALL		0xff
-
-#define ENOUGH(v,unit)		(((v)-1)/(unit)+1)
-#define EZ(v,unit)		((v)?ENOUGH(v,unit):0)
-
-#define XFER_MODE	0xf0
-#define XFER_MWDMA	0x20
-#define XFER_EPIO	0x01
-#define XFER_PIO	0x00
-
-static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int T, int UT)
+struct ide_timing *ide_timing_find_mode(u8 speed)
+{
+	struct ide_timing *t;
+
+	for (t = ide_timing; t->mode != speed; t++)
+		if (t->mode == 0xff)
+			return NULL;
+	return t;
+}
+EXPORT_SYMBOL_GPL(ide_timing_find_mode);
+
+u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
+{
+	struct hd_driveid *id = drive->id;
+	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
+	u16 cycle = 0;
+
+	if (id->field_valid & 2) {
+		if (id->capability & 8)
+			cycle = id->eide_pio_iordy;
+		else
+			cycle = id->eide_pio;
+
+		/* conservative "downgrade" for all pre-ATA2 drives */
+		if (pio < 3 && cycle < t->cycle)
+			cycle = 0; /* use standard timing */
+	}
+
+	return cycle ? cycle : t->cycle;
+}
+EXPORT_SYMBOL_GPL(ide_pio_cycle_time);
+
+#define ENOUGH(v, unit)		(((v) - 1) / (unit) + 1)
+#define EZ(v, unit)		((v) ? ENOUGH(v, unit) : 0)
+
+static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q,
+				int T, int UT)
 {
 {
 	q->setup   = EZ(t->setup   * 1000,  T);
 	q->setup   = EZ(t->setup   * 1000,  T);
 	q->act8b   = EZ(t->act8b   * 1000,  T);
 	q->act8b   = EZ(t->act8b   * 1000,  T);
@@ -115,92 +113,83 @@ static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q, int
 	q->udma    = EZ(t->udma    * 1000, UT);
 	q->udma    = EZ(t->udma    * 1000, UT);
 }
 }
 
 
-static void ide_timing_merge(struct ide_timing *a, struct ide_timing *b, struct ide_timing *m, unsigned int what)
-{
-	if (what & IDE_TIMING_SETUP  ) m->setup   = max(a->setup,   b->setup);
-	if (what & IDE_TIMING_ACT8B  ) m->act8b   = max(a->act8b,   b->act8b);
-	if (what & IDE_TIMING_REC8B  ) m->rec8b   = max(a->rec8b,   b->rec8b);
-	if (what & IDE_TIMING_CYC8B  ) m->cyc8b   = max(a->cyc8b,   b->cyc8b);
-	if (what & IDE_TIMING_ACTIVE ) m->active  = max(a->active,  b->active);
-	if (what & IDE_TIMING_RECOVER) m->recover = max(a->recover, b->recover);
-	if (what & IDE_TIMING_CYCLE  ) m->cycle   = max(a->cycle,   b->cycle);
-	if (what & IDE_TIMING_UDMA   ) m->udma    = max(a->udma,    b->udma);
-}
-
-static struct ide_timing* ide_timing_find_mode(short speed)
+void ide_timing_merge(struct ide_timing *a, struct ide_timing *b,
+		      struct ide_timing *m, unsigned int what)
 {
 {
-	struct ide_timing *t;
-
-	for (t = ide_timing; t->mode != speed; t++)
-		if (t->mode < 0)
-			return NULL;
-	return t; 
+	if (what & IDE_TIMING_SETUP)
+		m->setup   = max(a->setup,   b->setup);
+	if (what & IDE_TIMING_ACT8B)
+		m->act8b   = max(a->act8b,   b->act8b);
+	if (what & IDE_TIMING_REC8B)
+		m->rec8b   = max(a->rec8b,   b->rec8b);
+	if (what & IDE_TIMING_CYC8B)
+		m->cyc8b   = max(a->cyc8b,   b->cyc8b);
+	if (what & IDE_TIMING_ACTIVE)
+		m->active  = max(a->active,  b->active);
+	if (what & IDE_TIMING_RECOVER)
+		m->recover = max(a->recover, b->recover);
+	if (what & IDE_TIMING_CYCLE)
+		m->cycle   = max(a->cycle,   b->cycle);
+	if (what & IDE_TIMING_UDMA)
+		m->udma    = max(a->udma,    b->udma);
 }
 }
+EXPORT_SYMBOL_GPL(ide_timing_merge);
 
 
-static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing *t, int T, int UT)
+int ide_timing_compute(ide_drive_t *drive, u8 speed,
+		       struct ide_timing *t, int T, int UT)
 {
 {
 	struct hd_driveid *id = drive->id;
 	struct hd_driveid *id = drive->id;
 	struct ide_timing *s, p;
 	struct ide_timing *s, p;
 
 
-/*
- * Find the mode.
- */
-
-	if (!(s = ide_timing_find_mode(speed)))
+	/*
+	 * Find the mode.
+	 */
+	s = ide_timing_find_mode(speed);
+	if (s == NULL)
 		return -EINVAL;
 		return -EINVAL;
 
 
-/*
- * Copy the timing from the table.
- */
-
+	/*
+	 * Copy the timing from the table.
+	 */
 	*t = *s;
 	*t = *s;
 
 
-/*
- * If the drive is an EIDE drive, it can tell us it needs extended
- * PIO/MWDMA cycle timing.
- */
-
+	/*
+	 * If the drive is an EIDE drive, it can tell us it needs extended
+	 * PIO/MWDMA cycle timing.
+	 */
 	if (id && id->field_valid & 2) {	/* EIDE drive */
 	if (id && id->field_valid & 2) {	/* EIDE drive */
 
 
 		memset(&p, 0, sizeof(p));
 		memset(&p, 0, sizeof(p));
 
 
-		switch (speed & XFER_MODE) {
-
-			case XFER_PIO:
-				if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = id->eide_pio;
-						    else p.cycle = p.cyc8b = id->eide_pio_iordy;
-				break;
-
-			case XFER_MWDMA:
-				p.cycle = id->eide_dma_min;
-				break;
-		}
+		if (speed <= XFER_PIO_2)
+			p.cycle = p.cyc8b = id->eide_pio;
+		else if (speed <= XFER_PIO_5)
+			p.cycle = p.cyc8b = id->eide_pio_iordy;
+		else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
+			p.cycle = id->eide_dma_min;
 
 
 		ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B);
 		ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B);
 	}
 	}
 
 
-/*
- * Convert the timing to bus clock counts.
- */
-
+	/*
+	 * Convert the timing to bus clock counts.
+	 */
 	ide_timing_quantize(t, t, T, UT);
 	ide_timing_quantize(t, t, T, UT);
 
 
-/*
- * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
- * and some other commands. We have to ensure that the DMA cycle timing is
- * slower/equal than the fastest PIO timing.
- */
-
-	if ((speed & XFER_MODE) != XFER_PIO) {
+	/*
+	 * Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
+	 * S.M.A.R.T and some other commands. We have to ensure that the
+	 * DMA cycle timing is slower/equal than the fastest PIO timing.
+	 */
+	if (speed >= XFER_SW_DMA_0) {
 		u8 pio = ide_get_best_pio_mode(drive, 255, 5);
 		u8 pio = ide_get_best_pio_mode(drive, 255, 5);
 		ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT);
 		ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT);
 		ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
 		ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
 	}
 	}
 
 
-/*
- * Lengthen active & recovery time so that cycle time is correct.
- */
-
+	/*
+	 * Lengthen active & recovery time so that cycle time is correct.
+	 */
 	if (t->act8b + t->rec8b < t->cyc8b) {
 	if (t->act8b + t->rec8b < t->cyc8b) {
 		t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2;
 		t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2;
 		t->rec8b = t->cyc8b - t->act8b;
 		t->rec8b = t->cyc8b - t->act8b;
@@ -213,5 +202,4 @@ static int ide_timing_compute(ide_drive_t *drive, short speed, struct ide_timing
 
 
 	return 0;
 	return 0;
 }
 }
-
-#endif
+EXPORT_SYMBOL_GPL(ide_timing_compute);

+ 19 - 57
drivers/ide/ide.c

@@ -50,29 +50,16 @@
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/major.h>
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/genhd.h>
 #include <linux/genhd.h>
-#include <linux/blkpg.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
-#include <linux/delay.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
 #include <linux/completion.h>
 #include <linux/completion.h>
-#include <linux/reboot.h>
-#include <linux/cdrom.h>
-#include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/device.h>
-#include <linux/bitops.h>
-
-#include <asm/byteorder.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
 
 
 
 
 /* default maximum number of failures */
 /* default maximum number of failures */
@@ -91,8 +78,6 @@ DEFINE_MUTEX(ide_cfg_mtx);
 __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
 __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock);
 EXPORT_SYMBOL(ide_lock);
 EXPORT_SYMBOL(ide_lock);
 
 
-ide_hwif_t ide_hwifs[MAX_HWIFS];	/* master data repository */
-
 static void ide_port_init_devices_data(ide_hwif_t *);
 static void ide_port_init_devices_data(ide_hwif_t *);
 
 
 /*
 /*
@@ -121,7 +106,6 @@ void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
 
 
 	ide_port_init_devices_data(hwif);
 	ide_port_init_devices_data(hwif);
 }
 }
-EXPORT_SYMBOL_GPL(ide_init_port_data);
 
 
 static void ide_port_init_devices_data(ide_hwif_t *hwif)
 static void ide_port_init_devices_data(ide_hwif_t *hwif)
 {
 {
@@ -150,18 +134,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif)
 	}
 	}
 }
 }
 
 
-static void __init init_ide_data (void)
-{
-	unsigned int index;
-
-	/* Initialise all interface structures */
-	for (index = 0; index < MAX_HWIFS; ++index) {
-		ide_hwif_t *hwif = &ide_hwifs[index];
-
-		ide_init_port_data(hwif, index);
-	}
-}
-
 void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
 void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
 {
 {
 	ide_hwgroup_t *hwgroup = hwif->hwgroup;
 	ide_hwgroup_t *hwgroup = hwif->hwgroup;
@@ -312,7 +284,8 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
 	memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
 	memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
 	hwif->irq = hw->irq;
 	hwif->irq = hw->irq;
 	hwif->chipset = hw->chipset;
 	hwif->chipset = hw->chipset;
-	hwif->gendev.parent = hw->dev;
+	hwif->dev = hw->dev;
+	hwif->gendev.parent = hw->parent ? hw->parent : hw->dev;
 	hwif->ack_intr = hw->ack_intr;
 	hwif->ack_intr = hw->ack_intr;
 }
 }
 EXPORT_SYMBOL_GPL(ide_init_port_hw);
 EXPORT_SYMBOL_GPL(ide_init_port_hw);
@@ -556,6 +529,22 @@ static int generic_ide_resume(struct device *dev)
 	return err;
 	return err;
 }
 }
 
 
+static int generic_drive_reset(ide_drive_t *drive)
+{
+	struct request *rq;
+	int ret = 0;
+
+	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+	rq->cmd_type = REQ_TYPE_SPECIAL;
+	rq->cmd_len = 1;
+	rq->cmd[0] = REQ_DRIVE_RESET;
+	rq->cmd_flags |= REQ_SOFTBARRIER;
+	if (blk_execute_rq(drive->queue, NULL, rq, 1))
+		ret = rq->errors;
+	blk_put_request(rq);
+	return ret;
+}
+
 int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,
 int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,
 			unsigned int cmd, unsigned long arg)
 			unsigned int cmd, unsigned long arg)
 {
 {
@@ -630,33 +619,8 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
 			if (!capable(CAP_SYS_ADMIN))
 			if (!capable(CAP_SYS_ADMIN))
 				return -EACCES;
 				return -EACCES;
 
 
-			/*
-			 *	Abort the current command on the
-			 *	group if there is one, taking
-			 *	care not to allow anything else
-			 *	to be queued and to die on the
-			 *	spot if we miss one somehow
-			 */
-
-			spin_lock_irqsave(&ide_lock, flags);
-
-			if (HWGROUP(drive)->resetting) {
-				spin_unlock_irqrestore(&ide_lock, flags);
-				return -EBUSY;
-			}
+			return generic_drive_reset(drive);
 
 
-			ide_abort(drive, "drive reset");
-
-			BUG_ON(HWGROUP(drive)->handler);
-
-			/* Ensure nothing gets queued after we
-			   drop the lock. Reset will clear the busy */
-
-			HWGROUP(drive)->busy = 1;
-			spin_unlock_irqrestore(&ide_lock, flags);
-			(void) ide_do_reset(drive);
-
-			return 0;
 		case HDIO_GET_BUSSTATE:
 		case HDIO_GET_BUSSTATE:
 			if (!capable(CAP_SYS_ADMIN))
 			if (!capable(CAP_SYS_ADMIN))
 				return -EACCES;
 				return -EACCES;
@@ -1021,8 +985,6 @@ static int __init ide_init(void)
 		goto out_port_class;
 		goto out_port_class;
 	}
 	}
 
 
-	init_ide_data();
-
 	proc_ide_create();
 	proc_ide_create();
 
 
 	return 0;
 	return 0;

+ 2 - 1
drivers/ide/legacy/ali14xx.c

@@ -117,10 +117,11 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	u8 param1, param2, param3, param4;
 	u8 param1, param2, param3, param4;
 	unsigned long flags;
 	unsigned long flags;
 	int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
 	int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
+	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
 
 
 	/* calculate timing, according to PIO mode */
 	/* calculate timing, according to PIO mode */
 	time1 = ide_pio_cycle_time(drive, pio);
 	time1 = ide_pio_cycle_time(drive, pio);
-	time2 = ide_pio_timings[pio].active_time;
+	time2 = t->active;
 	param3 = param1 = (time2 * bus_speed + 999) / 1000;
 	param3 = param1 = (time2 * bus_speed + 999) / 1000;
 	param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1;
 	param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1;
 	if (pio < 3) {
 	if (pio < 3) {

+ 0 - 1
drivers/ide/legacy/buddha.c

@@ -227,7 +227,6 @@ fail_base2:
 			if (hwif) {
 			if (hwif) {
 				u8 index = hwif->index;
 				u8 index = hwif->index;
 
 
-				ide_init_port_data(hwif, index);
 				ide_init_port_hw(hwif, &hw);
 				ide_init_port_hw(hwif, &hw);
 
 
 				idx[i] = index;
 				idx[i] = index;

+ 0 - 1
drivers/ide/legacy/falconide.c

@@ -111,7 +111,6 @@ static int __init falconide_init(void)
 		u8 index = hwif->index;
 		u8 index = hwif->index;
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
 
 
-		ide_init_port_data(hwif, index);
 		ide_init_port_hw(hwif, &hw);
 		ide_init_port_hw(hwif, &hw);
 
 
 		/* Atari has a byte-swapped IDE interface */
 		/* Atari has a byte-swapped IDE interface */

+ 0 - 1
drivers/ide/legacy/gayle.c

@@ -185,7 +185,6 @@ found:
 	if (hwif) {
 	if (hwif) {
 	    u8 index = hwif->index;
 	    u8 index = hwif->index;
 
 
-	    ide_init_port_data(hwif, index);
 	    ide_init_port_hw(hwif, &hw);
 	    ide_init_port_hw(hwif, &hw);
 
 
 	    idx[i] = index;
 	    idx[i] = index;

+ 7 - 8
drivers/ide/legacy/ht6560b.c

@@ -216,6 +216,7 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
 
 
         if (pio) {
         if (pio) {
 		unsigned int cycle_time;
 		unsigned int cycle_time;
+		struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
 
 
 		cycle_time = ide_pio_cycle_time(drive, pio);
 		cycle_time = ide_pio_cycle_time(drive, pio);
 
 
@@ -224,10 +225,8 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
 		 *  actual cycle time for recovery and activity
 		 *  actual cycle time for recovery and activity
 		 *  according system bus speed.
 		 *  according system bus speed.
 		 */
 		 */
-		active_time = ide_pio_timings[pio].active_time;
-		recovery_time = cycle_time
-			- active_time
-			- ide_pio_timings[pio].setup_time;
+		active_time = t->active;
+		recovery_time = cycle_time - active_time - t->setup;
 		/*
 		/*
 		 *  Cycle times should be Vesa bus cycles
 		 *  Cycle times should be Vesa bus cycles
 		 */
 		 */
@@ -311,16 +310,16 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
 #endif
 #endif
 }
 }
 
 
-static void __init ht6560b_port_init_devs(ide_hwif_t *hwif)
+static void __init ht6560b_init_dev(ide_drive_t *drive)
 {
 {
+	ide_hwif_t *hwif = drive->hwif;
 	/* Setting default configurations for drives. */
 	/* Setting default configurations for drives. */
 	int t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT;
 	int t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT;
 
 
 	if (hwif->channel)
 	if (hwif->channel)
 		t |= (HT_SECONDARY_IF << 8);
 		t |= (HT_SECONDARY_IF << 8);
 
 
-	hwif->drives[0].drive_data = t;
-	hwif->drives[1].drive_data = t;
+	drive->drive_data = t;
 }
 }
 
 
 static int probe_ht6560b;
 static int probe_ht6560b;
@@ -329,7 +328,7 @@ module_param_named(probe, probe_ht6560b, bool, 0);
 MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
 MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
 
 
 static const struct ide_port_ops ht6560b_port_ops = {
 static const struct ide_port_ops ht6560b_port_ops = {
-	.port_init_devs		= ht6560b_port_init_devs,
+	.init_dev		= ht6560b_init_dev,
 	.set_pio_mode		= ht6560b_set_pio_mode,
 	.set_pio_mode		= ht6560b_set_pio_mode,
 	.selectproc		= ht6560b_selectproc,
 	.selectproc		= ht6560b_selectproc,
 };
 };

+ 16 - 9
drivers/ide/legacy/ide-4drives.c

@@ -11,6 +11,21 @@ static int probe_4drives;
 module_param_named(probe, probe_4drives, bool, 0);
 module_param_named(probe, probe_4drives, bool, 0);
 MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
 MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
 
 
+static void ide_4drives_init_dev(ide_drive_t *drive)
+{
+	if (drive->hwif->channel)
+		drive->select.all ^= 0x20;
+}
+
+static const struct ide_port_ops ide_4drives_port_ops = {
+	.init_dev		= ide_4drives_init_dev,
+};
+
+static const struct ide_port_info ide_4drives_port_info = {
+	.port_ops		= &ide_4drives_port_ops,
+	.host_flags		= IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+};
+
 static int __init ide_4drives_init(void)
 static int __init ide_4drives_init(void)
 {
 {
 	ide_hwif_t *hwif, *mate;
 	ide_hwif_t *hwif, *mate;
@@ -49,18 +64,10 @@ static int __init ide_4drives_init(void)
 	mate = ide_find_port();
 	mate = ide_find_port();
 	if (mate) {
 	if (mate) {
 		ide_init_port_hw(mate, &hw);
 		ide_init_port_hw(mate, &hw);
-		mate->drives[0].select.all ^= 0x20;
-		mate->drives[1].select.all ^= 0x20;
 		idx[1] = mate->index;
 		idx[1] = mate->index;
-
-		if (hwif) {
-			hwif->mate = mate;
-			mate->mate = hwif;
-			hwif->serialized = mate->serialized = 1;
-		}
 	}
 	}
 
 
-	ide_device_add(idx, NULL);
+	ide_device_add(idx, &ide_4drives_port_info);
 
 
 	return 0;
 	return 0;
 }
 }

+ 6 - 3
drivers/ide/legacy/ide-cs.c

@@ -154,6 +154,11 @@ static const struct ide_port_ops idecs_port_ops = {
 	.quirkproc		= ide_undecoded_slave,
 	.quirkproc		= ide_undecoded_slave,
 };
 };
 
 
+static const struct ide_port_info idecs_port_info = {
+	.port_ops		= &idecs_port_ops,
+	.host_flags		= IDE_HFLAG_NO_DMA,
+};
+
 static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl,
 static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl,
 				unsigned long irq, struct pcmcia_device *handle)
 				unsigned long irq, struct pcmcia_device *handle)
 {
 {
@@ -187,13 +192,11 @@ static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl,
 
 
     i = hwif->index;
     i = hwif->index;
 
 
-    ide_init_port_data(hwif, i);
     ide_init_port_hw(hwif, &hw);
     ide_init_port_hw(hwif, &hw);
-    hwif->port_ops = &idecs_port_ops;
 
 
     idx[0] = i;
     idx[0] = i;
 
 
-    ide_device_add(idx, NULL);
+    ide_device_add(idx, &idecs_port_info);
 
 
     if (hwif->present)
     if (hwif->present)
 	return hwif;
 	return hwif;

+ 7 - 2
drivers/ide/legacy/ide_platform.c

@@ -44,6 +44,10 @@ static void __devinit plat_ide_setup_ports(hw_regs_t *hw,
 	hw->chipset = ide_generic;
 	hw->chipset = ide_generic;
 }
 }
 
 
+static const struct ide_port_info platform_ide_port_info = {
+	.host_flags		= IDE_HFLAG_NO_DMA,
+};
+
 static int __devinit plat_ide_probe(struct platform_device *pdev)
 static int __devinit plat_ide_probe(struct platform_device *pdev)
 {
 {
 	struct resource *res_base, *res_alt, *res_irq;
 	struct resource *res_base, *res_alt, *res_irq;
@@ -54,6 +58,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
 	int ret = 0;
 	int ret = 0;
 	int mmio = 0;
 	int mmio = 0;
 	hw_regs_t hw;
 	hw_regs_t hw;
+	struct ide_port_info d = platform_ide_port_info;
 
 
 	pdata = pdev->dev.platform_data;
 	pdata = pdev->dev.platform_data;
 
 
@@ -102,13 +107,13 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
 	ide_init_port_hw(hwif, &hw);
 	ide_init_port_hw(hwif, &hw);
 
 
 	if (mmio) {
 	if (mmio) {
-		hwif->host_flags = IDE_HFLAG_MMIO;
+		d.host_flags |= IDE_HFLAG_MMIO;
 		default_hwif_mmiops(hwif);
 		default_hwif_mmiops(hwif);
 	}
 	}
 
 
 	idx[0] = hwif->index;
 	idx[0] = hwif->index;
 
 
-	ide_device_add(idx, NULL);
+	ide_device_add(idx, &d);
 
 
 	platform_set_drvdata(pdev, hwif);
 	platform_set_drvdata(pdev, hwif);
 
 

+ 0 - 1
drivers/ide/legacy/macide.c

@@ -130,7 +130,6 @@ static int __init macide_init(void)
 		u8 index = hwif->index;
 		u8 index = hwif->index;
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
 		u8 idx[4] = { index, 0xff, 0xff, 0xff };
 
 
-		ide_init_port_data(hwif, index);
 		ide_init_port_hw(hwif, &hw);
 		ide_init_port_hw(hwif, &hw);
 
 
 		ide_device_add(idx, NULL);
 		ide_device_add(idx, NULL);

+ 0 - 1
drivers/ide/legacy/q40ide.c

@@ -142,7 +142,6 @@ static int __init q40ide_init(void)
 
 
 	hwif = ide_find_port();
 	hwif = ide_find_port();
 	if (hwif) {
 	if (hwif) {
-		ide_init_port_data(hwif, hwif->index);
 		ide_init_port_hw(hwif, &hw);
 		ide_init_port_hw(hwif, &hw);
 
 
 		/* Q40 has a byte-swapped IDE interface */
 		/* Q40 has a byte-swapped IDE interface */

+ 10 - 9
drivers/ide/legacy/qd65xx.c

@@ -207,6 +207,7 @@ 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)
 static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
 {
 	ide_hwif_t *hwif = drive->hwif;
 	ide_hwif_t *hwif = drive->hwif;
+	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
 	unsigned int cycle_time;
 	unsigned int cycle_time;
 	int active_time   = 175;
 	int active_time   = 175;
 	int recovery_time = 415; /* worst case values from the dos driver */
 	int recovery_time = 415; /* worst case values from the dos driver */
@@ -236,7 +237,7 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
 					active_time = 110;
 					active_time = 110;
 					recovery_time = cycle_time - 120;
 					recovery_time = cycle_time - 120;
 				} else {
 				} else {
-					active_time = ide_pio_timings[pio].active_time;
+					active_time = t->active;
 					recovery_time = cycle_time - active_time;
 					recovery_time = cycle_time - active_time;
 				}
 				}
 		}
 		}
@@ -281,17 +282,18 @@ static int __init qd_testreg(int port)
 	return (readreg != QD_TESTVAL);
 	return (readreg != QD_TESTVAL);
 }
 }
 
 
-static void __init qd6500_port_init_devs(ide_hwif_t *hwif)
+static void __init qd6500_init_dev(ide_drive_t *drive)
 {
 {
+	ide_hwif_t *hwif = drive->hwif;
 	u8 base = (hwif->config_data & 0xff00) >> 8;
 	u8 base = (hwif->config_data & 0xff00) >> 8;
 	u8 config = QD_CONFIG(hwif);
 	u8 config = QD_CONFIG(hwif);
 
 
-	hwif->drives[0].drive_data = QD6500_DEF_DATA;
-	hwif->drives[1].drive_data = QD6500_DEF_DATA;
+	drive->drive_data = QD6500_DEF_DATA;
 }
 }
 
 
-static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
+static void __init qd6580_init_dev(ide_drive_t *drive)
 {
 {
+	ide_hwif_t *hwif = drive->hwif;
 	u16 t1, t2;
 	u16 t1, t2;
 	u8 base = (hwif->config_data & 0xff00) >> 8;
 	u8 base = (hwif->config_data & 0xff00) >> 8;
 	u8 config = QD_CONFIG(hwif);
 	u8 config = QD_CONFIG(hwif);
@@ -302,18 +304,17 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
 	} else
 	} else
 		t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA;
 		t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA;
 
 
-	hwif->drives[0].drive_data = t1;
-	hwif->drives[1].drive_data = t2;
+	drive->drive_data = drive->select.b.unit ? t2 : t1;
 }
 }
 
 
 static const struct ide_port_ops qd6500_port_ops = {
 static const struct ide_port_ops qd6500_port_ops = {
-	.port_init_devs		= qd6500_port_init_devs,
+	.init_dev		= qd6500_init_dev,
 	.set_pio_mode		= qd6500_set_pio_mode,
 	.set_pio_mode		= qd6500_set_pio_mode,
 	.selectproc		= qd65xx_select,
 	.selectproc		= qd65xx_select,
 };
 };
 
 
 static const struct ide_port_ops qd6580_port_ops = {
 static const struct ide_port_ops qd6580_port_ops = {
-	.port_init_devs		= qd6580_port_init_devs,
+	.init_dev		= qd6580_init_dev,
 	.set_pio_mode		= qd6580_set_pio_mode,
 	.set_pio_mode		= qd6580_set_pio_mode,
 	.selectproc		= qd65xx_select,
 	.selectproc		= qd65xx_select,
 };
 };

+ 3 - 10
drivers/ide/mips/au1xxx-ide.c

@@ -213,10 +213,8 @@ static int auide_build_dmatable(ide_drive_t *drive)
 {
 {
 	int i, iswrite, count = 0;
 	int i, iswrite, count = 0;
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_hwif_t *hwif = HWIF(drive);
-
 	struct request *rq = HWGROUP(drive)->rq;
 	struct request *rq = HWGROUP(drive)->rq;
-
-	_auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+	_auide_hwif *ahwif = &auide_hwif;
 	struct scatterlist *sg;
 	struct scatterlist *sg;
 
 
 	iswrite = (rq_data_dir(rq) == WRITE);
 	iswrite = (rq_data_dir(rq) == WRITE);
@@ -402,7 +400,7 @@ static const struct ide_dma_ops au1xxx_dma_ops = {
 
 
 static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
 static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
 {
 {
-	_auide_hwif *auide = (_auide_hwif *)hwif->hwif_data;
+	_auide_hwif *auide = &auide_hwif;
 	dbdev_tab_t source_dev_tab, target_dev_tab;
 	dbdev_tab_t source_dev_tab, target_dev_tab;
 	u32 dev_id, tsize, devwidth, flags;
 	u32 dev_id, tsize, devwidth, flags;
 
 
@@ -463,7 +461,7 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
 #else
 #else
 static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
 static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
 {
 {
-	_auide_hwif *auide = (_auide_hwif *)hwif->hwif_data;
+	_auide_hwif *auide = &auide_hwif;
 	dbdev_tab_t source_dev_tab;
 	dbdev_tab_t source_dev_tab;
 	int flags;
 	int flags;
 
 
@@ -600,8 +598,6 @@ static int au_ide_probe(struct device *dev)
 
 
 	ide_init_port_hw(hwif, &hw);
 	ide_init_port_hw(hwif, &hw);
 
 
-	hwif->dev = dev;
-
 	/* If the user has selected DDMA assisted copies,
 	/* If the user has selected DDMA assisted copies,
 	   then set up a few local I/O function entry points 
 	   then set up a few local I/O function entry points 
 	*/
 	*/
@@ -610,11 +606,8 @@ static int au_ide_probe(struct device *dev)
 	hwif->input_data  = au1xxx_input_data;
 	hwif->input_data  = au1xxx_input_data;
 	hwif->output_data = au1xxx_output_data;
 	hwif->output_data = au1xxx_output_data;
 #endif
 #endif
-	hwif->select_data               = 0;    /* no chipset-specific code */
-	hwif->config_data               = 0;    /* no chipset-specific code */
 
 
 	auide_hwif.hwif                 = hwif;
 	auide_hwif.hwif                 = hwif;
-	hwif->hwif_data                 = &auide_hwif;
 
 
 	idx[0] = hwif->index;
 	idx[0] = hwif->index;
 
 

+ 17 - 11
drivers/ide/mips/swarm.c

@@ -61,6 +61,11 @@ static struct resource swarm_ide_resource = {
 
 
 static struct platform_device *swarm_ide_dev;
 static struct platform_device *swarm_ide_dev;
 
 
+static const struct ide_port_info swarm_port_info = {
+	.name			= DRV_NAME,
+	.host_flags		= IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+};
+
 /*
 /*
  * swarm_ide_probe - if the board header indicates the existence of
  * swarm_ide_probe - if the board header indicates the existence of
  * Generic Bus IDE, allocate a HWIF for it.
  * Generic Bus IDE, allocate a HWIF for it.
@@ -77,12 +82,6 @@ static int __devinit swarm_ide_probe(struct device *dev)
 	if (!SIBYTE_HAVE_IDE)
 	if (!SIBYTE_HAVE_IDE)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	hwif = ide_find_port();
-	if (hwif == NULL) {
-		printk(KERN_ERR DRV_NAME ": no free slot for interface\n");
-		return -ENOMEM;
-	}
-
 	base = ioremap(A_IO_EXT_BASE, 0x800);
 	base = ioremap(A_IO_EXT_BASE, 0x800);
 	offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
 	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));
 	size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
@@ -109,10 +108,6 @@ static int __devinit swarm_ide_probe(struct device *dev)
 
 
 	base = ioremap(offset, size);
 	base = ioremap(offset, size);
 
 
-	/* Setup MMIO ops.  */
-	hwif->host_flags = IDE_HFLAG_MMIO;
-	default_hwif_mmiops(hwif);
-
 	for (i = 0; i <= 7; i++)
 	for (i = 0; i <= 7; i++)
 		hw.io_ports_array[i] =
 		hw.io_ports_array[i] =
 				(unsigned long)(base + ((0x1f0 + i) << 5));
 				(unsigned long)(base + ((0x1f0 + i) << 5));
@@ -121,15 +116,26 @@ static int __devinit swarm_ide_probe(struct device *dev)
 	hw.irq = K_INT_GB_IDE;
 	hw.irq = K_INT_GB_IDE;
 	hw.chipset = ide_generic;
 	hw.chipset = ide_generic;
 
 
+	hwif = ide_find_port_slot(&swarm_port_info);
+	if (hwif == NULL)
+		goto err;
+
 	ide_init_port_hw(hwif, &hw);
 	ide_init_port_hw(hwif, &hw);
 
 
+	/* Setup MMIO ops. */
+	default_hwif_mmiops(hwif);
+
 	idx[0] = hwif->index;
 	idx[0] = hwif->index;
 
 
-	ide_device_add(idx, NULL);
+	ide_device_add(idx, &swarm_port_info);
 
 
 	dev_set_drvdata(dev, hwif);
 	dev_set_drvdata(dev, hwif);
 
 
 	return 0;
 	return 0;
+err:
+	release_resource(&swarm_ide_resource);
+	iounmap(base);
+	return -ENOMEM;
 }
 }
 
 
 static struct device_driver swarm_ide_driver = {
 static struct device_driver swarm_ide_driver = {

+ 2 - 4
drivers/ide/pci/alim15x3.c

@@ -69,7 +69,8 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
 {
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_hwif_t *hwif = HWIF(drive);
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
 	struct pci_dev *dev = to_pci_dev(hwif->dev);
-	int s_time, a_time, c_time;
+	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
+	int s_time = t->setup, a_time = t->active, c_time = t->cycle;
 	u8 s_clc, a_clc, r_clc;
 	u8 s_clc, a_clc, r_clc;
 	unsigned long flags;
 	unsigned long flags;
 	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
 	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
@@ -78,13 +79,10 @@ static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	u8 cd_dma_fifo = 0;
 	u8 cd_dma_fifo = 0;
 	int unit = drive->select.b.unit & 1;
 	int unit = drive->select.b.unit & 1;
 
 
-	s_time = ide_pio_timings[pio].setup_time;
-	a_time = ide_pio_timings[pio].active_time;
 	if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8)
 	if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8)
 		s_clc = 0;
 		s_clc = 0;
 	if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
 	if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
 		a_clc = 0;
 		a_clc = 0;
-	c_time = ide_pio_timings[pio].cycle_time;
 
 
 	if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
 	if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
 		r_clc = 1;
 		r_clc = 1;

+ 0 - 2
drivers/ide/pci/amd74xx.c

@@ -21,8 +21,6 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
 
 
-#include "ide-timing.h"
-
 enum {
 enum {
 	AMD_IDE_CONFIG		= 0x41,
 	AMD_IDE_CONFIG		= 0x41,
 	AMD_CABLE_DETECT	= 0x42,
 	AMD_CABLE_DETECT	= 0x42,

+ 57 - 74
drivers/ide/pci/cmd640.c

@@ -521,6 +521,7 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index)
 static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
 static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
 			    u8 pio_mode, unsigned int cycle_time)
 			    u8 pio_mode, unsigned int cycle_time)
 {
 {
+	struct ide_timing *t;
 	int setup_time, active_time, recovery_time, clock_time;
 	int setup_time, active_time, recovery_time, clock_time;
 	u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
 	u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
 	int bus_speed;
 	int bus_speed;
@@ -532,8 +533,11 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
 
 
 	if (pio_mode > 5)
 	if (pio_mode > 5)
 		pio_mode = 5;
 		pio_mode = 5;
-	setup_time  = ide_pio_timings[pio_mode].setup_time;
-	active_time = ide_pio_timings[pio_mode].active_time;
+
+	t = ide_timing_find_mode(XFER_PIO_0 + pio_mode);
+	setup_time  = t->setup;
+	active_time = t->active;
+
 	recovery_time = cycle_time - (setup_time + active_time);
 	recovery_time = cycle_time - (setup_time + active_time);
 	clock_time = 1000 / bus_speed;
 	clock_time = 1000 / bus_speed;
 	cycle_count = DIV_ROUND_UP(cycle_time, clock_time);
 	cycle_count = DIV_ROUND_UP(cycle_time, clock_time);
@@ -607,11 +611,40 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
 
 
 	display_clocks(index);
 	display_clocks(index);
 }
 }
+#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
+
+static void cmd640_init_dev(ide_drive_t *drive)
+{
+	unsigned int i = drive->hwif->channel * 2 + drive->select.b.unit;
+
+#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
+	/*
+	 * Reset timing to the slowest speed and turn off prefetch.
+	 * This way, the drive identify code has a better chance.
+	 */
+	setup_counts[i]    =  4;	/* max possible */
+	active_counts[i]   = 16;	/* max possible */
+	recovery_counts[i] = 16;	/* max possible */
+	program_drive_counts(drive, i);
+	set_prefetch_mode(drive, i, 0);
+	printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch cleared\n", i);
+#else
+	/*
+	 * Set the drive unmask flags to match the prefetch setting.
+	 */
+	check_prefetch(drive, i);
+	printk(KERN_INFO DRV_NAME ": drive%d timings/prefetch(%s) preserved\n",
+				  i, drive->no_io_32bit ? "off" : "on");
+#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
+}
+
 
 
 static const struct ide_port_ops cmd640_port_ops = {
 static const struct ide_port_ops cmd640_port_ops = {
+	.init_dev		= cmd640_init_dev,
+#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 	.set_pio_mode		= cmd640_set_pio_mode,
 	.set_pio_mode		= cmd640_set_pio_mode,
+#endif
 };
 };
-#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 
 
 static int pci_conf1(void)
 static int pci_conf1(void)
 {
 {
@@ -654,10 +687,8 @@ static const struct ide_port_info cmd640_port_info __initdata = {
 				  IDE_HFLAG_NO_DMA |
 				  IDE_HFLAG_NO_DMA |
 				  IDE_HFLAG_ABUSE_PREFETCH |
 				  IDE_HFLAG_ABUSE_PREFETCH |
 				  IDE_HFLAG_ABUSE_FAST_DEVSEL,
 				  IDE_HFLAG_ABUSE_FAST_DEVSEL,
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 	.port_ops		= &cmd640_port_ops,
 	.port_ops		= &cmd640_port_ops,
 	.pio_mask		= ATA_PIO5,
 	.pio_mask		= ATA_PIO5,
-#endif
 };
 };
 
 
 static int cmd640x_init_one(unsigned long base, unsigned long ctl)
 static int cmd640x_init_one(unsigned long base, unsigned long ctl)
@@ -683,12 +714,8 @@ static int cmd640x_init_one(unsigned long base, unsigned long ctl)
  */
  */
 static int __init cmd640x_init(void)
 static int __init cmd640x_init(void)
 {
 {
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
-	int second_port_toggled = 0;
-#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 	int second_port_cmd640 = 0, rc;
 	int second_port_cmd640 = 0, rc;
 	const char *bus_type, *port2;
 	const char *bus_type, *port2;
-	unsigned int index;
 	u8 b, cfr;
 	u8 b, cfr;
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	hw_regs_t hw[2];
 	hw_regs_t hw[2];
@@ -774,88 +801,44 @@ static int __init cmd640x_init(void)
 	put_cmd640_reg(CMDTIM, 0);
 	put_cmd640_reg(CMDTIM, 0);
 	put_cmd640_reg(BRST, 0x40);
 	put_cmd640_reg(BRST, 0x40);
 
 
-	cmd_hwif1 = ide_find_port();
+	b = get_cmd640_reg(CNTRL);
 
 
 	/*
 	/*
 	 * Try to enable the secondary interface, if not already enabled
 	 * Try to enable the secondary interface, if not already enabled
 	 */
 	 */
-	if (cmd_hwif1 &&
-	    cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe) {
-		port2 = "not probed";
+	if (secondary_port_responding()) {
+		if ((b & CNTRL_ENA_2ND)) {
+			second_port_cmd640 = 1;
+			port2 = "okay";
+		} else if (cmd640_vlb) {
+			second_port_cmd640 = 1;
+			port2 = "alive";
+		} else
+			port2 = "not cmd640";
 	} else {
 	} else {
-		b = get_cmd640_reg(CNTRL);
+		put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* toggle the bit */
 		if (secondary_port_responding()) {
 		if (secondary_port_responding()) {
-			if ((b & CNTRL_ENA_2ND)) {
-				second_port_cmd640 = 1;
-				port2 = "okay";
-			} else if (cmd640_vlb) {
-				second_port_cmd640 = 1;
-				port2 = "alive";
-			} else
-				port2 = "not cmd640";
+			second_port_cmd640 = 1;
+			port2 = "enabled";
 		} else {
 		} else {
-			put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* toggle the bit */
-			if (secondary_port_responding()) {
-				second_port_cmd640 = 1;
-#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
-				second_port_toggled = 1;
-#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
-				port2 = "enabled";
-			} else {
-				put_cmd640_reg(CNTRL, b); /* restore original setting */
-				port2 = "not responding";
-			}
+			put_cmd640_reg(CNTRL, b); /* restore original setting */
+			port2 = "not responding";
 		}
 		}
 	}
 	}
 
 
 	/*
 	/*
 	 * Initialize data for secondary cmd640 port, if enabled
 	 * Initialize data for secondary cmd640 port, if enabled
 	 */
 	 */
-	if (second_port_cmd640 && cmd_hwif1) {
-		ide_init_port_hw(cmd_hwif1, &hw[1]);
-		idx[1] = cmd_hwif1->index;
+	if (second_port_cmd640) {
+		cmd_hwif1 = ide_find_port();
+		if (cmd_hwif1) {
+			ide_init_port_hw(cmd_hwif1, &hw[1]);
+			idx[1] = cmd_hwif1->index;
+		}
 	}
 	}
 	printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n",
 	printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n",
 			 second_port_cmd640 ? "" : "not ", port2);
 			 second_port_cmd640 ? "" : "not ", port2);
 
 
-	/*
-	 * Establish initial timings/prefetch for all drives.
-	 * Do not unnecessarily disturb any prior BIOS setup of these.
-	 */
-	for (index = 0; index < (2 + (second_port_cmd640 << 1)); 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
-		/*
-		 * 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(drive, index);
-		set_prefetch_mode(drive, index, 0);
-		printk("cmd640: drive%d timings/prefetch cleared\n", index);
-#else
-		/*
-		 * Set the drive unmask flags to match the prefetch setting
-		 */
-		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 */
-	}
-
 #ifdef CMD640_DUMP_REGS
 #ifdef CMD640_DUMP_REGS
 	cmd640_dump_regs();
 	cmd640_dump_regs();
 #endif
 #endif

+ 3 - 3
drivers/ide/pci/cmd64x.c

@@ -116,6 +116,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
 {
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
 	struct pci_dev *dev	= to_pci_dev(hwif->dev);
+	struct ide_timing *t	= ide_timing_find_mode(XFER_PIO_0 + pio);
 	unsigned int cycle_time;
 	unsigned int cycle_time;
 	u8 setup_count, arttim = 0;
 	u8 setup_count, arttim = 0;
 
 
@@ -124,10 +125,9 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
 
 
 	cycle_time = ide_pio_cycle_time(drive, pio);
 	cycle_time = ide_pio_cycle_time(drive, pio);
 
 
-	program_cycle_times(drive, cycle_time,
-			    ide_pio_timings[pio].active_time);
+	program_cycle_times(drive, cycle_time, t->active);
 
 
-	setup_count = quantize_timing(ide_pio_timings[pio].setup_time,
+	setup_count = quantize_timing(t->setup,
 			1000 / (ide_pci_clk ? ide_pci_clk : 33));
 			1000 / (ide_pci_clk ? ide_pci_clk : 33));
 
 
 	/*
 	/*

+ 1 - 5
drivers/ide/pci/cs5535.c

@@ -26,8 +26,6 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
 
 
-#include "ide-timing.h"
-
 #define MSR_ATAC_BASE		0x51300000
 #define MSR_ATAC_BASE		0x51300000
 #define ATAC_GLD_MSR_CAP	(MSR_ATAC_BASE+0)
 #define ATAC_GLD_MSR_CAP	(MSR_ATAC_BASE+0)
 #define ATAC_GLD_MSR_CONFIG	(MSR_ATAC_BASE+0x01)
 #define ATAC_GLD_MSR_CONFIG	(MSR_ATAC_BASE+0x01)
@@ -75,13 +73,11 @@ static unsigned int cs5535_udma_timings[5] =
  */
  */
 static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
 static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
 {
 {
-
 	u32 reg = 0, dummy;
 	u32 reg = 0, dummy;
 	int unit = drive->select.b.unit;
 	int unit = drive->select.b.unit;
 
 
-
 	/* Set the PIO timings */
 	/* Set the PIO timings */
-	if ((speed & XFER_MODE) == XFER_PIO) {
+	if (speed < XFER_SW_DMA_0) {
 		ide_drive_t *pair = ide_get_paired_drive(drive);
 		ide_drive_t *pair = ide_get_paired_drive(drive);
 		u8 cmd, pioa;
 		u8 cmd, pioa;
 
 

+ 4 - 5
drivers/ide/pci/cy82c693.c

@@ -133,6 +133,7 @@ static int calc_clk(int time, int bus_speed)
  */
  */
 static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
 static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
 {
 {
+	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
 	int clk1, clk2;
 	int clk1, clk2;
 	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
 	int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
 
 
@@ -141,15 +142,13 @@ static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
 	 */
 	 */
 
 
 	/* let's calc the address setup time clocks */
 	/* let's calc the address setup time clocks */
-	p_pclk->address_time = (u8)calc_clk(ide_pio_timings[pio].setup_time, bus_speed);
+	p_pclk->address_time = (u8)calc_clk(t->setup, bus_speed);
 
 
 	/* let's calc the active and recovery time clocks */
 	/* let's calc the active and recovery time clocks */
-	clk1 = calc_clk(ide_pio_timings[pio].active_time, bus_speed);
+	clk1 = calc_clk(t->active, bus_speed);
 
 
 	/* calc recovery timing */
 	/* calc recovery timing */
-	clk2 =	ide_pio_timings[pio].cycle_time -
-		ide_pio_timings[pio].active_time -
-		ide_pio_timings[pio].setup_time;
+	clk2 = t->cycle - t->active - t->setup;
 
 
 	clk2 = calc_clk(clk2, bus_speed);
 	clk2 = calc_clk(clk2, bus_speed);
 
 

+ 0 - 1
drivers/ide/pci/delkin_cb.c

@@ -93,7 +93,6 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
 
 
 	i = hwif->index;
 	i = hwif->index;
 
 
-	ide_init_port_data(hwif, i);
 	ide_init_port_hw(hwif, &hw);
 	ide_init_port_hw(hwif, &hw);
 
 
 	idx[0] = i;
 	idx[0] = i;

+ 6 - 0
drivers/ide/pci/it821x.c

@@ -512,8 +512,14 @@ static void __devinit it821x_quirkproc(ide_drive_t *drive)
 }
 }
 
 
 static struct ide_dma_ops it821x_pass_through_dma_ops = {
 static struct ide_dma_ops it821x_pass_through_dma_ops = {
+	.dma_host_set		= ide_dma_host_set,
+	.dma_setup		= ide_dma_setup,
+	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= it821x_dma_start,
 	.dma_start		= it821x_dma_start,
 	.dma_end		= it821x_dma_end,
 	.dma_end		= it821x_dma_end,
+	.dma_test_irq		= ide_dma_test_irq,
+	.dma_timeout		= ide_dma_timeout,
+	.dma_lost_irq		= ide_dma_lost_irq,
 };
 };
 
 
 /**
 /**

+ 2 - 6
drivers/ide/pci/scc_pata.c

@@ -558,12 +558,9 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	int i;
 	int i;
 
 
-	hwif = ide_find_port();
-	if (hwif == NULL) {
-		printk(KERN_ERR "%s: too many IDE interfaces, "
-				"no room in table\n", SCC_PATA_NAME);
+	hwif = ide_find_port_slot(d);
+	if (hwif == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	memset(&hw, 0, sizeof(hw));
 	memset(&hw, 0, sizeof(hw));
 	for (i = 0; i <= 8; i++)
 	for (i = 0; i <= 8; i++)
@@ -572,7 +569,6 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
 	hw.dev = &dev->dev;
 	hw.dev = &dev->dev;
 	hw.chipset = ide_pci;
 	hw.chipset = ide_pci;
 	ide_init_port_hw(hwif, &hw);
 	ide_init_port_hw(hwif, &hw);
-	hwif->dev = &dev->dev;
 
 
 	idx[0] = hwif->index;
 	idx[0] = hwif->index;
 
 

+ 12 - 11
drivers/ide/pci/sgiioc4.c

@@ -568,6 +568,7 @@ static const struct ide_dma_ops sgiioc4_dma_ops = {
 };
 };
 
 
 static const struct ide_port_info sgiioc4_port_info __devinitdata = {
 static const struct ide_port_info sgiioc4_port_info __devinitdata = {
+	.name			= DRV_NAME,
 	.chipset		= ide_pci,
 	.chipset		= ide_pci,
 	.init_dma		= ide_dma_sgiioc4,
 	.init_dma		= ide_dma_sgiioc4,
 	.port_ops		= &sgiioc4_port_ops,
 	.port_ops		= &sgiioc4_port_ops,
@@ -587,13 +588,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 	hw_regs_t hw;
 	hw_regs_t hw;
 	struct ide_port_info d = sgiioc4_port_info;
 	struct ide_port_info d = sgiioc4_port_info;
 
 
-	hwif = ide_find_port();
-	if (hwif == NULL) {
-		printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n",
-				DRV_NAME);
-		return -ENOMEM;
-	}
-
 	/*  Get the CmdBlk and CtrlBlk Base Registers */
 	/*  Get the CmdBlk and CtrlBlk Base Registers */
 	bar0 = pci_resource_start(dev, 0);
 	bar0 = pci_resource_start(dev, 0);
 	virt_base = ioremap(bar0, pci_resource_len(dev, 0));
 	virt_base = ioremap(bar0, pci_resource_len(dev, 0));
@@ -608,11 +602,11 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 
 
 	cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
 	cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
 	if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
 	if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
-	    hwif->name)) {
+	    DRV_NAME)) {
 		printk(KERN_ERR
 		printk(KERN_ERR
 			"%s : %s -- ERROR, Addresses "
 			"%s : %s -- ERROR, Addresses "
 			"0x%p to 0x%p ALREADY in use\n",
 			"0x%p to 0x%p ALREADY in use\n",
-		       __func__, hwif->name, (void *) cmd_phys_base,
+		       __func__, DRV_NAME, (void *) cmd_phys_base,
 		       (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
 		       (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
@@ -623,9 +617,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 	hw.irq = dev->irq;
 	hw.irq = dev->irq;
 	hw.chipset = ide_pci;
 	hw.chipset = ide_pci;
 	hw.dev = &dev->dev;
 	hw.dev = &dev->dev;
-	ide_init_port_hw(hwif, &hw);
 
 
-	hwif->dev = &dev->dev;
+	hwif = ide_find_port_slot(&d);
+	if (hwif == NULL)
+		goto err;
+
+	ide_init_port_hw(hwif, &hw);
 
 
 	/* The IOC4 uses MMIO rather than Port IO. */
 	/* The IOC4 uses MMIO rather than Port IO. */
 	default_hwif_mmiops(hwif);
 	default_hwif_mmiops(hwif);
@@ -641,6 +638,10 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 		return -EIO;
 		return -EIO;
 
 
 	return 0;
 	return 0;
+err:
+	release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE);
+	iounmap(virt_base);
+	return -ENOMEM;
 }
 }
 
 
 static unsigned int __devinit
 static unsigned int __devinit

+ 1 - 2
drivers/ide/pci/siimage.c

@@ -421,8 +421,7 @@ static int sil_sata_reset_poll(ide_drive_t *drive)
 		if ((sata_stat & 0x03) != 0x03) {
 		if ((sata_stat & 0x03) != 0x03) {
 			printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
 			printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
 					    hwif->name, sata_stat);
 					    hwif->name, sata_stat);
-			HWGROUP(drive)->polling = 0;
-			return ide_started;
+			return -ENXIO;
 		}
 		}
 	}
 	}
 
 

+ 0 - 3
drivers/ide/pci/sis5513.c

@@ -52,8 +52,6 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
 
 
-#include "ide-timing.h"
-
 /* registers layout and init values are chipset family dependant */
 /* registers layout and init values are chipset family dependant */
 
 
 #define ATA_16		0x01
 #define ATA_16		0x01
@@ -616,7 +614,6 @@ MODULE_LICENSE("GPL");
 /*
 /*
  * TODO:
  * TODO:
  *	- CLEANUP
  *	- CLEANUP
- *	- Use drivers/ide/ide-timing.h !
  *	- More checks in the config registers (force values instead of
  *	- More checks in the config registers (force values instead of
  *	  relying on the BIOS setting them correctly).
  *	  relying on the BIOS setting them correctly).
  *	- Further optimisations ?
  *	- Further optimisations ?

+ 2 - 1
drivers/ide/pci/sl82c105.c

@@ -47,10 +47,11 @@
  */
  */
 static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
 static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
 {
 {
+	struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
 	unsigned int cmd_on, cmd_off;
 	unsigned int cmd_on, cmd_off;
 	u8 iordy = 0;
 	u8 iordy = 0;
 
 
-	cmd_on  = (ide_pio_timings[pio].active_time + 29) / 30;
+	cmd_on  = (t->active + 29) / 30;
 	cmd_off = (ide_pio_cycle_time(drive, pio) - 30 * cmd_on + 29) / 30;
 	cmd_off = (ide_pio_cycle_time(drive, pio) - 30 * cmd_on + 29) / 30;
 
 
 	if (cmd_on == 0)
 	if (cmd_on == 0)

+ 0 - 2
drivers/ide/pci/via82cxxx.c

@@ -35,8 +35,6 @@
 #include <asm/processor.h>
 #include <asm/processor.h>
 #endif
 #endif
 
 
-#include "ide-timing.h"
-
 #define VIA_IDE_ENABLE		0x40
 #define VIA_IDE_ENABLE		0x40
 #define VIA_IDE_CONFIG		0x41
 #define VIA_IDE_CONFIG		0x41
 #define VIA_FIFO_CONFIG		0x43
 #define VIA_FIFO_CONFIG		0x43

+ 0 - 1
drivers/ide/ppc/Makefile

@@ -1,3 +1,2 @@
 
 
 obj-$(CONFIG_BLK_DEV_IDE_PMAC)		+= pmac.o
 obj-$(CONFIG_BLK_DEV_IDE_PMAC)		+= pmac.o
-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= mpc8xx.o

+ 0 - 851
drivers/ide/ppc/mpc8xx.c

@@ -1,851 +0,0 @@
-/*
- *  Copyright (C) 2000, 2001 Wolfgang Denk, wd@denx.de
- *  Modified for direct IDE interface
- *	by Thomas Lange, thomas@corelatus.com
- *  Modified for direct IDE interface on 8xx without using the PCMCIA
- *  controller
- *	by Steven.Scholz@imc-berlin.de
- *  Moved out of arch/ppc/kernel/m8xx_setup.c, other minor cleanups
- *	by Mathew Locke <mattl@mvista.com>
- */
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/tty.h>
-#include <linux/major.h>
-#include <linux/interrupt.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/ide.h>
-#include <linux/bootmem.h>
-
-#include <asm/mpc8xx.h>
-#include <asm/mmu.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/ide.h>
-#include <asm/8xx_immap.h>
-#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);
-static int check_ide_device (unsigned long base);
-
-static void ide_interrupt_ack (void *dev);
-static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio);
-
-typedef	struct ide_ioport_desc {
-	unsigned long	base_off;		/* Offset to PCMCIA memory	*/
-	unsigned long	reg_off[IDE_NR_PORTS];	/* controller register offsets	*/
-	int		irq;			/* IRQ				*/
-} ide_ioport_desc_t;
-
-ide_ioport_desc_t ioport_dsc[MAX_HWIFS] = {
-#ifdef IDE0_BASE_OFFSET
-	{ IDE0_BASE_OFFSET,
-	    {
-		IDE0_DATA_REG_OFFSET,
-		IDE0_ERROR_REG_OFFSET,
-		IDE0_NSECTOR_REG_OFFSET,
-		IDE0_SECTOR_REG_OFFSET,
-		IDE0_LCYL_REG_OFFSET,
-		IDE0_HCYL_REG_OFFSET,
-		IDE0_SELECT_REG_OFFSET,
-		IDE0_STATUS_REG_OFFSET,
-		IDE0_CONTROL_REG_OFFSET,
-		IDE0_IRQ_REG_OFFSET,
-	    },
-	    IDE0_INTERRUPT,
-	},
-#ifdef IDE1_BASE_OFFSET
-	{ IDE1_BASE_OFFSET,
-	    {
-		IDE1_DATA_REG_OFFSET,
-		IDE1_ERROR_REG_OFFSET,
-		IDE1_NSECTOR_REG_OFFSET,
-		IDE1_SECTOR_REG_OFFSET,
-		IDE1_LCYL_REG_OFFSET,
-		IDE1_HCYL_REG_OFFSET,
-		IDE1_SELECT_REG_OFFSET,
-		IDE1_STATUS_REG_OFFSET,
-		IDE1_CONTROL_REG_OFFSET,
-		IDE1_IRQ_REG_OFFSET,
-	    },
-	    IDE1_INTERRUPT,
-	},
-#endif /* IDE1_BASE_OFFSET */
-#endif	/* IDE0_BASE_OFFSET */
-};
-
-ide_pio_timings_t ide_pio_clocks[6];
-int hold_time[6] =  {30, 20, 15, 10, 10, 10 };   /* PIO Mode 5 with IORDY (nonstandard) */
-
-/*
- * Warning: only 1 (ONE) PCMCIA slot supported here,
- * which must be correctly initialized by the firmware (PPCBoot).
- */
-static int _slot_ = -1;			/* will be read from PCMCIA registers   */
-
-/* Make clock cycles and always round up */
-#define PCMCIA_MK_CLKS( t, T ) (( (t) * ((T)/1000000) + 999U ) / 1000U )
-
-#define M8XX_PCMCIA_CD2(slot)      (0x10000000 >> (slot << 4))
-#define M8XX_PCMCIA_CD1(slot)      (0x08000000 >> (slot << 4))
-
-/*
- * The TQM850L hardware has two pins swapped! Grrrrgh!
- */
-#ifdef	CONFIG_TQM850L
-#define __MY_PCMCIA_GCRX_CXRESET	PCMCIA_GCRX_CXOE
-#define __MY_PCMCIA_GCRX_CXOE		PCMCIA_GCRX_CXRESET
-#else
-#define __MY_PCMCIA_GCRX_CXRESET	PCMCIA_GCRX_CXRESET
-#define __MY_PCMCIA_GCRX_CXOE		PCMCIA_GCRX_CXOE
-#endif
-
-#if defined(CONFIG_BLK_DEV_MPC8xx_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
-#define PCMCIA_SCHLVL IDE0_INTERRUPT	/* Status Change Interrupt Level	*/
-static int pcmcia_schlvl = PCMCIA_SCHLVL;
-#endif
-
-/*
- * See include/linux/ide.h for definition of hw_regs_t (p, base)
- */
-
-/*
- * m8xx_ide_init_ports() for a direct IDE interface _using_
- * MPC8xx's internal PCMCIA interface
- */
-#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
-static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
-{
-	unsigned long *p = hw->io_ports_array;
-	int i;
-
-	typedef struct {
-		ulong br;
-		ulong or;
-	} pcmcia_win_t;
-	volatile pcmcia_win_t *win;
-	volatile pcmconf8xx_t *pcmp;
-
-	uint *pgcrx;
-	u32 pcmcia_phy_base;
-	u32 pcmcia_phy_end;
-	static unsigned long pcmcia_base = 0;
-	unsigned long base;
-
-	*p = 0;
-
-	pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
-
-	if (!pcmcia_base) {
-                /*
-                 * Read out PCMCIA registers. Since the reset values
-                 * are undefined, we sure hope that they have been
-                 * set up by firmware
-		 */
-
-		/* Scan all registers for valid settings */
-		pcmcia_phy_base = 0xFFFFFFFF;
-		pcmcia_phy_end = 0;
-		/* br0 is start of brX and orX regs */
-		win = (pcmcia_win_t *) \
-			(&(((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0));
-		for (i = 0; i < 8; i++) {
-			if (win->or & 1) {	/* This bank is marked as valid */
-				if (win->br < pcmcia_phy_base) {
-					pcmcia_phy_base = win->br;
-				}
-				if ((win->br + PCMCIA_MEM_SIZE) > pcmcia_phy_end) {
-					pcmcia_phy_end  = win->br + PCMCIA_MEM_SIZE;
-				}
-				/* Check which slot that has been defined */
-				_slot_ = (win->or >> 2) & 1;
-
-			}					/* Valid bank */
-			win++;
-		}						/* for */
-
-		printk ("PCMCIA slot %c: phys mem %08x...%08x (size %08x)\n",
-			'A' + _slot_,
-			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);
-
-#ifdef DEBUG
-		printk ("PCMCIA virt base: %08lx\n", pcmcia_base);
-#endif
-		/* Compute clock cycles for PIO timings */
-		for (i=0; i<6; ++i) {
-			bd_t	*binfo = (bd_t *)__res;
-
-			hold_time[i]   =
-				PCMCIA_MK_CLKS (hold_time[i],
-						binfo->bi_busfreq);
-			ide_pio_clocks[i].setup_time  =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].setup_time,
-						binfo->bi_busfreq);
-			ide_pio_clocks[i].active_time =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].active_time,
-						binfo->bi_busfreq);
-			ide_pio_clocks[i].cycle_time  =
-				PCMCIA_MK_CLKS (ide_pio_timings[i].cycle_time,
-						binfo->bi_busfreq);
-#if 0
-			printk ("PIO mode %d timings: %d/%d/%d => %d/%d/%d\n",
-				i,
-				ide_pio_clocks[i].setup_time,
-				ide_pio_clocks[i].active_time,
-				ide_pio_clocks[i].hold_time,
-				ide_pio_clocks[i].cycle_time,
-				ide_pio_timings[i].setup_time,
-				ide_pio_timings[i].active_time,
-				ide_pio_timings[i].hold_time,
-				ide_pio_timings[i].cycle_time);
-#endif
-		}
-	}
-
-	if (_slot_ == -1) {
-		printk ("PCMCIA slot has not been defined! Using A as default\n");
-		_slot_ = 0;
-	}
-
-#ifdef CONFIG_IDE_8xx_PCCARD
-
-#ifdef DEBUG
-	printk ("PIPR = 0x%08X  slot %c ==> mask = 0x%X\n",
-		pcmp->pcmc_pipr,
-		'A' + _slot_,
-		M8XX_PCMCIA_CD1(_slot_) | M8XX_PCMCIA_CD2(_slot_) );
-#endif /* DEBUG */
-
-	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 -ENODEV;		/* No card in slot */
-	}
-
-	check_ide_device (pcmcia_base);
-
-#endif	/* CONFIG_IDE_8xx_PCCARD */
-
-	base = pcmcia_base + ioport_dsc[data_port].base_off;
-#ifdef DEBUG
-	printk ("base: %08x + %08x = %08x\n",
-			pcmcia_base, ioport_dsc[data_port].base_off, base);
-#endif
-
-	for (i = 0; i < IDE_NR_PORTS; ++i) {
-#ifdef DEBUG
-		printk ("port[%d]: %08x + %08x = %08x\n",
-			i,
-			base,
-			ioport_dsc[data_port].reg_off[i],
-			i, base + ioport_dsc[data_port].reg_off[i]);
-#endif
-	 	*p++ = base + ioport_dsc[data_port].reg_off[i];
-	}
-
-	hw->irq = ioport_dsc[data_port].irq;
-	hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
-
-#ifdef CONFIG_IDE_8xx_PCCARD
-	{
-		unsigned int reg;
-
-		if (_slot_)
-			pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcrb;
-		else
-			pgcrx = &((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pgcra;
-
-		reg = *pgcrx;
-		reg |= mk_int_int_mask (pcmcia_schlvl) << 24;
-		reg |= mk_int_int_mask (pcmcia_schlvl) << 16;
-		*pgcrx = reg;
-	}
-#endif	/* CONFIG_IDE_8xx_PCCARD */
-
-	/* 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);
-
-#ifdef CONFIG_IDE_8xx_PCCARD
-	/* Make sure we don't get garbage irq */
-	((immap_t *) IMAP_ADDR)->im_pcmcia.pcmc_pscr = 0xFFFF;
-
-	/* Enable falling edge irq */
-	pcmp->pcmc_per = 0x100000 >> (16 * _slot_);
-#endif	/* CONFIG_IDE_8xx_PCCARD */
-
-	hw->chipset = ide_generic;
-
-	return 0;
-}
-#endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */
-
-/*
- * m8xx_ide_init_ports() for a direct IDE interface _not_ using
- * MPC8xx's internal PCMCIA interface
- */
-#if defined(CONFIG_IDE_EXT_DIRECT)
-static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port)
-{
-	unsigned long *p = hw->io_ports_array;
-	int i;
-
-	u32 ide_phy_base;
-	u32 ide_phy_end;
-	static unsigned long ide_base = 0;
-	unsigned long base;
-
-	*p = 0;
-
-	if (!ide_base) {
-
-		/* TODO:
-		 * - add code to read ORx, BRx
-		 */
-		ide_phy_base = CFG_ATA_BASE_ADDR;
-		ide_phy_end  = CFG_ATA_BASE_ADDR + 0x200;
-
-		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);
-
-#ifdef DEBUG
-		printk ("IDE virt base: %08lx\n", ide_base);
-#endif
-	}
-
-	base = ide_base + ioport_dsc[data_port].base_off;
-#ifdef DEBUG
-	printk ("base: %08x + %08x = %08x\n",
-		ide_base, ioport_dsc[data_port].base_off, base);
-#endif
-
-	for (i = 0; i < IDE_NR_PORTS; ++i) {
-#ifdef DEBUG
-		printk ("port[%d]: %08x + %08x = %08x\n",
-			i,
-			base,
-			ioport_dsc[data_port].reg_off[i],
-			i, base + ioport_dsc[data_port].reg_off[i]);
-#endif
-	 	*p++ = base + ioport_dsc[data_port].reg_off[i];
-	}
-
-	/* direct connected IDE drive, i.e. external IRQ */
-	hw->irq = ioport_dsc[data_port].irq;
-	hw->ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
-
-	/* 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);
-
-	hw->chipset = ide_generic;
-
-	return 0;
-}
-#endif	/* CONFIG_IDE_8xx_DIRECT */
-
-
-/* -------------------------------------------------------------------- */
-
-
-/* PCMCIA Timing */
-#ifndef	PCMCIA_SHT
-#define PCMCIA_SHT(t)	((t & 0x0F)<<16)	/* Strobe Hold  Time 	*/
-#define PCMCIA_SST(t)	((t & 0x0F)<<12)	/* Strobe Setup Time	*/
-#define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length	*/
-#endif
-
-/* Calculate PIO timings */
-static void m8xx_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
-#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_DIRECT)
-	volatile pcmconf8xx_t	*pcmp;
-	ulong timing, mask, reg;
-
-	pcmp = (pcmconf8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_pcmcia));
-
-	mask = ~(PCMCIA_SHT(0xFF) | PCMCIA_SST(0xFF) | PCMCIA_SL(0xFF));
-
-	timing  = PCMCIA_SHT(hold_time[pio]  )
-		| PCMCIA_SST(ide_pio_clocks[pio].setup_time )
-		| PCMCIA_SL (ide_pio_clocks[pio].active_time)
-		;
-
-#if 1
-	printk ("Setting timing bits 0x%08lx in PCMCIA controller\n", timing);
-#endif
-	if ((reg = pcmp->pcmc_por0 & mask) != 0)
-		pcmp->pcmc_por0 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por1 & mask) != 0)
-		pcmp->pcmc_por1 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por2 & mask) != 0)
-		pcmp->pcmc_por2 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por3 & mask) != 0)
-		pcmp->pcmc_por3 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por4 & mask) != 0)
-		pcmp->pcmc_por4 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por5 & mask) != 0)
-		pcmp->pcmc_por5 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por6 & mask) != 0)
-		pcmp->pcmc_por6 = reg | timing;
-
-	if ((reg = pcmp->pcmc_por7 & mask) != 0)
-		pcmp->pcmc_por7 = reg | timing;
-
-#elif defined(CONFIG_IDE_EXT_DIRECT)
-
-	printk("%s[%d] %s: not implemented yet!\n",
-		__FILE__, __LINE__, __func__);
-#endif /* defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_PCMCIA */
-}
-
-static const struct ide_port_ops m8xx_port_ops = {
-	.set_pio_mode		= m8xx_ide_set_pio_mode,
-};
-
-static void
-ide_interrupt_ack (void *dev)
-{
-#ifdef CONFIG_IDE_8xx_PCCARD
-	u_int pscr, pipr;
-
-#if (PCMCIA_SOCKETS_NO == 2)
-	u_int _slot_;
-#endif
-
-	/* get interrupt sources */
-
-	pscr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr;
-	pipr = ((volatile immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
-
-	/*
-	 * report only if both card detect signals are the same
-	 * not too nice done,
-	 * we depend on that CD2 is the bit to the left of CD1...
-	 */
-
-	if(_slot_==-1){
-	  printk("PCMCIA slot has not been defined! Using A as default\n");
-	  _slot_=0;
-	}
-
-	if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1) ^
-	   (pipr & M8XX_PCMCIA_CD1(_slot_))         ) {
-	  printk ("card detect interrupt\n");
-	}
-	/* clear the interrupt sources */
-	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr;
-
-#else /* ! CONFIG_IDE_8xx_PCCARD */
-	/*
-	 * Only CONFIG_IDE_8xx_PCCARD is using the interrupt of the
-	 * MPC8xx's PCMCIA controller, so there is nothing to be done here
-	 * for CONFIG_IDE_8xx_DIRECT and CONFIG_IDE_EXT_DIRECT.
-	 * The interrupt is handled somewhere else.	-- Steven
-	 */
-#endif /* CONFIG_IDE_8xx_PCCARD */
-}
-
-
-
-/*
- * CIS Tupel codes
- */
-#define CISTPL_NULL		0x00
-#define CISTPL_DEVICE		0x01
-#define CISTPL_LONGLINK_CB	0x02
-#define CISTPL_INDIRECT		0x03
-#define CISTPL_CONFIG_CB	0x04
-#define CISTPL_CFTABLE_ENTRY_CB 0x05
-#define CISTPL_LONGLINK_MFC	0x06
-#define CISTPL_BAR		0x07
-#define CISTPL_PWR_MGMNT	0x08
-#define CISTPL_EXTDEVICE	0x09
-#define CISTPL_CHECKSUM		0x10
-#define CISTPL_LONGLINK_A	0x11
-#define CISTPL_LONGLINK_C	0x12
-#define CISTPL_LINKTARGET	0x13
-#define CISTPL_NO_LINK		0x14
-#define CISTPL_VERS_1		0x15
-#define CISTPL_ALTSTR		0x16
-#define CISTPL_DEVICE_A		0x17
-#define CISTPL_JEDEC_C		0x18
-#define CISTPL_JEDEC_A		0x19
-#define CISTPL_CONFIG		0x1a
-#define CISTPL_CFTABLE_ENTRY	0x1b
-#define CISTPL_DEVICE_OC	0x1c
-#define CISTPL_DEVICE_OA	0x1d
-#define CISTPL_DEVICE_GEO	0x1e
-#define CISTPL_DEVICE_GEO_A	0x1f
-#define CISTPL_MANFID		0x20
-#define CISTPL_FUNCID		0x21
-#define CISTPL_FUNCE		0x22
-#define CISTPL_SWIL		0x23
-#define CISTPL_END		0xff
-
-/*
- * CIS Function ID codes
- */
-#define CISTPL_FUNCID_MULTI	0x00
-#define CISTPL_FUNCID_MEMORY	0x01
-#define CISTPL_FUNCID_SERIAL	0x02
-#define CISTPL_FUNCID_PARALLEL	0x03
-#define CISTPL_FUNCID_FIXED	0x04
-#define CISTPL_FUNCID_VIDEO	0x05
-#define CISTPL_FUNCID_NETWORK	0x06
-#define CISTPL_FUNCID_AIMS	0x07
-#define CISTPL_FUNCID_SCSI	0x08
-
-/*
- * Fixed Disk FUNCE codes
- */
-#define CISTPL_IDE_INTERFACE	0x01
-
-#define CISTPL_FUNCE_IDE_IFACE	0x01
-#define CISTPL_FUNCE_IDE_MASTER	0x02
-#define CISTPL_FUNCE_IDE_SLAVE	0x03
-
-/* First feature byte */
-#define CISTPL_IDE_SILICON	0x04
-#define CISTPL_IDE_UNIQUE	0x08
-#define CISTPL_IDE_DUAL		0x10
-
-/* Second feature byte */
-#define CISTPL_IDE_HAS_SLEEP	0x01
-#define CISTPL_IDE_HAS_STANDBY	0x02
-#define CISTPL_IDE_HAS_IDLE	0x04
-#define CISTPL_IDE_LOW_POWER	0x08
-#define CISTPL_IDE_REG_INHIBIT	0x10
-#define CISTPL_IDE_HAS_INDEX	0x20
-#define CISTPL_IDE_IOIS16	0x40
-
-
-/* -------------------------------------------------------------------- */
-
-
-#define	MAX_TUPEL_SZ	512
-#define MAX_FEATURES	4
-
-static int check_ide_device (unsigned long base)
-{
-	volatile u8 *ident = NULL;
-	volatile u8 *feature_p[MAX_FEATURES];
-	volatile u8 *p, *start;
-	int n_features = 0;
-	u8 func_id = ~0;
-	u8 code, len;
-	unsigned short config_base = 0;
-	int found = 0;
-	int i;
-
-#ifdef DEBUG
-	printk ("PCMCIA MEM: %08lX\n", base);
-#endif
-	start = p = (volatile u8 *) base;
-
-	while ((p - start) < MAX_TUPEL_SZ) {
-
-		code = *p; p += 2;
-
-		if (code == 0xFF) { /* End of chain */
-			break;
-		}
-
-		len = *p; p += 2;
-#ifdef	DEBUG_PCMCIA
-		{ volatile u8 *q = p;
-			printk ("\nTuple code %02x  length %d\n\tData:",
-				code, len);
-
-			for (i = 0; i < len; ++i) {
-				printk (" %02x", *q);
-				q+= 2;
-			}
-		}
-#endif	/* DEBUG_PCMCIA */
-		switch (code) {
-		case CISTPL_VERS_1:
-			ident = p + 4;
-			break;
-		case CISTPL_FUNCID:
-			func_id = *p;
-			break;
-		case CISTPL_FUNCE:
-			if (n_features < MAX_FEATURES)
-				feature_p[n_features++] = p;
-			break;
-		case CISTPL_CONFIG:
-			config_base = (*(p+6) << 8) + (*(p+4));
-		default:
-			break;
-		}
-		p += 2 * len;
-	}
-
-	found = identify (ident);
-
-	if (func_id != ((u8)~0)) {
-		print_funcid (func_id);
-
-		if (func_id == CISTPL_FUNCID_FIXED)
-			found = 1;
-		else
-			return (1);	/* no disk drive */
-	}
-
-	for (i=0; i<n_features; ++i) {
-		print_fixed (feature_p[i]);
-	}
-
-	if (!found) {
-		printk ("unknown card type\n");
-		return (1);
-	}
-
-	/* set level mode irq and I/O mapped device in config reg*/
-	*((u8 *)(base + config_base)) = 0x41;
-
-	return (0);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void print_funcid (int func)
-{
-	switch (func) {
-	case CISTPL_FUNCID_MULTI:
-		printk (" Multi-Function");
-		break;
-	case CISTPL_FUNCID_MEMORY:
-		printk (" Memory");
-		break;
-	case CISTPL_FUNCID_SERIAL:
-		printk (" Serial Port");
-		break;
-	case CISTPL_FUNCID_PARALLEL:
-		printk (" Parallel Port");
-		break;
-	case CISTPL_FUNCID_FIXED:
-		printk (" Fixed Disk");
-		break;
-	case CISTPL_FUNCID_VIDEO:
-		printk (" Video Adapter");
-		break;
-	case CISTPL_FUNCID_NETWORK:
-		printk (" Network Adapter");
-		break;
-	case CISTPL_FUNCID_AIMS:
-		printk (" AIMS Card");
-		break;
-	case CISTPL_FUNCID_SCSI:
-		printk (" SCSI Adapter");
-		break;
-	default:
-		printk (" Unknown");
-		break;
-	}
-	printk (" Card\n");
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void print_fixed (volatile u8 *p)
-{
-	if (p == NULL)
-		return;
-
-	switch (*p) {
-	case CISTPL_FUNCE_IDE_IFACE:
-	    {   u8 iface = *(p+2);
-
-		printk ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
-		printk (" interface ");
-		break;
-	    }
-	case CISTPL_FUNCE_IDE_MASTER:
-	case CISTPL_FUNCE_IDE_SLAVE:
-	    {   u8 f1 = *(p+2);
-		u8 f2 = *(p+4);
-
-		printk ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
-
-		if (f1 & CISTPL_IDE_UNIQUE)
-			printk (" [unique]");
-
-		printk ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
-
-		if (f2 & CISTPL_IDE_HAS_SLEEP)
-			printk (" [sleep]");
-
-		if (f2 & CISTPL_IDE_HAS_STANDBY)
-			printk (" [standby]");
-
-		if (f2 & CISTPL_IDE_HAS_IDLE)
-			printk (" [idle]");
-
-		if (f2 & CISTPL_IDE_LOW_POWER)
-			printk (" [low power]");
-
-		if (f2 & CISTPL_IDE_REG_INHIBIT)
-			printk (" [reg inhibit]");
-
-		if (f2 & CISTPL_IDE_HAS_INDEX)
-			printk (" [index]");
-
-		if (f2 & CISTPL_IDE_IOIS16)
-			printk (" [IOis16]");
-
-		break;
-	    }
-	}
-	printk ("\n");
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-#define MAX_IDENT_CHARS		64
-#define	MAX_IDENT_FIELDS	4
-
-static u8 *known_cards[] = {
-	"ARGOSY PnPIDE D5",
-	NULL
-};
-
-static int identify  (volatile u8 *p)
-{
-	u8 id_str[MAX_IDENT_CHARS];
-	u8 data;
-	u8 *t;
-	u8 **card;
-	int i, done;
-
-	if (p == NULL)
-		return (0);	/* Don't know */
-
-	t = id_str;
-	done =0;
-
-	for (i=0; i<=4 && !done; ++i, p+=2) {
-		while ((data = *p) != '\0') {
-			if (data == 0xFF) {
-				done = 1;
-				break;
-			}
-			*t++ = data;
-			if (t == &id_str[MAX_IDENT_CHARS-1]) {
-				done = 1;
-				break;
-			}
-			p += 2;
-		}
-		if (!done)
-			*t++ = ' ';
-	}
-	*t = '\0';
-	while (--t > id_str) {
-		if (*t == ' ')
-			*t = '\0';
-		else
-			break;
-	}
-	printk ("Card ID: %s\n", id_str);
-
-	for (card=known_cards; *card; ++card) {
-		if (strcmp(*card, id_str) == 0) {	/* found! */
-			return (1);
-		}
-	}
-
-	return (0);	/* don't know */
-}
-
-static int __init mpc8xx_ide_probe(void)
-{
-	hw_regs_t hw;
-	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-
-#ifdef IDE0_BASE_OFFSET
-	memset(&hw, 0, sizeof(hw));
-	if (!m8xx_ide_init_ports(&hw, 0)) {
-		ide_hwif_t *hwif = ide_find_port();
-
-		if (hwif) {
-			ide_init_port_hw(hwif, &hw);
-			hwif->pio_mask = ATA_PIO4;
-			hwif->port_ops = &m8xx_port_ops;
-
-			idx[0] = hwif->index;
-		}
-	}
-#ifdef IDE1_BASE_OFFSET
-	memset(&hw, 0, sizeof(hw));
-	if (!m8xx_ide_init_ports(&hw, 1)) {
-		ide_hwif_t *mate = ide_find_port();
-
-		if (mate) {
-			ide_init_port_hw(mate, &hw);
-			mate->pio_mask = ATA_PIO4;
-			mate->port_ops = &m8xx_port_ops;
-
-			idx[1] = mate->index;
-		}
-	}
-#endif
-#endif
-
-	ide_device_add(idx, NULL);
-
-	return 0;
-}
-
-module_init(mpc8xx_ide_probe);
-
-MODULE_LICENSE("GPL");

+ 8 - 13
drivers/ide/ppc/pmac.c

@@ -5,7 +5,7 @@
  * for doing DMA.
  * for doing DMA.
  *
  *
  *  Copyright (C) 1998-2003 Paul Mackerras & Ben. Herrenschmidt
  *  Copyright (C) 1998-2003 Paul Mackerras & Ben. Herrenschmidt
- *  Copyright (C)      2007 Bartlomiej Zolnierkiewicz
+ *  Copyright (C) 2007-2008 Bartlomiej Zolnierkiewicz
  *
  *
  *  This program is free software; you can redistribute it and/or
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
  *  modify it under the terms of the GNU General Public License
@@ -48,8 +48,6 @@
 #include <asm/mediabay.h>
 #include <asm/mediabay.h>
 #endif
 #endif
 
 
-#include "../ide-timing.h"
-
 #undef IDE_PMAC_DEBUG
 #undef IDE_PMAC_DEBUG
 
 
 #define DMA_WAIT_TIMEOUT	50
 #define DMA_WAIT_TIMEOUT	50
@@ -495,6 +493,7 @@ static void pmac_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port)
 static void
 static void
 pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
 {
+	struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio);
 	u32 *timings, t;
 	u32 *timings, t;
 	unsigned accessTicks, recTicks;
 	unsigned accessTicks, recTicks;
 	unsigned accessTime, recTime;
 	unsigned accessTime, recTime;
@@ -526,10 +525,9 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 		}
 		}
 	case controller_kl_ata4:
 	case controller_kl_ata4:
 		/* 66Mhz cell */
 		/* 66Mhz cell */
-		recTime = cycle_time - ide_pio_timings[pio].active_time
-				- ide_pio_timings[pio].setup_time;
+		recTime = cycle_time - tim->active - tim->setup;
 		recTime = max(recTime, 150U);
 		recTime = max(recTime, 150U);
-		accessTime = ide_pio_timings[pio].active_time;
+		accessTime = tim->active;
 		accessTime = max(accessTime, 150U);
 		accessTime = max(accessTime, 150U);
 		accessTicks = SYSCLK_TICKS_66(accessTime);
 		accessTicks = SYSCLK_TICKS_66(accessTime);
 		accessTicks = min(accessTicks, 0x1fU);
 		accessTicks = min(accessTicks, 0x1fU);
@@ -542,10 +540,9 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 	default: {
 	default: {
 		/* 33Mhz cell */
 		/* 33Mhz cell */
 		int ebit = 0;
 		int ebit = 0;
-		recTime = cycle_time - ide_pio_timings[pio].active_time
-				- ide_pio_timings[pio].setup_time;
+		recTime = cycle_time - tim->active - tim->setup;
 		recTime = max(recTime, 150U);
 		recTime = max(recTime, 150U);
-		accessTime = ide_pio_timings[pio].active_time;
+		accessTime = tim->active;
 		accessTime = max(accessTime, 150U);
 		accessTime = max(accessTime, 150U);
 		accessTicks = SYSCLK_TICKS(accessTime);
 		accessTicks = SYSCLK_TICKS(accessTime);
 		accessTicks = min(accessTicks, 0x1fU);
 		accessTicks = min(accessTicks, 0x1fU);
@@ -1151,8 +1148,6 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	base = ioremap(macio_resource_start(mdev, 0), 0x400);
 	base = ioremap(macio_resource_start(mdev, 0), 0x400);
 	regbase = (unsigned long) base;
 	regbase = (unsigned long) base;
 
 
-	hwif->dev = &mdev->bus->pdev->dev;
-
 	pmif->mdev = mdev;
 	pmif->mdev = mdev;
 	pmif->node = mdev->ofdev.node;
 	pmif->node = mdev->ofdev.node;
 	pmif->regbase = regbase;
 	pmif->regbase = regbase;
@@ -1174,7 +1169,8 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	memset(&hw, 0, sizeof(hw));
 	memset(&hw, 0, sizeof(hw));
 	pmac_ide_init_ports(&hw, pmif->regbase);
 	pmac_ide_init_ports(&hw, pmif->regbase);
 	hw.irq = irq;
 	hw.irq = irq;
-	hw.dev = &mdev->ofdev.dev;
+	hw.dev = &mdev->bus->pdev->dev;
+	hw.parent = &mdev->ofdev.dev;
 
 
 	rc = pmac_ide_setup_device(pmif, hwif, &hw);
 	rc = pmac_ide_setup_device(pmif, hwif, &hw);
 	if (rc != 0) {
 	if (rc != 0) {
@@ -1274,7 +1270,6 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 		goto out_free_pmif;
 		goto out_free_pmif;
 	}
 	}
 
 
-	hwif->dev = &pdev->dev;
 	pmif->mdev = NULL;
 	pmif->mdev = NULL;
 	pmif->node = np;
 	pmif->node = np;
 
 

+ 8 - 17
drivers/ide/setup-pci.c

@@ -6,19 +6,15 @@
  *  May be copied or modified under the terms of the GNU General Public License
  *  May be copied or modified under the terms of the GNU General Public License
  */
  */
 
 
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/init.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 
 
 #include <asm/io.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 
 
 /**
 /**
  *	ide_setup_pci_baseregs	-	place a PCI IDE controller native
  *	ide_setup_pci_baseregs	-	place a PCI IDE controller native
@@ -319,25 +315,22 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
 
 
 		ctl  = pci_resource_start(dev, 2*port+1);
 		ctl  = pci_resource_start(dev, 2*port+1);
 		base = pci_resource_start(dev, 2*port);
 		base = pci_resource_start(dev, 2*port);
-		if ((ctl && !base) || (base && !ctl)) {
-			printk(KERN_ERR "%s: inconsistent baseregs (BIOS) "
-				"for port %d, skipping\n", d->name, port);
-			return NULL;
-		}
-	}
-	if (!ctl) {
+	} else {
 		/* Use default values */
 		/* Use default values */
 		ctl = port ? 0x374 : 0x3f4;
 		ctl = port ? 0x374 : 0x3f4;
 		base = port ? 0x170 : 0x1f0;
 		base = port ? 0x170 : 0x1f0;
 	}
 	}
 
 
-	hwif = ide_find_port_slot(d);
-	if (hwif == NULL) {
-		printk(KERN_ERR "%s: too many IDE interfaces, no room in "
-				"table\n", d->name);
+	if (!base || !ctl) {
+		printk(KERN_ERR "%s: bad PCI BARs for port %d, skipping\n",
+				d->name, port);
 		return NULL;
 		return NULL;
 	}
 	}
 
 
+	hwif = ide_find_port_slot(d);
+	if (hwif == NULL)
+		return NULL;
+
 	memset(&hw, 0, sizeof(hw));
 	memset(&hw, 0, sizeof(hw));
 	hw.irq = irq;
 	hw.irq = irq;
 	hw.dev = &dev->dev;
 	hw.dev = &dev->dev;
@@ -346,8 +339,6 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
 
 
 	ide_init_port_hw(hwif, &hw);
 	ide_init_port_hw(hwif, &hw);
 
 
-	hwif->dev = &dev->dev;
-
 	return hwif;
 	return hwif;
 }
 }
 
 

+ 0 - 14
drivers/scsi/ide-scsi.c

@@ -258,19 +258,6 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 	return ide_stopped;
 	return ide_stopped;
 }
 }
 
 
-static ide_startstop_t
-idescsi_atapi_abort(ide_drive_t *drive, struct request *rq)
-{
-	debug_log("%s called for %lu\n", __func__,
-		((struct ide_atapi_pc *) rq->special)->scsi_cmd->serial_number);
-
-	rq->errors |= ERROR_MAX;
-
-	idescsi_end_request(drive, 0, 0);
-
-	return ide_stopped;
-}
-
 static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
 static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
 {
 {
 	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
 	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
@@ -524,7 +511,6 @@ static ide_driver_t idescsi_driver = {
 	.do_request		= idescsi_do_request,
 	.do_request		= idescsi_do_request,
 	.end_request		= idescsi_end_request,
 	.end_request		= idescsi_end_request,
 	.error                  = idescsi_atapi_error,
 	.error                  = idescsi_atapi_error,
-	.abort                  = idescsi_atapi_abort,
 #ifdef CONFIG_IDE_PROC_FS
 #ifdef CONFIG_IDE_PROC_FS
 	.proc			= idescsi_proc,
 	.proc			= idescsi_proc,
 #endif
 #endif

+ 44 - 30
include/linux/ide.h

@@ -138,6 +138,12 @@ struct ide_io_ports {
 #define WAIT_CMD	(10*HZ)	/* 10sec  - maximum wait for an IRQ to happen */
 #define WAIT_CMD	(10*HZ)	/* 10sec  - maximum wait for an IRQ to happen */
 #define WAIT_MIN_SLEEP	(2*HZ/100)	/* 20msec - minimum sleep time */
 #define WAIT_MIN_SLEEP	(2*HZ/100)	/* 20msec - minimum sleep time */
 
 
+/*
+ * Op codes for special requests to be handled by ide_special_rq().
+ * Values should be in the range of 0x20 to 0x3f.
+ */
+#define REQ_DRIVE_RESET		0x20
+
 /*
 /*
  * Check for an interrupt and acknowledge the interrupt status
  * Check for an interrupt and acknowledge the interrupt status
  */
  */
@@ -171,7 +177,7 @@ typedef struct hw_regs_s {
 	int		irq;			/* our irq number */
 	int		irq;			/* our irq number */
 	ide_ack_intr_t	*ack_intr;		/* acknowledge interrupt */
 	ide_ack_intr_t	*ack_intr;		/* acknowledge interrupt */
 	hwif_chipset_t  chipset;
 	hwif_chipset_t  chipset;
-	struct device	*dev;
+	struct device	*dev, *parent;
 } hw_regs_t;
 } hw_regs_t;
 
 
 void ide_init_port_data(struct hwif_s *, unsigned int);
 void ide_init_port_data(struct hwif_s *, unsigned int);
@@ -405,8 +411,8 @@ typedef struct ide_drive_s {
 struct ide_port_info;
 struct ide_port_info;
 
 
 struct ide_port_ops {
 struct ide_port_ops {
-	/* host specific initialization of devices on a port */
-	void	(*port_init_devs)(struct hwif_s *);
+	/* host specific initialization of a device */
+	void	(*init_dev)(ide_drive_t *);
 	/* routine to program host for PIO mode */
 	/* routine to program host for PIO mode */
 	void	(*set_pio_mode)(ide_drive_t *, const u8);
 	void	(*set_pio_mode)(ide_drive_t *, const u8);
 	/* routine to program host for DMA mode */
 	/* routine to program host for DMA mode */
@@ -565,8 +571,6 @@ typedef struct hwgroup_s {
 	unsigned int sleeping	: 1;
 	unsigned int sleeping	: 1;
 		/* BOOL: polling active & poll_timeout field valid */
 		/* BOOL: polling active & poll_timeout field valid */
 	unsigned int polling	: 1;
 	unsigned int polling	: 1;
-	 	/* BOOL: in a polling reset situation. Must not trigger another reset yet */
-	unsigned int resetting  : 1;
 
 
 		/* current drive */
 		/* current drive */
 	ide_drive_t *drive;
 	ide_drive_t *drive;
@@ -786,7 +790,6 @@ struct ide_driver_s {
 	ide_startstop_t	(*do_request)(ide_drive_t *, struct request *, sector_t);
 	ide_startstop_t	(*do_request)(ide_drive_t *, struct request *, sector_t);
 	int		(*end_request)(ide_drive_t *, int, int);
 	int		(*end_request)(ide_drive_t *, int, int);
 	ide_startstop_t	(*error)(ide_drive_t *, struct request *rq, u8, u8);
 	ide_startstop_t	(*error)(ide_drive_t *, struct request *rq, u8, u8);
-	ide_startstop_t	(*abort)(ide_drive_t *, struct request *rq);
 	struct device_driver	gen_driver;
 	struct device_driver	gen_driver;
 	int		(*probe)(ide_drive_t *);
 	int		(*probe)(ide_drive_t *);
 	void		(*remove)(ide_drive_t *);
 	void		(*remove)(ide_drive_t *);
@@ -801,18 +804,6 @@ struct ide_driver_s {
 
 
 int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long);
 int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long);
 
 
-/*
- * ide_hwifs[] is the master data structure used to keep track
- * of just about everything in ide.c.  Whenever possible, routines
- * should be using pointers to a drive (ide_drive_t *) or
- * pointers to a hwif (ide_hwif_t *), rather than indexing this
- * structure directly (the allocation/layout may change!).
- *
- */
-#ifndef _IDE_C
-extern	ide_hwif_t	ide_hwifs[];		/* master data repository */
-#endif
-
 extern int ide_vlb_clk;
 extern int ide_vlb_clk;
 extern int ide_pci_clk;
 extern int ide_pci_clk;
 
 
@@ -840,10 +831,6 @@ ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8);
 
 
 ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
 ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
 
 
-ide_startstop_t __ide_abort(ide_drive_t *, struct request *);
-
-extern ide_startstop_t ide_abort(ide_drive_t *, const char *);
-
 extern void ide_fix_driveid(struct hd_driveid *);
 extern void ide_fix_driveid(struct hd_driveid *);
 
 
 extern void ide_fixstring(u8 *, const int, const int);
 extern void ide_fixstring(u8 *, const int, const int);
@@ -1271,16 +1258,43 @@ static inline int ide_dev_is_sata(struct hd_driveid *id)
 u64 ide_get_lba_addr(struct ide_taskfile *, int);
 u64 ide_get_lba_addr(struct ide_taskfile *, int);
 u8 ide_dump_status(ide_drive_t *, const char *, u8);
 u8 ide_dump_status(ide_drive_t *, const char *, u8);
 
 
-typedef struct ide_pio_timings_s {
-	int	setup_time;	/* Address setup (ns) minimum */
-	int	active_time;	/* Active pulse (ns) minimum */
-	int	cycle_time;	/* Cycle time (ns) minimum = */
-				/* active + recovery (+ setup for some chips) */
-} ide_pio_timings_t;
+struct ide_timing {
+	u8  mode;
+	u8  setup;	/* t1 */
+	u16 act8b;	/* t2 for 8-bit io */
+	u16 rec8b;	/* t2i for 8-bit io */
+	u16 cyc8b;	/* t0 for 8-bit io */
+	u16 active;	/* t2 or tD */
+	u16 recover;	/* t2i or tK */
+	u16 cycle;	/* t0 */
+	u16 udma;	/* t2CYCTYP/2 */
+};
+
+enum {
+	IDE_TIMING_SETUP	= (1 << 0),
+	IDE_TIMING_ACT8B	= (1 << 1),
+	IDE_TIMING_REC8B	= (1 << 2),
+	IDE_TIMING_CYC8B	= (1 << 3),
+	IDE_TIMING_8BIT		= IDE_TIMING_ACT8B | IDE_TIMING_REC8B |
+				  IDE_TIMING_CYC8B,
+	IDE_TIMING_ACTIVE	= (1 << 4),
+	IDE_TIMING_RECOVER	= (1 << 5),
+	IDE_TIMING_CYCLE	= (1 << 6),
+	IDE_TIMING_UDMA		= (1 << 7),
+	IDE_TIMING_ALL		= IDE_TIMING_SETUP | IDE_TIMING_8BIT |
+				  IDE_TIMING_ACTIVE | IDE_TIMING_RECOVER |
+				  IDE_TIMING_CYCLE | IDE_TIMING_UDMA,
+};
+
+struct ide_timing *ide_timing_find_mode(u8);
+u16 ide_pio_cycle_time(ide_drive_t *, u8);
+void ide_timing_merge(struct ide_timing *, struct ide_timing *,
+		      struct ide_timing *, unsigned int);
+int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int);
+
+int ide_scan_pio_blacklist(char *);
 
 
-unsigned int ide_pio_cycle_time(ide_drive_t *, u8);
 u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
 u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
-extern const ide_pio_timings_t ide_pio_timings[6];
 
 
 int ide_set_pio_mode(ide_drive_t *, u8);
 int ide_set_pio_mode(ide_drive_t *, u8);
 int ide_set_dma_mode(ide_drive_t *, u8);
 int ide_set_dma_mode(ide_drive_t *, u8);