[kernel] r10402 - in dists/trunk/linux-2.6/debian/patches: bugfix/all series

Maximilian Attems maks at alioth.debian.org
Sun Feb 3 21:56:52 UTC 2008


Author: maks
Date: Sun Feb  3 21:56:41 2008
New Revision: 10402

Log:
update to patch-2.6.24-git13

ide merge + small fixes,
everyone flying out of au, thus calm..


Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git13
      - copied, changed from r10398, /dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git12
Removed:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git12
Modified:
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.1

Copied: dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git13 (from r10398, /dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git12)
==============================================================================
--- /dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git12	(original)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git13	Sun Feb  3 21:56:41 2008
@@ -2154,6 +2154,421 @@
 + * Ver 0.99  Feb 24 02   Remove duplicate code, modify clik! detection code
 + *                        to support new PocketZip drives
 + */
+diff --git a/Documentation/ide/ChangeLog.ide-tape.1995-2002 b/Documentation/ide/ChangeLog.ide-tape.1995-2002
+new file mode 100644
+index 0000000..877fac8
+--- /dev/null
++++ b/Documentation/ide/ChangeLog.ide-tape.1995-2002
+@@ -0,0 +1,257 @@
++/*
++ * Ver 0.1   Nov  1 95   Pre-working code :-)
++ * Ver 0.2   Nov 23 95   A short backup (few megabytes) and restore procedure
++ *                        was successful ! (Using tar cvf ... on the block
++ *                        device interface).
++ *                       A longer backup resulted in major swapping, bad
++ *                        overall Linux performance and eventually failed as
++ *                        we received non serial read-ahead requests from the
++ *                        buffer cache.
++ * Ver 0.3   Nov 28 95   Long backups are now possible, thanks to the
++ *                        character device interface. Linux's responsiveness
++ *                        and performance doesn't seem to be much affected
++ *                        from the background backup procedure.
++ *                       Some general mtio.h magnetic tape operations are
++ *                        now supported by our character device. As a result,
++ *                        popular tape utilities are starting to work with
++ *                        ide tapes :-)
++ *                       The following configurations were tested:
++ *                       1. An IDE ATAPI TAPE shares the same interface
++ *                        and irq with an IDE ATAPI CDROM.
++ *                       2. An IDE ATAPI TAPE shares the same interface
++ *                        and irq with a normal IDE disk.
++ *                        Both configurations seemed to work just fine !
++ *                        However, to be on the safe side, it is meanwhile
++ *                        recommended to give the IDE TAPE its own interface
++ *                        and irq.
++ *                       The one thing which needs to be done here is to
++ *                        add a "request postpone" feature to ide.c,
++ *                        so that we won't have to wait for the tape to finish
++ *                        performing a long media access (DSC) request (such
++ *                        as a rewind) before we can access the other device
++ *                        on the same interface. This effect doesn't disturb
++ *                        normal operation most of the time because read/write
++ *                        requests are relatively fast, and once we are
++ *                        performing one tape r/w request, a lot of requests
++ *                        from the other device can be queued and ide.c will
++ *			  service all of them after this single tape request.
++ * Ver 1.0   Dec 11 95   Integrated into Linux 1.3.46 development tree.
++ *                       On each read / write request, we now ask the drive
++ *                        if we can transfer a constant number of bytes
++ *                        (a parameter of the drive) only to its buffers,
++ *                        without causing actual media access. If we can't,
++ *                        we just wait until we can by polling the DSC bit.
++ *                        This ensures that while we are not transferring
++ *                        more bytes than the constant referred to above, the
++ *                        interrupt latency will not become too high and
++ *                        we won't cause an interrupt timeout, as happened
++ *                        occasionally in the previous version.
++ *                       While polling for DSC, the current request is
++ *                        postponed and ide.c is free to handle requests from
++ *                        the other device. This is handled transparently to
++ *                        ide.c. The hwgroup locking method which was used
++ *                        in the previous version was removed.
++ *                       Use of new general features which are provided by
++ *                        ide.c for use with atapi devices.
++ *                        (Programming done by Mark Lord)
++ *                       Few potential bug fixes (Again, suggested by Mark)
++ *                       Single character device data transfers are now
++ *                        not limited in size, as they were before.
++ *                       We are asking the tape about its recommended
++ *                        transfer unit and send a larger data transfer
++ *                        as several transfers of the above size.
++ *                        For best results, use an integral number of this
++ *                        basic unit (which is shown during driver
++ *                        initialization). I will soon add an ioctl to get
++ *                        this important parameter.
++ *                       Our data transfer buffer is allocated on startup,
++ *                        rather than before each data transfer. This should
++ *                        ensure that we will indeed have a data buffer.
++ * Ver 1.1   Dec 14 95   Fixed random problems which occurred when the tape
++ *                        shared an interface with another device.
++ *                        (poll_for_dsc was a complete mess).
++ *                       Removed some old (non-active) code which had
++ *                        to do with supporting buffer cache originated
++ *                        requests.
++ *                       The block device interface can now be opened, so
++ *                        that general ide driver features like the unmask
++ *                        interrupts flag can be selected with an ioctl.
++ *                        This is the only use of the block device interface.
++ *                       New fast pipelined operation mode (currently only on
++ *                        writes). When using the pipelined mode, the
++ *                        throughput can potentially reach the maximum
++ *                        tape supported throughput, regardless of the
++ *                        user backup program. On my tape drive, it sometimes
++ *                        boosted performance by a factor of 2. Pipelined
++ *                        mode is enabled by default, but since it has a few
++ *                        downfalls as well, you may want to disable it.
++ *                        A short explanation of the pipelined operation mode
++ *                        is available below.
++ * Ver 1.2   Jan  1 96   Eliminated pipelined mode race condition.
++ *                       Added pipeline read mode. As a result, restores
++ *                        are now as fast as backups.
++ *                       Optimized shared interface behavior. The new behavior
++ *                        typically results in better IDE bus efficiency and
++ *                        higher tape throughput.
++ *                       Pre-calculation of the expected read/write request
++ *                        service time, based on the tape's parameters. In
++ *                        the pipelined operation mode, this allows us to
++ *                        adjust our polling frequency to a much lower value,
++ *                        and thus to dramatically reduce our load on Linux,
++ *                        without any decrease in performance.
++ *                       Implemented additional mtio.h operations.
++ *                       The recommended user block size is returned by
++ *                        the MTIOCGET ioctl.
++ *                       Additional minor changes.
++ * Ver 1.3   Feb  9 96   Fixed pipelined read mode bug which prevented the
++ *                        use of some block sizes during a restore procedure.
++ *                       The character device interface will now present a
++ *                        continuous view of the media - any mix of block sizes
++ *                        during a backup/restore procedure is supported. The
++ *                        driver will buffer the requests internally and
++ *                        convert them to the tape's recommended transfer
++ *                        unit, making performance almost independent of the
++ *                        chosen user block size.
++ *                       Some improvements in error recovery.
++ *                       By cooperating with ide-dma.c, bus mastering DMA can
++ *                        now sometimes be used with IDE tape drives as well.
++ *                        Bus mastering DMA has the potential to dramatically
++ *                        reduce the CPU's overhead when accessing the device,
++ *                        and can be enabled by using hdparm -d1 on the tape's
++ *                        block device interface. For more info, read the
++ *                        comments in ide-dma.c.
++ * Ver 1.4   Mar 13 96   Fixed serialize support.
++ * Ver 1.5   Apr 12 96   Fixed shared interface operation, broken in 1.3.85.
++ *                       Fixed pipelined read mode inefficiency.
++ *                       Fixed nasty null dereferencing bug.
++ * Ver 1.6   Aug 16 96   Fixed FPU usage in the driver.
++ *                       Fixed end of media bug.
++ * Ver 1.7   Sep 10 96   Minor changes for the CONNER CTT8000-A model.
++ * Ver 1.8   Sep 26 96   Attempt to find a better balance between good
++ *                        interactive response and high system throughput.
++ * Ver 1.9   Nov  5 96   Automatically cross encountered filemarks rather
++ *                        than requiring an explicit FSF command.
++ *                       Abort pending requests at end of media.
++ *                       MTTELL was sometimes returning incorrect results.
++ *                       Return the real block size in the MTIOCGET ioctl.
++ *                       Some error recovery bug fixes.
++ * Ver 1.10  Nov  5 96   Major reorganization.
++ *                       Reduced CPU overhead a bit by eliminating internal
++ *                        bounce buffers.
++ *                       Added module support.
++ *                       Added multiple tape drives support.
++ *                       Added partition support.
++ *                       Rewrote DSC handling.
++ *                       Some portability fixes.
++ *                       Removed ide-tape.h.
++ *                       Additional minor changes.
++ * Ver 1.11  Dec  2 96   Bug fix in previous DSC timeout handling.
++ *                       Use ide_stall_queue() for DSC overlap.
++ *                       Use the maximum speed rather than the current speed
++ *                        to compute the request service time.
++ * Ver 1.12  Dec  7 97   Fix random memory overwriting and/or last block data
++ *                        corruption, which could occur if the total number
++ *                        of bytes written to the tape was not an integral
++ *                        number of tape blocks.
++ *                       Add support for INTERRUPT DRQ devices.
++ * Ver 1.13  Jan  2 98   Add "speed == 0" work-around for HP COLORADO 5GB
++ * Ver 1.14  Dec 30 98   Partial fixes for the Sony/AIWA tape drives.
++ *                       Replace cli()/sti() with hwgroup spinlocks.
++ * Ver 1.15  Mar 25 99   Fix SMP race condition by replacing hwgroup
++ *                        spinlock with private per-tape spinlock.
++ * Ver 1.16  Sep  1 99   Add OnStream tape support.
++ *                       Abort read pipeline on EOD.
++ *                       Wait for the tape to become ready in case it returns
++ *                        "in the process of becoming ready" on open().
++ *                       Fix zero padding of the last written block in
++ *                        case the tape block size is larger than PAGE_SIZE.
++ *                       Decrease the default disconnection time to tn.
++ * Ver 1.16e Oct  3 99   Minor fixes.
++ * Ver 1.16e1 Oct 13 99  Patches by Arnold Niessen,
++ *                          niessen at iae.nl / arnold.niessen at philips.com
++ *                   GO-1)  Undefined code in idetape_read_position
++ *				according to Gadi's email
++ *                   AJN-1) Minor fix asc == 11 should be asc == 0x11
++ *                               in idetape_issue_packet_command (did effect
++ *                               debugging output only)
++ *                   AJN-2) Added more debugging output, and
++ *                              added ide-tape: where missing. I would also
++ *				like to add tape->name where possible
++ *                   AJN-3) Added different debug_level's
++ *                              via /proc/ide/hdc/settings
++ *				"debug_level" determines amount of debugging output;
++ *				can be changed using /proc/ide/hdx/settings
++ *				0 : almost no debugging output
++ *				1 : 0+output errors only
++ *				2 : 1+output all sensekey/asc
++ *				3 : 2+follow all chrdev related procedures
++ *				4 : 3+follow all procedures
++ *				5 : 4+include pc_stack rq_stack info
++ *				6 : 5+USE_COUNT updates
++ *                   AJN-4) Fixed timeout for retension in idetape_queue_pc_tail
++ *				from 5 to 10 minutes
++ *                   AJN-5) Changed maximum number of blocks to skip when
++ *                              reading tapes with multiple consecutive write
++ *                              errors from 100 to 1000 in idetape_get_logical_blk
++ *                   Proposed changes to code:
++ *                   1) output "logical_blk_num" via /proc
++ *                   2) output "current_operation" via /proc
++ *                   3) Either solve or document the fact that `mt rewind' is
++ *                      required after reading from /dev/nhtx to be
++ *			able to rmmod the idetape module;
++ *			Also, sometimes an application finishes but the
++ *			device remains `busy' for some time. Same cause ?
++ *                   Proposed changes to release-notes:
++ *		     4) write a simple `quickstart' section in the
++ *                      release notes; I volunteer if you don't want to
++ *		     5) include a pointer to video4linux in the doc
++ *                      to stimulate video applications
++ *                   6) release notes lines 331 and 362: explain what happens
++ *			if the application data rate is higher than 1100 KB/s;
++ *			similar approach to lower-than-500 kB/s ?
++ *		     7) 6.6 Comparison; wouldn't it be better to allow different
++ *			strategies for read and write ?
++ *			Wouldn't it be better to control the tape buffer
++ *			contents instead of the bandwidth ?
++ *		     8) line 536: replace will by would (if I understand
++ *			this section correctly, a hypothetical and unwanted situation
++ *			 is being described)
++ * Ver 1.16f Dec 15 99   Change place of the secondary OnStream header frames.
++ * Ver 1.17  Nov 2000 / Jan 2001  Marcel Mol, marcel at mesa.nl
++ *			- Add idetape_onstream_mode_sense_tape_parameter_page
++ *			  function to get tape capacity in frames: tape->capacity.
++ *			- Add support for DI-50 drives( or any DI- drive).
++ *			- 'workaround' for read error/blank block around block 3000.
++ *			- Implement Early warning for end of media for Onstream.
++ *			- Cosmetic code changes for readability.
++ *			- Idetape_position_tape should not use SKIP bit during
++ *			  Onstream read recovery.
++ *			- Add capacity, logical_blk_num and first/last_frame_position
++ *			  to /proc/ide/hd?/settings.
++ *			- Module use count was gone in the Linux 2.4 driver.
++ * Ver 1.17a Apr 2001 Willem Riede osst at riede.org
++ *			- Get drive's actual block size from mode sense block descriptor
++ *			- Limit size of pipeline
++ * Ver 1.17b Oct 2002   Alan Stern <stern at rowland.harvard.edu>
++ *			Changed IDETAPE_MIN_PIPELINE_STAGES to 1 and actually used
++ *			 it in the code!
++ *			Actually removed aborted stages in idetape_abort_pipeline
++ *			 instead of just changing the command code.
++ *			Made the transfer byte count for Request Sense equal to the
++ *			 actual length of the data transfer.
++ *			Changed handling of partial data transfers: they do not
++ *			 cause DMA errors.
++ *			Moved initiation of DMA transfers to the correct place.
++ *			Removed reference to unallocated memory.
++ *			Made __idetape_discard_read_pipeline return the number of
++ *			 sectors skipped, not the number of stages.
++ *			Replaced errant kfree() calls with __idetape_kfree_stage().
++ *			Fixed off-by-one error in testing the pipeline length.
++ *			Fixed handling of filemarks in the read pipeline.
++ *			Small code optimization for MTBSF and MTBSFM ioctls.
++ *			Don't try to unlock the door during device close if is
++ *			 already unlocked!
++ *			Cosmetic fixes to miscellaneous debugging output messages.
++ *			Set the minimum /proc/ide/hd?/settings values for "pipeline",
++ *			 "pipeline_min", and "pipeline_max" to 1.
++ */
+diff --git a/Documentation/ide/ide-tape.txt b/Documentation/ide/ide-tape.txt
+new file mode 100644
+index 0000000..658f271
+--- /dev/null
++++ b/Documentation/ide/ide-tape.txt
+@@ -0,0 +1,146 @@
++/*
++ * IDE ATAPI streaming tape driver.
++ *
++ * This driver is a part of the Linux ide driver.
++ *
++ * The driver, in co-operation with ide.c, basically traverses the
++ * request-list for the block device interface. The character device
++ * interface, on the other hand, creates new requests, adds them
++ * to the request-list of the block device, and waits for their completion.
++ *
++ * Pipelined operation mode is now supported on both reads and writes.
++ *
++ * The block device major and minor numbers are determined from the
++ * tape's relative position in the ide interfaces, as explained in ide.c.
++ *
++ * The character device interface consists of the following devices:
++ *
++ * ht0		major 37, minor 0	first  IDE tape, rewind on close.
++ * ht1		major 37, minor 1	second IDE tape, rewind on close.
++ * ...
++ * nht0		major 37, minor 128	first  IDE tape, no rewind on close.
++ * nht1		major 37, minor 129	second IDE tape, no rewind on close.
++ * ...
++ *
++ * The general magnetic tape commands compatible interface, as defined by
++ * include/linux/mtio.h, is accessible through the character device.
++ *
++ * General ide driver configuration options, such as the interrupt-unmask
++ * flag, can be configured by issuing an ioctl to the block device interface,
++ * as any other ide device.
++ *
++ * Our own ide-tape ioctl's can be issued to either the block device or
++ * the character device interface.
++ *
++ * Maximal throughput with minimal bus load will usually be achieved in the
++ * following scenario:
++ *
++ *	1.	ide-tape is operating in the pipelined operation mode.
++ *	2.	No buffering is performed by the user backup program.
++ *
++ * Testing was done with a 2 GB CONNER CTMA 4000 IDE ATAPI Streaming Tape Drive.
++ *
++ * Here are some words from the first releases of hd.c, which are quoted
++ * in ide.c and apply here as well:
++ *
++ * | Special care is recommended.  Have Fun!
++ *
++ *
++ * An overview of the pipelined operation mode.
++ *
++ * In the pipelined write mode, we will usually just add requests to our
++ * pipeline and return immediately, before we even start to service them. The
++ * user program will then have enough time to prepare the next request while
++ * we are still busy servicing previous requests. In the pipelined read mode,
++ * the situation is similar - we add read-ahead requests into the pipeline,
++ * before the user even requested them.
++ *
++ * The pipeline can be viewed as a "safety net" which will be activated when
++ * the system load is high and prevents the user backup program from keeping up
++ * with the current tape speed. At this point, the pipeline will get
++ * shorter and shorter but the tape will still be streaming at the same speed.
++ * Assuming we have enough pipeline stages, the system load will hopefully
++ * decrease before the pipeline is completely empty, and the backup program
++ * will be able to "catch up" and refill the pipeline again.
++ *
++ * When using the pipelined mode, it would be best to disable any type of
++ * buffering done by the user program, as ide-tape already provides all the
++ * benefits in the kernel, where it can be done in a more efficient way.
++ * As we will usually not block the user program on a request, the most
++ * efficient user code will then be a simple read-write-read-... cycle.
++ * Any additional logic will usually just slow down the backup process.
++ *
++ * Using the pipelined mode, I get a constant over 400 KBps throughput,
++ * which seems to be the maximum throughput supported by my tape.
++ *
++ * However, there are some downfalls:
++ *
++ *	1.	We use memory (for data buffers) in proportional to the number
++ *		of pipeline stages (each stage is about 26 KB with my tape).
++ *	2.	In the pipelined write mode, we cheat and postpone error codes
++ *		to the user task. In read mode, the actual tape position
++ *		will be a bit further than the last requested block.
++ *
++ * Concerning (1):
++ *
++ *	1.	We allocate stages dynamically only when we need them. When
++ *		we don't need them, we don't consume additional memory. In
++ *		case we can't allocate stages, we just manage without them
++ *		(at the expense of decreased throughput) so when Linux is
++ *		tight in memory, we will not pose additional difficulties.
++ *
++ *	2.	The maximum number of stages (which is, in fact, the maximum
++ *		amount of memory) which we allocate is limited by the compile
++ *		time parameter IDETAPE_MAX_PIPELINE_STAGES.
++ *
++ *	3.	The maximum number of stages is a controlled parameter - We
++ *		don't start from the user defined maximum number of stages
++ *		but from the lower IDETAPE_MIN_PIPELINE_STAGES (again, we
++ *		will not even allocate this amount of stages if the user
++ *		program can't handle the speed). We then implement a feedback
++ *		loop which checks if the pipeline is empty, and if it is, we
++ *		increase the maximum number of stages as necessary until we
++ *		reach the optimum value which just manages to keep the tape
++ *		busy with minimum allocated memory or until we reach
++ *		IDETAPE_MAX_PIPELINE_STAGES.
++ *
++ * Concerning (2):
++ *
++ *	In pipelined write mode, ide-tape can not return accurate error codes
++ *	to the user program since we usually just add the request to the
++ *      pipeline without waiting for it to be serviced. In case an error
++ *      occurs, I will report it on the next user request.
++ *
++ *	In the pipelined read mode, subsequent read requests or forward
++ *	filemark spacing will perform correctly, as we preserve all blocks
++ *	and filemarks which we encountered during our excess read-ahead.
++ *
++ *	For accurate tape positioning and error reporting, disabling
++ *	pipelined mode might be the best option.
++ *
++ * You can enable/disable/tune the pipelined operation mode by adjusting
++ * the compile time parameters below.
++ *
++ *
++ *	Possible improvements.
++ *
++ *	1.	Support for the ATAPI overlap protocol.
++ *
++ *		In order to maximize bus throughput, we currently use the DSC
++ *		overlap method which enables ide.c to service requests from the
++ *		other device while the tape is busy executing a command. The
++ *		DSC overlap method involves polling the tape's status register
++ *		for the DSC bit, and servicing the other device while the tape
++ *		isn't ready.
++ *
++ *		In the current QIC development standard (December 1995),
++ *		it is recommended that new tape drives will *in addition*
++ *		implement the ATAPI overlap protocol, which is used for the
++ *		same purpose - efficient use of the IDE bus, but is interrupt
++ *		driven and thus has much less CPU overhead.
++ *
++ *		ATAPI overlap is likely to be supported in most new ATAPI
++ *		devices, including new ATAPI cdroms, and thus provides us
++ *		a method by which we can achieve higher throughput when
++ *		sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
++ */
 diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
 index 5c7fbf9..c18363b 100644
 --- a/Documentation/ioctl-number.txt
@@ -396279,10 +396694,10 @@
  
  static int i2cdev_ioctl(struct inode *inode, struct file *file,
 diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
-index fb06555..e42a465 100644
+index fb06555..45b26ed 100644
 --- a/drivers/ide/Kconfig
 +++ b/drivers/ide/Kconfig
-@@ -206,6 +206,15 @@ config BLK_DEV_IDECD
+@@ -206,9 +206,17 @@ config BLK_DEV_IDECD
  	  To compile this driver as a module, choose M here: the
  	  module will be called ide-cd.
  
@@ -396296,9 +396711,13 @@
 +	  memory, though.
 +
  config BLK_DEV_IDETAPE
- 	tristate "Include IDE/ATAPI TAPE support (EXPERIMENTAL)"
- 	depends on EXPERIMENTAL
-@@ -325,7 +334,7 @@ config BLK_DEV_PLATFORM
+-	tristate "Include IDE/ATAPI TAPE support (EXPERIMENTAL)"
+-	depends on EXPERIMENTAL
++	tristate "Include IDE/ATAPI TAPE support"
+ 	help
+ 	  If you have an IDE tape drive using the ATAPI protocol, say Y.
+ 	  ATAPI is a newer protocol used by IDE tape and CD-ROM drives,
+@@ -325,7 +333,7 @@ config BLK_DEV_PLATFORM
  	  If unsure, say N.
  
  config BLK_DEV_CMD640
@@ -396307,7 +396726,7 @@
  	depends on X86
  	---help---
  	  The CMD-Technologies CMD640 IDE chip is used on many common 486 and
-@@ -359,9 +368,8 @@ config BLK_DEV_CMD640_ENHANCED
+@@ -359,9 +367,8 @@ config BLK_DEV_CMD640_ENHANCED
  	  Otherwise say N.
  
  config BLK_DEV_IDEPNP
@@ -396318,7 +396737,7 @@
  	help
  	  If you have a PnP (Plug and Play) compatible EIDE card and
  	  would like the kernel to automatically detect and activate
-@@ -374,19 +382,20 @@ comment "PCI IDE chipsets support"
+@@ -374,19 +381,20 @@ comment "PCI IDE chipsets support"
  config BLK_DEV_IDEPCI
  	bool
  
@@ -396349,7 +396768,7 @@
  
  # TODO: split it on per host driver config options (or module parameters)
  config BLK_DEV_OFFBOARD
-@@ -617,8 +626,8 @@ config BLK_DEV_SC1200
+@@ -617,8 +625,8 @@ config BLK_DEV_SC1200
  	tristate "National SCx200 chipset support"
  	select BLK_DEV_IDEDMA_PCI
  	help
@@ -396360,7 +396779,7 @@
  
  config BLK_DEV_PIIX
  	tristate "Intel PIIXn chipsets support"
-@@ -707,7 +716,6 @@ config BLK_DEV_SVWKS
+@@ -707,7 +715,6 @@ config BLK_DEV_SVWKS
  config BLK_DEV_SGIIOC4
  	tristate "Silicon Graphics IOC4 chipset ATA/ATAPI support"
  	depends on (IA64_SGI_SN2 || IA64_GENERIC) && SGI_IOC4
@@ -396368,7 +396787,7 @@
  	select BLK_DEV_IDEDMA_PCI
  	help
  	  This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4
-@@ -794,22 +802,22 @@ config BLK_DEV_CELLEB
+@@ -794,22 +801,22 @@ config BLK_DEV_CELLEB
  	depends on PPC_CELLEB
  	select BLK_DEV_IDEDMA_PCI
  	help
@@ -396395,7 +396814,7 @@
  	depends on BLK_DEV_IDE_PMAC
  	help
  	  This option will cause the ATA/100 controller found in UniNorth2
-@@ -824,7 +832,7 @@ config BLK_DEV_IDEDMA_PMAC
+@@ -824,7 +831,7 @@ config BLK_DEV_IDEDMA_PMAC
  	depends on BLK_DEV_IDE_PMAC
  	select BLK_DEV_IDEDMA_PCI
  	help
@@ -396404,7 +396823,7 @@
  	  Power Macintoshes and PowerBooks to use DMA (direct memory access)
  	  to transfer data to and from memory.  Saying Y is safe and improves
  	  performance.
-@@ -855,8 +863,9 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
+@@ -855,8 +862,9 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
         depends on BLK_DEV_IDE_AU1XXX
  
  config IDE_ARM
@@ -396416,7 +396835,7 @@
  
  config BLK_DEV_IDE_ICSIDE
  	tristate "ICS IDE interface support"
-@@ -888,10 +897,9 @@ config BLK_DEV_IDE_BAST
+@@ -888,10 +896,9 @@ config BLK_DEV_IDE_BAST
  	  Simtec BAST or the Thorcom VR1000
  
  config ETRAX_IDE
@@ -396428,7 +396847,7 @@
  	help
  	  Enables the ETRAX IDE driver.
  
-@@ -923,21 +931,19 @@ config ETRAX_IDE_G27_RESET
+@@ -923,21 +930,19 @@ config ETRAX_IDE_G27_RESET
  endchoice
  
  config IDE_H8300
@@ -396453,7 +396872,7 @@
  	  A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion
  	  bus (M-Tech E-Matrix 530 expansion card).
  	  Say Y if you have an Amiga with a Gayle IDE interface and want to use
-@@ -951,10 +957,10 @@ config BLK_DEV_IDEDOUBLER
+@@ -951,10 +956,10 @@ config BLK_DEV_IDEDOUBLER
  	depends on BLK_DEV_GAYLE && EXPERIMENTAL
  	---help---
  	  This driver provides support for the so-called `IDE doublers' (made
@@ -396468,7 +396887,7 @@
  
  	  Note that the normal Amiga Gayle IDE driver may not work correctly
  	  if you have an IDE doubler and don't enable this driver!
-@@ -963,55 +969,50 @@ config BLK_DEV_IDEDOUBLER
+@@ -963,55 +968,50 @@ config BLK_DEV_IDEDOUBLER
  	  runtime using the "ide=doubler" kernel boot parameter.
  
  config BLK_DEV_BUDDHA
@@ -396536,7 +396955,7 @@
  	help
  	  This option provides support for IDE on Motorola MPC8xx Systems.
  	  Please see 'Type of MPC8xx IDE interface' for details.
-@@ -1070,8 +1071,8 @@ config BLK_DEV_ALI14XX
+@@ -1070,8 +1070,8 @@ config BLK_DEV_ALI14XX
  	  boot parameter.  It enables support for the secondary IDE interface
  	  of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster
  	  I/O speeds to be set as well.  See the files
@@ -396547,7 +396966,7 @@
  
  config BLK_DEV_DTC2278
  	tristate "DTC-2278 support"
-@@ -1096,8 +1097,8 @@ config BLK_DEV_QD65XX
+@@ -1096,8 +1096,8 @@ config BLK_DEV_QD65XX
  	help
  	  This driver is enabled at runtime using the "qd65xx.probe" kernel
  	  boot parameter.  It permits faster I/O speeds to be set.  See the
@@ -396662,7 +397081,7 @@
 +
  EXTRA_CFLAGS	:= -Idrivers/ide
 diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
-index 48db616..037300f 100644
+index 48db616..0e7574c 100644
 --- a/drivers/ide/arm/bast-ide.c
 +++ b/drivers/ide/arm/bast-ide.c
 @@ -1,5 +1,4 @@
@@ -396672,17 +397091,45 @@
   * Copyright (c) 2003-2004 Simtec Electronics
   *  Ben Dooks <ben at simtec.co.uk>
   *
-@@ -45,7 +44,7 @@ bastide_register(unsigned int base, unsigned int aux, int irq,
+@@ -29,8 +28,10 @@ static int __init
+ bastide_register(unsigned int base, unsigned int aux, int irq,
+ 		 ide_hwif_t **hwif)
+ {
++	ide_hwif_t *hwif;
+ 	hw_regs_t hw;
+ 	int i;
++	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ 
+ 	memset(&hw, 0, sizeof(hw));
+ 
+@@ -45,8 +46,24 @@ bastide_register(unsigned int base, unsigned int aux, int irq,
  	hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
  	hw.irq = irq;
  
 -	ide_register_hw(&hw, NULL, 0, hwif);
-+	ide_register_hw(&hw, NULL, hwif);
++	hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
++	if (hwif == NULL)
++		goto out;
++
++	i = hwif->index;
++
++	if (hwif->present)
++		ide_unregister(i, 0, 0);
++	else if (!hwif->hold)
++		ide_init_port_data(hwif, i);
++
++	ide_init_port_hw(hwif, &hw);
++	hwif->quirkproc = NULL;
++
++	idx[0] = i;
  
++	ide_device_add(idx, NULL);
++out:
  	return 0;
  }
+ 
 diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
-index 93f71fc..8d2cc47 100644
+index 93f71fc..fb00f38 100644
 --- a/drivers/ide/arm/icside.c
 +++ b/drivers/ide/arm/icside.c
 @@ -1,6 +1,4 @@
@@ -396830,7 +397277,14 @@
  
  	drive->waiting_for_dma = 1;
  
-@@ -424,10 +384,7 @@ static void icside_dma_init(ide_hwif_t *hwif)
+@@ -417,17 +377,11 @@ static void icside_dma_lost_irq(ide_drive_t *drive)
+ 
+ static void icside_dma_init(ide_hwif_t *hwif)
+ {
+-	hwif->mwdma_mask	= 7; /* MW0..2 */
+-	hwif->swdma_mask	= 7; /* SW0..2 */
+-
+ 	hwif->dmatable_cpu	= NULL;
  	hwif->dmatable_dma	= 0;
  	hwif->set_dma_mode	= icside_set_dma_mode;
  
@@ -396842,7 +397296,7 @@
  	hwif->dma_setup		= icside_dma_setup;
  	hwif->dma_exec_cmd	= icside_dma_exec_cmd;
  	hwif->dma_start		= icside_dma_start;
-@@ -465,6 +422,7 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e
+@@ -465,6 +419,7 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e
  		hwif->noprobe = 0;
  		hwif->chipset = ide_acorn;
  		hwif->gendev.parent = &ec->dev;
@@ -396850,7 +397304,70 @@
  	}
  
  	return hwif;
-@@ -612,7 +570,6 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id)
+@@ -501,11 +456,19 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
+ 
+ 	idx[0] = hwif->index;
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, NULL);
+ 
+ 	return 0;
+ }
+ 
++static const struct ide_port_info icside_v6_port_info __initdata = {
++	.host_flags		= IDE_HFLAG_SERIALIZE |
++				  IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
++				  IDE_HFLAG_NO_AUTOTUNE,
++	.mwdma_mask		= ATA_MWDMA2,
++	.swdma_mask		= ATA_SWDMA2,
++};
++
+ static int __init
+ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
+ {
+@@ -514,6 +477,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
+ 	unsigned int sel = 0;
+ 	int ret;
+ 	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
++	struct ide_port_info d = icside_v6_port_info;
+ 
+ 	ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
+ 	if (!ioc_base) {
+@@ -563,30 +527,25 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
+ 	state->hwif[1]    = mate;
+ 
+ 	hwif->maskproc    = icside_maskproc;
+-	hwif->channel     = 0;
+ 	hwif->hwif_data   = state;
+-	hwif->mate        = mate;
+-	hwif->serialized  = 1;
+ 	hwif->config_data = (unsigned long)ioc_base;
+ 	hwif->select_data = sel;
+ 
+ 	mate->maskproc    = icside_maskproc;
+-	mate->channel     = 1;
+ 	mate->hwif_data   = state;
+-	mate->mate        = hwif;
+-	mate->serialized  = 1;
+ 	mate->config_data = (unsigned long)ioc_base;
+ 	mate->select_data = sel | 1;
+ 
+ 	if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
+ 		icside_dma_init(hwif);
+ 		icside_dma_init(mate);
+-	}
++	} else
++		d.mwdma_mask = d.swdma_mask = 0;
+ 
+ 	idx[0] = hwif->index;
+ 	idx[1] = mate->index;
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, &d);
+ 
+ 	return 0;
+ 
+@@ -612,7 +571,6 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id)
  	}
  
  	state->type	= ICS_TYPE_NOTYPE;
@@ -396859,7 +397376,7 @@
  	idmem = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
  	if (idmem) {
 diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
-index 8957cba..60f2497 100644
+index 8957cba..43a70e9 100644
 --- a/drivers/ide/arm/ide_arm.c
 +++ b/drivers/ide/arm/ide_arm.c
 @@ -24,12 +24,25 @@
@@ -396883,7 +397400,7 @@
 +		ide_init_port_hw(hwif, &hw);
 +		idx[0] = hwif->index;
 +
-+		ide_device_add(idx);
++		ide_device_add(idx, NULL);
 +	}
 +
 +	return 0;
@@ -396891,7 +397408,7 @@
 +
 +module_init(ide_arm_init);
 diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
-index 0775a3a..c8b6581 100644
+index 0775a3a..efba00d 100644
 --- a/drivers/ide/arm/rapide.c
 +++ b/drivers/ide/arm/rapide.c
 @@ -1,6 +1,4 @@
@@ -396941,7 +397458,7 @@
  
  	ret = ecard_request_resources(ec);
  	if (ret)
-@@ -53,11 +44,17 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
+@@ -53,15 +44,21 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
  		goto release;
  	}
  
@@ -396963,13 +397480,18 @@
  
  		idx[0] = hwif->index;
  
+-		ide_device_add(idx);
++		ide_device_add(idx, NULL);
+ 
+ 		ecard_set_drvdata(ec, hwif);
+ 		goto out;
 @@ -79,8 +76,8 @@ static void __devexit rapide_remove(struct expansion_card *ec)
  
  	ecard_set_drvdata(ec, NULL);
  
 -	/* there must be a better way */
 -	ide_unregister(hwif - ide_hwifs);
-+	ide_unregister(hwif->index);
++	ide_unregister(hwif->index, 0, 0);
 +
  	ecard_release_resources(ec);
  }
@@ -396984,7 +397506,7 @@
 -obj-y					+= ide-cris.o
 +obj-$(CONFIG_IDE_ETRAX)			+= ide-cris.o
 diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
-index 476e0d6..0640a38 100644
+index 476e0d6..00587a8 100644
 --- a/drivers/ide/cris/ide-cris.c
 +++ b/drivers/ide/cris/ide-cris.c
 @@ -1,5 +1,4 @@
@@ -397014,12 +397536,21 @@
  	}
  
  	if (speed >= XFER_UDMA_0)
-@@ -757,13 +753,11 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -757,13 +753,20 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
  		cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
  }
  
 -void __init
 -init_e100_ide (void)
++static const struct ide_port_info cris_port_info __initdata = {
++	.chipset		= ide_etrax100,
++	.host_flags		= IDE_HFLAG_NO_ATAPI_DMA |
++				  IDE_HFLAG_NO_DMA, /* no SFF-style DMA */
++	.pio_mask		= ATA_PIO4,
++	.udma_mask		= cris_ultra_mask,
++	.mwdma_mask		= ATA_MWDMA2,
++};
++
 +static int __init init_e100_ide(void)
  {
  	hw_regs_t hw;
@@ -397031,7 +397562,7 @@
  
  	printk("ide: ETRAX FS built-in ATA DMA controller\n");
  
-@@ -780,9 +774,11 @@ init_e100_ide (void)
+@@ -780,17 +783,19 @@ init_e100_ide (void)
  		                ide_offsets,
  		                0, 0, cris_ide_ack_intr,
  		                ide_default_irq(0));
@@ -397042,9 +397573,10 @@
 +		ide_init_port_data(hwif, hwif->index);
 +		ide_init_port_hw(hwif, &hw);
  		hwif->mmio = 1;
- 		hwif->chipset = ide_etrax100;
+-		hwif->chipset = ide_etrax100;
  		hwif->set_pio_mode = &cris_set_pio_mode;
-@@ -791,6 +787,7 @@ init_e100_ide (void)
+ 		hwif->set_dma_mode = &cris_set_dma_mode;
+ 		hwif->ata_input_data = &cris_ide_input_data;
  		hwif->ata_output_data = &cris_ide_output_data;
  		hwif->atapi_input_bytes = &cris_atapi_input_bytes;
  		hwif->atapi_output_bytes = &cris_atapi_output_bytes;
@@ -397052,7 +397584,7 @@
  		hwif->ide_dma_end = &cris_dma_end;
  		hwif->dma_setup = &cris_dma_setup;
  		hwif->dma_exec_cmd = &cris_dma_exec_cmd;
-@@ -801,9 +798,6 @@ init_e100_ide (void)
+@@ -801,16 +806,9 @@ init_e100_ide (void)
  		hwif->OUTBSYNC = &cris_ide_outbsync;
  		hwif->INB = &cris_ide_inb;
  		hwif->INW = &cris_ide_inw;
@@ -397060,18 +397592,18 @@
 -		hwif->dma_host_on = &cris_dma_on;
 -		hwif->dma_off_quietly = &cris_dma_off;
  		hwif->cbl = ATA_CBL_PATA40;
- 		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
- 		hwif->pio_mask = ATA_PIO4,
-@@ -811,6 +805,8 @@ init_e100_ide (void)
- 		hwif->drives[1].autotune = 1;
- 		hwif->ultra_mask = cris_ultra_mask;
- 		hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
+-		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+-		hwif->pio_mask = ATA_PIO4,
+-		hwif->drives[0].autotune = 1;
+-		hwif->drives[1].autotune = 1;
+-		hwif->ultra_mask = cris_ultra_mask;
+-		hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
 +
 +		idx[h] = hwif->index;
  	}
  
  	/* Reset pulse */
-@@ -823,14 +819,12 @@ init_e100_ide (void)
+@@ -823,14 +821,12 @@ init_e100_ide (void)
  	cris_ide_set_speed(TYPE_PIO, ATA_PIO4_SETUP, ATA_PIO4_STROBE, ATA_PIO4_HOLD);
  	cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD);
  	cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
@@ -397079,7 +397611,7 @@
  
 -static int cris_dma_on (ide_drive_t *drive)
 -{
-+	ide_device_add(idx);
++	ide_device_add(idx, &cris_port_info);
 +
  	return 0;
  }
@@ -397088,7 +397620,20 @@
  static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16)));
  
  /*
-@@ -1062,3 +1056,5 @@ static void cris_dma_start(ide_drive_t *drive)
+@@ -1038,11 +1034,7 @@ static int cris_dma_setup(ide_drive_t *drive)
+ 
+ static void cris_dma_exec_cmd(ide_drive_t *drive, u8 command)
+ {
+-	/* set the irq handler which will finish the request when DMA is done */
+-	ide_set_handler(drive, &cris_dma_intr, WAIT_CMD, NULL);
+-
+-	/* issue cmd to drive */
+-	cris_ide_outb(command, IDE_COMMAND_REG);
++	ide_execute_command(drive, command, &cris_dma_intr, WAIT_CMD, NULL);
+ }
+ 
+ static void cris_dma_start(ide_drive_t *drive)
+@@ -1062,3 +1054,5 @@ static void cris_dma_start(ide_drive_t *drive)
  		LED_DISK_READ(1);
  	}
  }
@@ -397103,7 +397648,7 @@
 +
 +obj-$(CONFIG_IDE_H8300)			+= ide-h8300.o
 diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
-index 4a49b5c..0243295 100644
+index 4a49b5c..520aec0 100644
 --- a/drivers/ide/h8300/ide-h8300.c
 +++ b/drivers/ide/h8300/ide-h8300.c
 @@ -1,5 +1,4 @@
@@ -397150,7 +397695,7 @@
 +
 +	idx[0] = index;
 +
-+	ide_device_add(idx);
++	ide_device_add(idx, NULL);
 +
 +	return 0;
  
@@ -397162,7 +397707,7 @@
 +
 +module_init(h8300_ide_init);
 diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
-index 899d565..68bc618 100644
+index 899d565..25aaeae 100644
 --- a/drivers/ide/ide-acpi.c
 +++ b/drivers/ide/ide-acpi.c
 @@ -1,5 +1,4 @@
@@ -397171,7 +397716,32 @@
   * Provides ACPI support for IDE drives.
   *
   * Copyright (C) 2005 Intel Corp.
-@@ -383,27 +382,19 @@ static int taskfile_load_raw(ide_drive_t *drive,
+@@ -40,7 +39,6 @@ struct GTM_buffer {
+ };
+ 
+ struct ide_acpi_drive_link {
+-	ide_drive_t	*drive;
+ 	acpi_handle	 obj_handle;
+ 	u8		 idbuff[512];
+ };
+@@ -281,16 +279,6 @@ static int do_drive_get_GTF(ide_drive_t *drive,
+ 
+ 	port = hwif->channel ? drive->dn - 2: drive->dn;
+ 
+-	if (!drive->acpidata) {
+-		if (port == 0) {
+-			drive->acpidata = &hwif->acpidata->master;
+-			hwif->acpidata->master.drive = drive;
+-		} else {
+-			drive->acpidata = &hwif->acpidata->slave;
+-			hwif->acpidata->slave.drive = drive;
+-		}
+-	}
+-
+ 	DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
+ 		 hwif->name, dev->bus_id, port, hwif->channel);
+ 
+@@ -383,27 +371,19 @@ static int taskfile_load_raw(ide_drive_t *drive,
  	       gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
  
  	memset(&args, 0, sizeof(ide_task_t));
@@ -397203,8 +397773,119 @@
  		       __FUNCTION__, err);
  
  	return err;
+@@ -503,7 +483,6 @@ int ide_acpi_exec_tfs(ide_drive_t *drive)
+ 
+ 	return ret;
+ }
+-EXPORT_SYMBOL_GPL(ide_acpi_exec_tfs);
+ 
+ /**
+  * ide_acpi_get_timing - get the channel (controller) timings
+@@ -589,7 +568,6 @@ void ide_acpi_get_timing(ide_hwif_t *hwif)
+ 
+ 	kfree(output.pointer);
+ }
+-EXPORT_SYMBOL_GPL(ide_acpi_get_timing);
+ 
+ /**
+  * ide_acpi_push_timing - set the channel (controller) timings
+@@ -643,7 +621,6 @@ void ide_acpi_push_timing(ide_hwif_t *hwif)
+ 	}
+ 	DEBPRINT("_STM status: %d\n", status);
+ }
+-EXPORT_SYMBOL_GPL(ide_acpi_push_timing);
+ 
+ /**
+  * ide_acpi_set_state - set the channel power state
+@@ -697,11 +674,6 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
+  */
+ void ide_acpi_init(ide_hwif_t *hwif)
+ {
+-	int unit;
+-	int			err;
+-	struct ide_acpi_drive_link	*master;
+-	struct ide_acpi_drive_link	*slave;
+-
+ 	ide_acpi_blacklist();
+ 
+ 	hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL);
+@@ -713,40 +685,38 @@ void ide_acpi_init(ide_hwif_t *hwif)
+ 		DEBPRINT("no ACPI object for %s found\n", hwif->name);
+ 		kfree(hwif->acpidata);
+ 		hwif->acpidata = NULL;
+-		return;
+ 	}
++}
++
++void ide_acpi_port_init_devices(ide_hwif_t *hwif)
++{
++	ide_drive_t *drive;
++	int i, err;
++
++	if (hwif->acpidata == NULL)
++		return;
+ 
+ 	/*
+ 	 * The ACPI spec mandates that we send information
+ 	 * for both drives, regardless whether they are connected
+ 	 * or not.
+ 	 */
+-	hwif->acpidata->master.drive = &hwif->drives[0];
+ 	hwif->drives[0].acpidata = &hwif->acpidata->master;
+-	master = &hwif->acpidata->master;
+-
+-	hwif->acpidata->slave.drive = &hwif->drives[1];
+ 	hwif->drives[1].acpidata = &hwif->acpidata->slave;
+-	slave = &hwif->acpidata->slave;
+-
+ 
+ 	/*
+ 	 * Send IDENTIFY for each drive
+ 	 */
+-	if (master->drive->present) {
+-		err = taskfile_lib_get_identify(master->drive, master->idbuff);
+-		if (err) {
+-			DEBPRINT("identify device %s failed (%d)\n",
+-				 master->drive->name, err);
+-		}
+-	}
++	for (i = 0; i < MAX_DRIVES; i++) {
++		drive = &hwif->drives[i];
++
++		if (!drive->present)
++			continue;
+ 
+-	if (slave->drive->present) {
+-		err = taskfile_lib_get_identify(slave->drive, slave->idbuff);
+-		if (err) {
++		err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff);
++		if (err)
+ 			DEBPRINT("identify device %s failed (%d)\n",
+-				 slave->drive->name, err);
+-		}
++				 drive->name, err);
+ 	}
+ 
+ 	if (ide_noacpionboot) {
+@@ -762,13 +732,11 @@ void ide_acpi_init(ide_hwif_t *hwif)
+ 	ide_acpi_get_timing(hwif);
+ 	ide_acpi_push_timing(hwif);
+ 
+-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
+-		ide_drive_t *drive = &hwif->drives[unit];
++	for (i = 0; i < MAX_DRIVES; i++) {
++		drive = &hwif->drives[i];
+ 
+-		if (drive->present) {
++		if (drive->present)
+ 			/* Execute ACPI startup code */
+ 			ide_acpi_exec_tfs(drive);
+-		}
+ 	}
+ }
+-EXPORT_SYMBOL_GPL(ide_acpi_init);
 diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
-index c7d77f0..23074e8 100644
+index c7d77f0..ee4d458 100644
 --- a/drivers/ide/ide-cd.c
 +++ b/drivers/ide/ide-cd.c
 @@ -1,14 +1,14 @@
@@ -397830,12 +398511,10 @@
  		/* Here we should have been called after receiving an interrupt
  		   from the device.  DRQ should how be set. */
  
-@@ -1011,6 +604,27 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
+@@ -1011,6 +604,25 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
   * Block read functions.
   */
  
-+typedef void (xfer_func_t)(ide_drive_t *, void *, u32);
-+
 +static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len)
 +{
 +	while (len > 0) {
@@ -397858,7 +398537,7 @@
  /*
   * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
   * buffer.  Once the first sector is added, any subsequent sectors are
-@@ -1049,11 +663,7 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
+@@ -1049,11 +661,7 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
  	}
  
  	/* Throw away any remaining data. */
@@ -397871,7 +398550,7 @@
  }
  
  /*
-@@ -1062,23 +672,25 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
+@@ -1062,23 +670,25 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
   * ok; nonzero if the request has been terminated.
   */
  static
@@ -397909,7 +398588,7 @@
  		/* Some drives (ASUS) seem to tell us that status
  		 * info is available. just get it and ignore.
  		 */
-@@ -1095,137 +707,28 @@ int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
+@@ -1095,137 +705,28 @@ int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
  }
  
  /*
@@ -398062,7 +398741,7 @@
  }
  
  /*
-@@ -1287,48 +790,58 @@ static int cdrom_read_from_buffer (ide_drive_t *drive)
+@@ -1287,48 +788,58 @@ static int cdrom_read_from_buffer (ide_drive_t *drive)
  	return 0;
  }
  
@@ -398147,7 +398826,7 @@
  #define IDECD_SEEK_THRESHOLD	(1000)			/* 1000 blocks */
  #define IDECD_SEEK_TIMER	(5 * WAIT_MIN_SLEEP)	/* 100 ms */
  #define IDECD_SEEK_TIMEOUT	(2 * WAIT_CMD)		/* 20 sec */
-@@ -1341,7 +854,8 @@ static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
+@@ -1341,7 +852,8 @@ static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
  
  	if (cdrom_decode_status(drive, 0, &stat))
  		return ide_stopped;
@@ -398157,7 +398836,7 @@
  
  	if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
  		if (--retry == 0) {
-@@ -1397,184 +911,25 @@ static void restore_request (struct request *rq)
+@@ -1397,184 +909,25 @@ static void restore_request (struct request *rq)
  	rq->q->prep_rq_fn(rq->q, rq);
  }
  
@@ -398319,8 +398998,8 @@
 -	/* Now we wait for another interrupt. */
 -	ide_set_handler(drive, &cdrom_pc_intr, ATAPI_WAIT_PC, cdrom_timer_expiry);
 -	return ide_started;
- }
- 
+-}
+-
 -static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive)
 -{
 -	struct request *rq = HWGROUP(drive)->rq;
@@ -398345,15 +399024,15 @@
 -
 -	/* Start sending the command to the drive. */
 -	return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation);
--}
--
+ }
+ 
 -
 -static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
 +int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
  {
  	struct request_sense sense;
  	int retries = 10;
-@@ -1623,59 +978,37 @@ static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
+@@ -1623,59 +976,37 @@ static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
  }
  
  /*
@@ -398428,7 +399107,7 @@
  	}
  
  	if (cdrom_decode_status(drive, 0, &stat))
-@@ -1685,14 +1018,12 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
+@@ -1685,14 +1016,12 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
  	 * using dma, transfer is complete now
  	 */
  	if (dma) {
@@ -398447,7 +399126,7 @@
  		goto end_request;
  	}
  
-@@ -1704,54 +1035,120 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
+@@ -1704,54 +1033,120 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
  	highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
  
  	len = lowcyl + (256 * highcyl);
@@ -398587,7 +399266,7 @@
  			break;
  		}
  
-@@ -1762,186 +1159,117 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
+@@ -1762,186 +1157,117 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
  
  		thislen -= blen;
  		len -= blen;
@@ -398605,14 +399284,14 @@
 -	if (len > 0) {
 -		while (len > 0) {
 -			int pad = 0;
- 
+-
 -			xferfunc(drive, &pad, sizeof(pad));
 -			len -= sizeof(pad);
 -		}
 -	}
 -
 -	BUG_ON(HWGROUP(drive)->handler != NULL);
--
+ 
 -	ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL);
 -	return ide_started;
 -
@@ -398853,7 +399532,7 @@
  }
  
  static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
-@@ -1958,7 +1286,10 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
+@@ -1958,7 +1284,10 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
  {
  	struct cdrom_info *info = drive->driver_data;
  
@@ -398865,7 +399544,7 @@
  
  	info->dma = 0;
  
-@@ -1995,7 +1326,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
+@@ -1995,7 +1324,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
  	struct cdrom_info *info = drive->driver_data;
  
  	if (blk_fs_request(rq)) {
@@ -398874,7 +399553,7 @@
  			unsigned long elapsed = jiffies - info->start_seek;
  			int stat = HWIF(drive)->INB(IDE_STATUS_REG);
  
-@@ -2006,22 +1337,16 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
+@@ -2006,22 +1335,16 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
  				}
  				printk (KERN_ERR "%s: DSC timeout\n", drive->name);
  			}
@@ -398901,7 +399580,7 @@
  		return cdrom_do_block_pc(drive, rq);
  	} else if (blk_special_request(rq)) {
  		/*
-@@ -2048,141 +1373,33 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
+@@ -2048,141 +1371,33 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
   * can also be NULL, in which case no sense information is returned.
   */
  
@@ -398975,10 +399654,10 @@
 +	 */
  	req.cmd[7] = cdi->sanyo_slot % 3;
 -#endif /* not STANDARD_ATAPI */
- 
+-
 -	return cdrom_queue_packet_command(drive, &req);
 -}
--
+ 
 -
 -/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
 -static int
@@ -399053,7 +399732,7 @@
  }
  
  static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
-@@ -2197,7 +1414,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
+@@ -2197,7 +1412,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
  	int stat;
  	struct request req;
  
@@ -399062,7 +399741,7 @@
  
  	req.sense = sense;
  	req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
-@@ -2205,7 +1422,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
+@@ -2205,7 +1420,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
  	req.data_len = sizeof(capbuf);
  	req.cmd_flags |= REQ_QUIET;
  
@@ -399071,7 +399750,7 @@
  	if (stat == 0) {
  		*capacity = 1 + be32_to_cpu(capbuf.lba);
  		*sectors_per_frame =
-@@ -2221,7 +1438,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
+@@ -2221,7 +1436,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
  {
  	struct request req;
  
@@ -399080,7 +399759,7 @@
  
  	req.sense = sense;
  	req.data =  buf;
-@@ -2236,12 +1453,11 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
+@@ -2236,12 +1451,11 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
  	if (msf_flag)
  		req.cmd[1] = 2;
  
@@ -399095,7 +399774,7 @@
  {
  	int stat, ntracks, i;
  	struct cdrom_info *info = drive->driver_data;
-@@ -2268,7 +1484,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
+@@ -2268,7 +1482,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
  	   If it is, just return. */
  	(void) cdrom_check_status(drive, sense);
  
@@ -399104,7 +399783,7 @@
  		return 0;
  
  	/* Try to get the total cdrom capacity and sector size. */
-@@ -2290,12 +1506,10 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
+@@ -2290,12 +1504,10 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
  	if (stat)
  		return stat;
  
@@ -399120,7 +399799,7 @@
  
  	ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
  	if (ntracks <= 0)
-@@ -2327,16 +1541,13 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
+@@ -2327,16 +1539,13 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
  					   (ntracks + 1) *
  					   sizeof(struct atapi_toc_entry),
  					   sense);
@@ -399143,7 +399822,7 @@
  			toc->hdr.first_track = CDROM_LEADOUT;
  			toc->hdr.last_track = CDROM_LEADOUT;
  		}
-@@ -2347,21 +1558,17 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
+@@ -2347,21 +1556,17 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
  
  	toc->hdr.toc_length = ntohs (toc->hdr.toc_length);
  
@@ -399172,7 +399851,7 @@
  		toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute,
  						   toc->ent[i].addr.msf.second,
  						   toc->ent[i].addr.msf.frame);
-@@ -2381,8 +1588,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
+@@ -2381,8 +1586,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
  		toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
  	}
  
@@ -399182,7 +399861,7 @@
  		/* Re-read multisession information using MSF format */
  		stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
  					   sizeof(ms_tmp), sense);
-@@ -2394,7 +1600,6 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
+@@ -2394,7 +1598,6 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
  					  	   ms_tmp.ent.addr.msf.second,
  						   ms_tmp.ent.addr.msf.frame);
  	}
@@ -399190,7 +399869,7 @@
  
  	toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
  
-@@ -2407,278 +1612,22 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
+@@ -2407,278 +1610,22 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
  	}
  
  	/* Remember that we've read this stuff. */
@@ -399475,7 +400154,7 @@
  	do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
  		stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
  		if (!stat)
-@@ -2687,177 +1636,33 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_pag
+@@ -2687,177 +1634,33 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_pag
  	return stat;
  }
  
@@ -399671,7 +400350,7 @@
  static struct cdrom_device_ops ide_cdrom_dops = {
  	.open			= ide_cdrom_open_real,
  	.release		= ide_cdrom_release_real,
-@@ -2870,14 +1675,7 @@ static struct cdrom_device_ops ide_cdrom_dops = {
+@@ -2870,14 +1673,7 @@ static struct cdrom_device_ops ide_cdrom_dops = {
  	.get_mcn		= ide_cdrom_get_mcn,
  	.reset			= ide_cdrom_reset,
  	.audio_ioctl		= ide_cdrom_audio_ioctl,
@@ -399687,7 +400366,7 @@
  	.generic_packet		= ide_cdrom_packet,
  };
  
-@@ -2887,35 +1685,12 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
+@@ -2887,35 +1683,12 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
  	struct cdrom_device_info *devinfo = &info->devinfo;
  
  	devinfo->ops = &ide_cdrom_dops;
@@ -399726,7 +400405,7 @@
  		devinfo->mask |= CDC_SELECT_SPEED;
  
  	devinfo->disk = info->disk;
-@@ -2925,22 +1700,25 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
+@@ -2925,22 +1698,25 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
  static
  int ide_cdrom_probe_capabilities (ide_drive_t *drive)
  {
@@ -399761,7 +400440,7 @@
  		return nslots;
  	}
  
-@@ -2954,83 +1732,66 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
+@@ -2954,83 +1730,66 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
  	cdi->handle = drive;
  	cdi->ops = &ide_cdrom_dops;
  
@@ -399892,7 +400571,7 @@
  
  	return nslots;
  }
-@@ -3123,11 +1884,74 @@ static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
+@@ -3123,11 +1882,74 @@ static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
  	return 0;
  }
  
@@ -399969,7 +400648,7 @@
  	int nslots;
  
  	blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
-@@ -3138,101 +1962,21 @@ int ide_cdrom_setup (ide_drive_t *drive)
+@@ -3138,101 +1960,21 @@ int ide_cdrom_setup (ide_drive_t *drive)
  
  	drive->special.all	= 0;
  
@@ -400084,7 +400763,7 @@
  
  	nslots = ide_cdrom_probe_capabilities (drive);
  
-@@ -3247,7 +1991,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
+@@ -3247,7 +1989,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
  
  	if (ide_cdrom_register(drive, nslots)) {
  		printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
@@ -400093,7 +400772,7 @@
  		return 1;
  	}
  	ide_cdrom_add_settings(drive);
-@@ -3287,7 +2031,6 @@ static void ide_cd_release(struct kref *kref)
+@@ -3287,7 +2029,6 @@ static void ide_cd_release(struct kref *kref)
  
  	kfree(info->buffer);
  	kfree(info->toc);
@@ -400101,7 +400780,7 @@
  	if (devinfo->handle == drive && unregister_cdrom(devinfo))
  		printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
  				"driver.\n", __FUNCTION__, drive->name);
-@@ -3443,7 +2186,9 @@ static int idecd_revalidate_disk(struct gendisk *disk)
+@@ -3443,7 +2184,9 @@ static int idecd_revalidate_disk(struct gendisk *disk)
  {
  	struct cdrom_info *info = ide_cd_g(disk);
  	struct request_sense sense;
@@ -400112,7 +400791,7 @@
  	return  0;
  }
  
-@@ -3518,7 +2263,7 @@ static int ide_cd_probe(ide_drive_t *drive)
+@@ -3518,7 +2261,7 @@ static int ide_cd_probe(ide_drive_t *drive)
  		goto failed;
  	}
  
@@ -400121,7 +400800,7 @@
  	g->fops = &idecd_ops;
  	g->flags |= GENHD_FL_REMOVABLE;
  	add_disk(g);
-@@ -3541,6 +2286,7 @@ static int __init ide_cdrom_init(void)
+@@ -3541,6 +2284,7 @@ static int __init ide_cdrom_init(void)
  }
  
  MODULE_ALIAS("ide:*m-cdrom*");
@@ -402370,7 +403049,7 @@
  	}
  
 diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
-index 4703837..7beaf1e 100644
+index 4703837..3cf59f2 100644
 --- a/drivers/ide/ide-dma.c
 +++ b/drivers/ide/ide-dma.c
 @@ -1,15 +1,13 @@
@@ -402649,7 +403328,7 @@
  		return 0;
  
  	if (ide_set_dma_mode(drive, speed))
-@@ -824,25 +800,23 @@ err_out:
+@@ -824,25 +800,43 @@ err_out:
  
  int ide_set_dma(ide_drive_t *drive)
  {
@@ -402681,13 +403360,33 @@
 -		break;
 -	}
 +	ide_dma_on(drive);
++
++	return 0;
++}
  
 -	return rc;
-+	return 0;
++void ide_check_dma_crc(ide_drive_t *drive)
++{
++	u8 mode;
++
++	ide_dma_off_quietly(drive);
++	drive->crc_count = 0;
++	mode = drive->current_speed;
++	/*
++	 * Don't try non Ultra-DMA modes without iCRC's.  Force the
++	 * device to PIO and make the user enable SWDMA/MWDMA modes.
++	 */
++	if (mode > XFER_UDMA_0 && mode <= XFER_UDMA_7)
++		mode--;
++	else
++		mode = XFER_PIO_4;
++	ide_set_xfer_rate(drive, mode);
++	if (drive->current_speed >= XFER_SW_DMA_0)
++		ide_dma_on(drive);
  }
  
  #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
-@@ -870,10 +844,10 @@ EXPORT_SYMBOL(ide_dma_timeout);
+@@ -870,10 +864,10 @@ EXPORT_SYMBOL(ide_dma_timeout);
  static void ide_release_dma_engine(ide_hwif_t *hwif)
  {
  	if (hwif->dmatable_cpu) {
@@ -402702,7 +403401,7 @@
  		hwif->dmatable_cpu = NULL;
  	}
  }
-@@ -901,7 +875,9 @@ int ide_release_dma(ide_hwif_t *hwif)
+@@ -901,7 +895,9 @@ int ide_release_dma(ide_hwif_t *hwif)
  
  static int ide_allocate_dma_engine(ide_hwif_t *hwif)
  {
@@ -402713,7 +403412,7 @@
  						  PRD_ENTRIES * PRD_BYTES,
  						  &hwif->dmatable_dma);
  
-@@ -914,19 +890,19 @@ static int ide_allocate_dma_engine(ide_hwif_t *hwif)
+@@ -914,19 +910,19 @@ static int ide_allocate_dma_engine(ide_hwif_t *hwif)
  	return 1;
  }
  
@@ -402737,7 +403436,7 @@
  		printk(" -- Error, ports in use.\n");
  		return 1;
  	}
-@@ -938,7 +914,7 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
+@@ -938,7 +934,7 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
  			if (!request_region(hwif->extra_base,
  					    hwif->cds->extra, hwif->cds->name)) {
  				printk(" -- Error, extra ports in use.\n");
@@ -402746,7 +403445,7 @@
  				return 1;
  			}
  			hwif->extra_ports = hwif->cds->extra;
-@@ -948,17 +924,19 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
+@@ -948,17 +944,19 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
  	return 0;
  }
  
@@ -402771,7 +403470,7 @@
  		return;
  
  	if (ide_allocate_dma_engine(hwif)) {
-@@ -968,30 +946,19 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
+@@ -968,30 +966,19 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
  
  	hwif->dma_base = base;
  
@@ -402815,7 +403514,7 @@
  	if (!hwif->dma_setup)
  		hwif->dma_setup = &ide_dma_setup;
  	if (!hwif->dma_exec_cmd)
-@@ -1007,15 +974,10 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
+@@ -1007,15 +994,10 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
  	if (!hwif->dma_lost_irq)
  		hwif->dma_lost_irq = &ide_dma_lost_irq;
  
@@ -402836,28 +403535,29 @@
  
  EXPORT_SYMBOL_GPL(ide_setup_dma);
 diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
-index 04a3578..3512637 100644
+index 04a3578..f8fe6ee 100644
 --- a/drivers/ide/ide-floppy.c
 +++ b/drivers/ide/ide-floppy.c
-@@ -1,13 +1,12 @@
+@@ -1,15 +1,9 @@
  /*
 - * linux/drivers/ide/ide-floppy.c	Version 0.99	Feb 24 2002
-+ * IDE ATAPI floppy driver.
-  *
+- *
 - * Copyright (C) 1996 - 1999 Gadi Oxman <gadio at netvision.net.il>
 - * Copyright (C) 2000 - 2002 Paul Bristow <paul at paulbristow.net>
+- */
+-
+-/*
+  * IDE ATAPI floppy driver.
+  *
+- * The driver currently doesn't have any fancy features, just the bare
+- * minimum read/write support.
 + * Copyright (C) 1996-1999  Gadi Oxman <gadio at netvision.net.il>
 + * Copyright (C) 2000-2002  Paul Bristow <paul at paulbristow.net>
 + * Copyright (C) 2005       Bartlomiej Zolnierkiewicz
-  */
- 
- /*
-- * IDE ATAPI floppy driver.
-- *
-  * The driver currently doesn't have any fancy features, just the bare
-  * minimum read/write support.
   *
-@@ -17,67 +16,8 @@
+  * This driver supports the following IDE floppy drives:
+  *
+@@ -17,70 +11,11 @@
   * Iomega Zip 100/250
   * Iomega PC Card Clik!/PocketZip
   *
@@ -402926,8 +403626,326 @@
 + * Documentation/ide/ChangeLog.ide-floppy.1996-2002
   */
  
- #define IDEFLOPPY_VERSION "0.99.newide"
-@@ -369,27 +309,6 @@ typedef struct ide_floppy_obj {
+-#define IDEFLOPPY_VERSION "0.99.newide"
++#define IDEFLOPPY_VERSION "1.00"
+ 
+ #include <linux/module.h>
+ #include <linux/types.h>
+@@ -102,179 +37,91 @@
+ #include <scsi/scsi_ioctl.h>
+ 
+ #include <asm/byteorder.h>
+-#include <asm/irq.h>
+-#include <asm/uaccess.h>
+-#include <asm/io.h>
++#include <linux/irq.h>
++#include <linux/uaccess.h>
++#include <linux/io.h>
+ #include <asm/unaligned.h>
+ 
+-/*
+- *	The following are used to debug the driver.
+- */
++/* define to see debug info */
+ #define IDEFLOPPY_DEBUG_LOG		0
+-#define IDEFLOPPY_DEBUG_INFO		0
+-#define IDEFLOPPY_DEBUG_BUGS		1
+ 
+ /* #define IDEFLOPPY_DEBUG(fmt, args...) printk(KERN_INFO fmt, ## args) */
+-#define IDEFLOPPY_DEBUG( fmt, args... )
++#define IDEFLOPPY_DEBUG(fmt, args...)
+ 
+ #if IDEFLOPPY_DEBUG_LOG
+-#define debug_log printk
++#define debug_log(fmt, args...) \
++	printk(KERN_INFO "ide-floppy: " fmt, ## args)
+ #else
+-#define debug_log(fmt, args... ) do {} while(0)
++#define debug_log(fmt, args...) do {} while (0)
+ #endif
+ 
+ 
+-/*
+- *	Some drives require a longer irq timeout.
+- */
++/* Some drives require a longer irq timeout. */
+ #define IDEFLOPPY_WAIT_CMD		(5 * WAIT_CMD)
+ 
+ /*
+- *	After each failed packet command we issue a request sense command
+- *	and retry the packet command IDEFLOPPY_MAX_PC_RETRIES times.
++ * After each failed packet command we issue a request sense command and retry
++ * the packet command IDEFLOPPY_MAX_PC_RETRIES times.
+  */
+ #define IDEFLOPPY_MAX_PC_RETRIES	3
+ 
+ /*
+- *	With each packet command, we allocate a buffer of
+- *	IDEFLOPPY_PC_BUFFER_SIZE bytes.
++ * With each packet command, we allocate a buffer of IDEFLOPPY_PC_BUFFER_SIZE
++ * bytes.
+  */
+ #define IDEFLOPPY_PC_BUFFER_SIZE	256
+ 
+ /*
+- *	In various places in the driver, we need to allocate storage
+- *	for packet commands and requests, which will remain valid while
+- *	we leave the driver to wait for an interrupt or a timeout event.
++ * In various places in the driver, we need to allocate storage for packet
++ * commands and requests, which will remain valid while	we leave the driver to
++ * wait for an interrupt or a timeout event.
+  */
+ #define IDEFLOPPY_PC_STACK		(10 + IDEFLOPPY_MAX_PC_RETRIES)
+ 
+-/*
+- *	Our view of a packet command.
+- */
+ typedef struct idefloppy_packet_command_s {
+ 	u8 c[12];				/* Actual packet bytes */
+-	int retries;				/* On each retry, we increment retries */
++	int retries;				/* On each retry, we increment
++						   retries */
+ 	int error;				/* Error code */
+ 	int request_transfer;			/* Bytes to transfer */
+ 	int actually_transferred;		/* Bytes actually transferred */
+ 	int buffer_size;			/* Size of our data buffer */
+-	int b_count;				/* Missing/Available data on the current buffer */
++	int b_count;				/* Missing/Available data on
++						   the current buffer */
+ 	struct request *rq;			/* The corresponding request */
+ 	u8 *buffer;				/* Data buffer */
+-	u8 *current_position;			/* Pointer into the above buffer */
+-	void (*callback) (ide_drive_t *);	/* Called when this packet command is completed */
++	u8 *current_position;			/* Pointer into above buffer */
++	void (*callback) (ide_drive_t *);	/* Called when this packet
++						   command is completed */
+ 	u8 pc_buffer[IDEFLOPPY_PC_BUFFER_SIZE];	/* Temporary buffer */
+-	unsigned long flags;			/* Status/Action bit flags: long for set_bit */
++	unsigned long flags;			/* Status/Action bit flags: long
++						   for set_bit */
+ } idefloppy_pc_t;
+ 
+-/*
+- *	Packet command flag bits.
+- */
+-#define	PC_ABORT			0	/* Set when an error is considered normal - We won't retry */
+-#define PC_DMA_RECOMMENDED		2	/* 1 when we prefer to use DMA if possible */
+-#define	PC_DMA_IN_PROGRESS		3	/* 1 while DMA in progress */
+-#define	PC_DMA_ERROR			4	/* 1 when encountered problem during DMA */
+-#define	PC_WRITING			5	/* Data direction */
+-
+-#define	PC_SUPPRESS_ERROR		6	/* Suppress error reporting */
+-
+-/*
+- *	Removable Block Access Capabilities Page
+- */
+-typedef struct {
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
+-	unsigned	page_code	:6;	/* Page code - Should be 0x1b */
+-	unsigned	reserved1_6	:1;	/* Reserved */
+-	unsigned	ps		:1;	/* Should be 0 */
+-#elif defined(__BIG_ENDIAN_BITFIELD)
+-	unsigned	ps		:1;	/* Should be 0 */
+-	unsigned	reserved1_6	:1;	/* Reserved */
+-	unsigned	page_code	:6;	/* Page code - Should be 0x1b */
+-#else
+-#error "Bitfield endianness not defined! Check your byteorder.h"
+-#endif
+-	u8		page_length;		/* Page Length - Should be 0xa */
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
+-	unsigned	reserved2	:6;
+-	unsigned	srfp		:1;	/* Supports reporting progress of format */
+-	unsigned	sflp		:1;	/* System floppy type device */
+-	unsigned	tlun		:3;	/* Total logical units supported by the device */
+-	unsigned	reserved3	:3;
+-	unsigned	sml		:1;	/* Single / Multiple lun supported */
+-	unsigned	ncd		:1;	/* Non cd optical device */
+-#elif defined(__BIG_ENDIAN_BITFIELD)
+-	unsigned	sflp		:1;	/* System floppy type device */
+-	unsigned	srfp		:1;	/* Supports reporting progress of format */
+-	unsigned	reserved2	:6;
+-	unsigned	ncd		:1;	/* Non cd optical device */
+-	unsigned	sml		:1;	/* Single / Multiple lun supported */
+-	unsigned	reserved3	:3;
+-	unsigned	tlun		:3;	/* Total logical units supported by the device */
+-#else
+-#error "Bitfield endianness not defined! Check your byteorder.h"
+-#endif
+-	u8		reserved[8];
+-} idefloppy_capabilities_page_t;
+-
+-/*
+- *	Flexible disk page.
+- */
+-typedef struct {
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
+-	unsigned	page_code	:6;	/* Page code - Should be 0x5 */
+-	unsigned	reserved1_6	:1;	/* Reserved */
+-	unsigned	ps		:1;	/* The device is capable of saving the page */
+-#elif defined(__BIG_ENDIAN_BITFIELD)
+-	unsigned	ps		:1;	/* The device is capable of saving the page */
+-	unsigned	reserved1_6	:1;	/* Reserved */
+-	unsigned	page_code	:6;	/* Page code - Should be 0x5 */
+-#else
+-#error "Bitfield endianness not defined! Check your byteorder.h"
+-#endif
+-	u8		page_length;		/* Page Length - Should be 0x1e */
+-	u16		transfer_rate;		/* In kilobits per second */
+-	u8		heads, sectors;		/* Number of heads, Number of sectors per track */
+-	u16		sector_size;		/* Byes per sector */
+-	u16		cyls;			/* Number of cylinders */
+-	u8		reserved10[10];
+-	u8		motor_delay;		/* Motor off delay */
+-	u8		reserved21[7];
+-	u16		rpm;			/* Rotations per minute */
+-	u8		reserved30[2];
+-} idefloppy_flexible_disk_page_t;
+- 
+-/*
+- *	Format capacity
+- */
+-typedef struct {
+-	u8		reserved[3];
+-	u8		length;			/* Length of the following descriptors in bytes */
+-} idefloppy_capacity_header_t;
+-
+-typedef struct {
+-	u32		blocks;			/* Number of blocks */
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
+-	unsigned	dc		:2;	/* Descriptor Code */
+-	unsigned	reserved	:6;
+-#elif defined(__BIG_ENDIAN_BITFIELD)
+-	unsigned	reserved	:6;
+-	unsigned	dc		:2;	/* Descriptor Code */
+-#else
+-#error "Bitfield endianness not defined! Check your byteorder.h"
+-#endif
+-	u8		length_msb;		/* Block Length (MSB)*/
+-	u16		length;			/* Block Length */
+-} idefloppy_capacity_descriptor_t;
++/* Packet command flag bits. */
++enum {
++	/* 1 when we prefer to use DMA if possible */
++	PC_FLAG_DMA_RECOMMENDED	= (1 << 0),
++	/* 1 while DMA in progress */
++	PC_FLAG_DMA_IN_PROGRESS	= (1 << 1),
++	/* 1 when encountered problem during DMA */
++	PC_FLAG_DMA_ERROR	= (1 << 2),
++	/* Data direction */
++	PC_FLAG_WRITING		= (1 << 3),
++	/* Suppress error reporting */
++	PC_FLAG_SUPPRESS_ERROR	= (1 << 4),
++};
+ 
++/* format capacities descriptor codes */
+ #define CAPACITY_INVALID	0x00
+ #define CAPACITY_UNFORMATTED	0x01
+ #define CAPACITY_CURRENT	0x02
+ #define CAPACITY_NO_CARTRIDGE	0x03
+ 
+ /*
+- *	Most of our global data which we need to save even as we leave the
+- *	driver due to an interrupt or a timer event is stored in a variable
+- *	of type idefloppy_floppy_t, defined below.
++ * Most of our global data which we need to save even as we leave the driver
++ * due to an interrupt or a timer event is stored in a variable of type
++ * idefloppy_floppy_t, defined below.
+  */
+ typedef struct ide_floppy_obj {
+ 	ide_drive_t	*drive;
+@@ -295,23 +142,19 @@ typedef struct ide_floppy_obj {
+ 	/* We implement a circular array */
+ 	int rq_stack_index;
+ 
+-	/*
+-	 *	Last error information
+-	 */
++	/* Last error information */
+ 	u8 sense_key, asc, ascq;
+ 	/* delay this long before sending packet command */
+ 	u8 ticks;
+ 	int progress_indication;
+ 
+-	/*
+-	 *	Device information
+-	 */
++	/* Device information */
+ 	/* Current format */
+ 	int blocks, block_size, bs_factor;
+-	/* Last format capacity */
+-	idefloppy_capacity_descriptor_t capacity;
++	/* Last format capacity descriptor */
++	u8 cap_desc[8];
+ 	/* Copy of the flexible disk page */
+-	idefloppy_flexible_disk_page_t flexible_disk_page;
++	u8 flexible_disk_page[32];
+ 	/* Write protect */
+ 	int wp;
+ 	/* Supports format progress report */
+@@ -322,85 +165,40 @@ typedef struct ide_floppy_obj {
+ 
+ #define IDEFLOPPY_TICKS_DELAY	HZ/20	/* default delay for ZIP 100 (50ms) */
+ 
+-/*
+- *	Floppy flag bits values.
+- */
+-#define IDEFLOPPY_DRQ_INTERRUPT		0	/* DRQ interrupt device */
+-#define IDEFLOPPY_MEDIA_CHANGED		1	/* Media may have changed */
+-#define IDEFLOPPY_USE_READ12		2	/* Use READ12/WRITE12 or READ10/WRITE10 */
+-#define	IDEFLOPPY_FORMAT_IN_PROGRESS	3	/* Format in progress */
+-#define IDEFLOPPY_CLIK_DRIVE	        4       /* Avoid commands not supported in Clik drive */
+-#define IDEFLOPPY_ZIP_DRIVE		5	/* Requires BH algorithm for packets */
+-
+-/*
+- *	ATAPI floppy drive packet commands
+- */
+-#define IDEFLOPPY_FORMAT_UNIT_CMD	0x04
+-#define IDEFLOPPY_INQUIRY_CMD		0x12
+-#define IDEFLOPPY_MODE_SELECT_CMD	0x55
+-#define IDEFLOPPY_MODE_SENSE_CMD	0x5a
+-#define IDEFLOPPY_READ10_CMD		0x28
+-#define IDEFLOPPY_READ12_CMD		0xa8
+-#define IDEFLOPPY_READ_CAPACITY_CMD	0x23
+-#define IDEFLOPPY_REQUEST_SENSE_CMD	0x03
+-#define IDEFLOPPY_PREVENT_REMOVAL_CMD	0x1e
+-#define IDEFLOPPY_SEEK_CMD		0x2b
+-#define IDEFLOPPY_START_STOP_CMD	0x1b
+-#define IDEFLOPPY_TEST_UNIT_READY_CMD	0x00
+-#define IDEFLOPPY_VERIFY_CMD		0x2f
+-#define IDEFLOPPY_WRITE10_CMD		0x2a
+-#define IDEFLOPPY_WRITE12_CMD		0xaa
+-#define IDEFLOPPY_WRITE_VERIFY_CMD	0x2e
++/* Floppy flag bits values. */
++enum {
++	/* DRQ interrupt device */
++	IDEFLOPPY_FLAG_DRQ_INTERRUPT		= (1 <<	0),
++	/* Media may have changed */
++	IDEFLOPPY_FLAG_MEDIA_CHANGED		= (1 << 1),
++	/* Format in progress */
++	IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS	= (1 << 2),
++	/* Avoid commands not supported in Clik drive */
++	IDEFLOPPY_FLAG_CLIK_DRIVE		= (1 << 3),
++	/* Requires BH algorithm for packets */
++	IDEFLOPPY_FLAG_ZIP_DRIVE		= (1 << 4),
++};
+ 
+-/*
+- *	Defines for the mode sense command
+- */
++/* Defines for the MODE SENSE command */
+ #define MODE_SENSE_CURRENT		0x00
+ #define MODE_SENSE_CHANGEABLE		0x01
+-#define MODE_SENSE_DEFAULT		0x02 
++#define MODE_SENSE_DEFAULT		0x02
+ #define MODE_SENSE_SAVED		0x03
+ 
+-/*
+- *	IOCTLs used in low-level formatting.
+- */
+-
++/* IOCTLs used in low-level formatting. */
+ #define	IDEFLOPPY_IOCTL_FORMAT_SUPPORTED	0x4600
+ #define	IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY	0x4601
  #define	IDEFLOPPY_IOCTL_FORMAT_START		0x4602
  #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS	0x4603
  
@@ -402952,10 +403970,426 @@
 -
 -#endif
 -
+-/*
+- *	Error codes which are returned in rq->errors to the higher part
+- *	of the driver.
+- */
++/* Error code returned in rq->errors to the higher part of the driver. */
+ #define	IDEFLOPPY_ERROR_GENERAL		101
+ 
+ /*
+- *	The following is used to format the general configuration word of
+- *	the ATAPI IDENTIFY DEVICE command.
++ * The following is used to format the general configuration word of the
++ * ATAPI IDENTIFY DEVICE command.
+  */
+-struct idefloppy_id_gcw {	
++struct idefloppy_id_gcw {
+ #if defined(__LITTLE_ENDIAN_BITFIELD)
+ 	unsigned packet_size		:2;	/* Packet Size */
+ 	unsigned reserved234		:3;	/* Reserved */
+@@ -423,103 +221,12 @@ struct idefloppy_id_gcw {
+ };
+ 
+ /*
+- *	INQUIRY packet command - Data Format
+- */
+-typedef struct {
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
+-	unsigned	device_type	:5;	/* Peripheral Device Type */
+-	unsigned	reserved0_765	:3;	/* Peripheral Qualifier - Reserved */
+-	unsigned	reserved1_6t0	:7;	/* Reserved */
+-	unsigned	rmb		:1;	/* Removable Medium Bit */
+-	unsigned	ansi_version	:3;	/* ANSI Version */
+-	unsigned	ecma_version	:3;	/* ECMA Version */
+-	unsigned	iso_version	:2;	/* ISO Version */
+-	unsigned	response_format :4;	/* Response Data Format */
+-	unsigned	reserved3_45	:2;	/* Reserved */
+-	unsigned	reserved3_6	:1;	/* TrmIOP - Reserved */
+-	unsigned	reserved3_7	:1;	/* AENC - Reserved */
+-#elif defined(__BIG_ENDIAN_BITFIELD)
+-	unsigned	reserved0_765	:3;	/* Peripheral Qualifier - Reserved */
+-	unsigned	device_type	:5;	/* Peripheral Device Type */
+-	unsigned	rmb		:1;	/* Removable Medium Bit */
+-	unsigned	reserved1_6t0	:7;	/* Reserved */
+-	unsigned	iso_version	:2;	/* ISO Version */
+-	unsigned	ecma_version	:3;	/* ECMA Version */
+-	unsigned	ansi_version	:3;	/* ANSI Version */
+-	unsigned	reserved3_7	:1;	/* AENC - Reserved */
+-	unsigned	reserved3_6	:1;	/* TrmIOP - Reserved */
+-	unsigned	reserved3_45	:2;	/* Reserved */
+-	unsigned	response_format :4;	/* Response Data Format */
+-#else
+-#error "Bitfield endianness not defined! Check your byteorder.h"
+-#endif
+-	u8		additional_length;	/* Additional Length (total_length-4) */
+-	u8		rsv5, rsv6, rsv7;	/* Reserved */
+-	u8		vendor_id[8];		/* Vendor Identification */
+-	u8		product_id[16];		/* Product Identification */
+-	u8		revision_level[4];	/* Revision Level */
+-	u8		vendor_specific[20];	/* Vendor Specific - Optional */
+-	u8		reserved56t95[40];	/* Reserved - Optional */
+-						/* Additional information may be returned */
+-} idefloppy_inquiry_result_t;
+-
+-/*
+- *	REQUEST SENSE packet command result - Data Format.
+- */
+-typedef struct {
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
+-	unsigned	error_code	:7;	/* Current error (0x70) */
+-	unsigned	valid		:1;	/* The information field conforms to SFF-8070i */
+-	u8		reserved1	:8;	/* Reserved */
+-	unsigned	sense_key	:4;	/* Sense Key */
+-	unsigned	reserved2_4	:1;	/* Reserved */
+-	unsigned	ili		:1;	/* Incorrect Length Indicator */
+-	unsigned	reserved2_67	:2;
+-#elif defined(__BIG_ENDIAN_BITFIELD)
+-	unsigned	valid		:1;	/* The information field conforms to SFF-8070i */
+-	unsigned	error_code	:7;	/* Current error (0x70) */
+-	u8		reserved1	:8;	/* Reserved */
+-	unsigned	reserved2_67	:2;
+-	unsigned	ili		:1;	/* Incorrect Length Indicator */
+-	unsigned	reserved2_4	:1;	/* Reserved */
+-	unsigned	sense_key	:4;	/* Sense Key */
+-#else
+-#error "Bitfield endianness not defined! Check your byteorder.h"
+-#endif
+-	u32		information __attribute__ ((packed));
+-	u8		asl;			/* Additional sense length (n-7) */
+-	u32		command_specific;	/* Additional command specific information */
+-	u8		asc;			/* Additional Sense Code */
+-	u8		ascq;			/* Additional Sense Code Qualifier */
+-	u8		replaceable_unit_code;	/* Field Replaceable Unit Code */
+-	u8		sksv[3];
+-	u8		pad[2];			/* Padding to 20 bytes */
+-} idefloppy_request_sense_result_t;
+-
+-/*
+- *	Pages of the SELECT SENSE / MODE SENSE packet commands.
++ * Pages of the SELECT SENSE / MODE SENSE packet commands.
++ * See SFF-8070i spec.
+  */
+ #define	IDEFLOPPY_CAPABILITIES_PAGE	0x1b
+ #define IDEFLOPPY_FLEXIBLE_DISK_PAGE	0x05
+ 
+-/*
+- *	Mode Parameter Header for the MODE SENSE packet command
+- */
+-typedef struct {
+-	u16		mode_data_length;	/* Length of the following data transfer */
+-	u8		medium_type;		/* Medium Type */
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
+-	unsigned	reserved3	:7;
+-	unsigned	wp		:1;	/* Write protect */
+-#elif defined(__BIG_ENDIAN_BITFIELD)
+-	unsigned	wp		:1;	/* Write protect */
+-	unsigned	reserved3	:7;
+-#else
+-#error "Bitfield endianness not defined! Check your byteorder.h"
+-#endif
+-	u8		reserved[4];
+-} idefloppy_mode_parameter_header_t;
+-
+ static DEFINE_MUTEX(idefloppy_ref_mutex);
+ 
+ #define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref)
+@@ -539,39 +246,35 @@ static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk)
+ 	return floppy;
+ }
+ 
+-static void ide_floppy_release(struct kref *);
++static void idefloppy_cleanup_obj(struct kref *);
+ 
+ static void ide_floppy_put(struct ide_floppy_obj *floppy)
+ {
+ 	mutex_lock(&idefloppy_ref_mutex);
+-	kref_put(&floppy->kref, ide_floppy_release);
++	kref_put(&floppy->kref, idefloppy_cleanup_obj);
+ 	mutex_unlock(&idefloppy_ref_mutex);
+ }
+ 
+ /*
+- *	Too bad. The drive wants to send us data which we are not ready to accept.
+- *	Just throw it away.
++ * Too bad. The drive wants to send us data which we are not ready to accept.
++ * Just throw it away.
+  */
+-static void idefloppy_discard_data (ide_drive_t *drive, unsigned int bcount)
++static void idefloppy_discard_data(ide_drive_t *drive, unsigned int bcount)
+ {
+ 	while (bcount--)
+ 		(void) HWIF(drive)->INB(IDE_DATA_REG);
+ }
+ 
+-#if IDEFLOPPY_DEBUG_BUGS
+-static void idefloppy_write_zeros (ide_drive_t *drive, unsigned int bcount)
++static void idefloppy_write_zeros(ide_drive_t *drive, unsigned int bcount)
+ {
+ 	while (bcount--)
+ 		HWIF(drive)->OUTB(0, IDE_DATA_REG);
+ }
+-#endif /* IDEFLOPPY_DEBUG_BUGS */
+ 
+ 
  /*
-  *	Error codes which are returned in rq->errors to the higher part
-  *	of the driver.
-@@ -793,9 +712,8 @@ static void idefloppy_retry_pc (ide_drive_t *drive)
+- *	idefloppy_do_end_request is used to finish servicing a request.
+- *
+- *	For read/write requests, we will call ide_end_request to pass to the
+- *	next buffer.
++ * Used to finish servicing a request. For read/write requests, we will call
++ * ide_end_request to pass to the next buffer.
+  */
+ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs)
+ {
+@@ -579,12 +282,12 @@ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs)
+ 	struct request *rq = HWGROUP(drive)->rq;
+ 	int error;
+ 
+-	debug_log(KERN_INFO "Reached idefloppy_end_request\n");
++	debug_log("Reached %s\n", __func__);
+ 
+ 	switch (uptodate) {
+-		case 0: error = IDEFLOPPY_ERROR_GENERAL; break;
+-		case 1: error = 0; break;
+-		default: error = uptodate;
++	case 0: error = IDEFLOPPY_ERROR_GENERAL; break;
++	case 1: error = 0; break;
++	default: error = uptodate;
+ 	}
+ 	if (error)
+ 		floppy->failed_pc = NULL;
+@@ -602,39 +305,8 @@ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs)
+ 	return 0;
+ }
+ 
+-static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
+-{
+-	struct request *rq = pc->rq;
+-	struct bio_vec *bvec;
+-	struct req_iterator iter;
+-	unsigned long flags;
+-	char *data;
+-	int count, done = 0;
+-
+-	rq_for_each_segment(bvec, rq, iter) {
+-		if (!bcount)
+-			break;
+-
+-		count = min(bvec->bv_len, bcount);
+-
+-		data = bvec_kmap_irq(bvec, &flags);
+-		drive->hwif->atapi_input_bytes(drive, data, count);
+-		bvec_kunmap_irq(data, &flags);
+-
+-		bcount -= count;
+-		pc->b_count += count;
+-		done += count;
+-	}
+-
+-	idefloppy_do_end_request(drive, 1, done >> 9);
+-
+-	if (bcount) {
+-		printk(KERN_ERR "%s: leftover data in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount);
+-		idefloppy_discard_data(drive, bcount);
+-	}
+-}
+-
+-static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
++static void ide_floppy_io_buffers(ide_drive_t *drive, idefloppy_pc_t *pc,
++				  unsigned int bcount, int direction)
+ {
+ 	struct request *rq = pc->rq;
+ 	struct req_iterator iter;
+@@ -650,7 +322,10 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un
+ 		count = min(bvec->bv_len, bcount);
+ 
+ 		data = bvec_kmap_irq(bvec, &flags);
+-		drive->hwif->atapi_output_bytes(drive, data, count);
++		if (direction)
++			drive->hwif->atapi_output_bytes(drive, data, count);
++		else
++			drive->hwif->atapi_input_bytes(drive, data, count);
+ 		bvec_kunmap_irq(data, &flags);
+ 
+ 		bcount -= count;
+@@ -660,15 +335,18 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un
+ 
+ 	idefloppy_do_end_request(drive, 1, done >> 9);
+ 
+-#if IDEFLOPPY_DEBUG_BUGS
+ 	if (bcount) {
+-		printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
+-		idefloppy_write_zeros(drive, bcount);
++		printk(KERN_ERR "%s: leftover data in %s, bcount == %d\n",
++				drive->name, __func__, bcount);
++		if (direction)
++			idefloppy_write_zeros(drive, bcount);
++		else
++			idefloppy_discard_data(drive, bcount);
++
+ 	}
+-#endif
+ }
+ 
+-static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
++static void idefloppy_update_buffers(ide_drive_t *drive, idefloppy_pc_t *pc)
+ {
+ 	struct request *rq = pc->rq;
+ 	struct bio *bio = rq->bio;
+@@ -678,11 +356,12 @@ static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
+ }
+ 
+ /*
+- *	idefloppy_queue_pc_head generates a new packet command request in front
+- *	of the request queue, before the current request, so that it will be
+- *	processed immediately, on the next pass through the driver.
++ * Generate a new packet command request in front of the request queue, before
++ * the current request so that it will be processed immediately, on the next
++ * pass through the driver.
+  */
+-static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struct request *rq)
++static void idefloppy_queue_pc_head(ide_drive_t *drive, idefloppy_pc_t *pc,
++		struct request *rq)
+ {
+ 	struct ide_floppy_obj *floppy = drive->driver_data;
+ 
+@@ -693,16 +372,16 @@ static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struc
+ 	(void) ide_do_drive_cmd(drive, rq, ide_preempt);
+ }
+ 
+-static idefloppy_pc_t *idefloppy_next_pc_storage (ide_drive_t *drive)
++static idefloppy_pc_t *idefloppy_next_pc_storage(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 
+ 	if (floppy->pc_stack_index == IDEFLOPPY_PC_STACK)
+-		floppy->pc_stack_index=0;
++		floppy->pc_stack_index = 0;
+ 	return (&floppy->pc_stack[floppy->pc_stack_index++]);
+ }
+ 
+-static struct request *idefloppy_next_rq_storage (ide_drive_t *drive)
++static struct request *idefloppy_next_rq_storage(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 
+@@ -711,60 +390,53 @@ static struct request *idefloppy_next_rq_storage (ide_drive_t *drive)
+ 	return (&floppy->rq_stack[floppy->rq_stack_index++]);
+ }
+ 
+-/*
+- *	idefloppy_analyze_error is called on each failed packet command retry
+- *	to analyze the request sense.
+- */
+-static void idefloppy_analyze_error (ide_drive_t *drive,idefloppy_request_sense_result_t *result)
++static void idefloppy_request_sense_callback(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
++	u8 *buf = floppy->pc->buffer;
+ 
+-	floppy->sense_key = result->sense_key;
+-	floppy->asc = result->asc;
+-	floppy->ascq = result->ascq;
+-	floppy->progress_indication = result->sksv[0] & 0x80 ?
+-		(u16)get_unaligned((u16 *)(result->sksv+1)):0x10000;
+-	if (floppy->failed_pc)
+-		debug_log(KERN_INFO "ide-floppy: pc = %x, sense key = %x, "
+-			"asc = %x, ascq = %x\n", floppy->failed_pc->c[0],
+-			result->sense_key, result->asc, result->ascq);
+-	else
+-		debug_log(KERN_INFO "ide-floppy: sense key = %x, asc = %x, "
+-			"ascq = %x\n", result->sense_key,
+-			result->asc, result->ascq);
+-}
+-
+-static void idefloppy_request_sense_callback (ide_drive_t *drive)
+-{
+-	idefloppy_floppy_t *floppy = drive->driver_data;
++	debug_log("Reached %s\n", __func__);
+ 
+-	debug_log(KERN_INFO "ide-floppy: Reached %s\n", __FUNCTION__);
+-	
+ 	if (!floppy->pc->error) {
+-		idefloppy_analyze_error(drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer);
++		floppy->sense_key = buf[2] & 0x0F;
++		floppy->asc = buf[12];
++		floppy->ascq = buf[13];
++		floppy->progress_indication = buf[15] & 0x80 ?
++			(u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
++
++		if (floppy->failed_pc)
++			debug_log("pc = %x, sense key = %x, asc = %x,"
++					" ascq = %x\n",
++					floppy->failed_pc->c[0],
++					floppy->sense_key,
++					floppy->asc,
++					floppy->ascq);
++		else
++			debug_log("sense key = %x, asc = %x, ascq = %x\n",
++					floppy->sense_key,
++					floppy->asc,
++					floppy->ascq);
++
++
+ 		idefloppy_do_end_request(drive, 1, 0);
+ 	} else {
+-		printk(KERN_ERR "Error in REQUEST SENSE itself - Aborting request!\n");
++		printk(KERN_ERR "Error in REQUEST SENSE itself - Aborting"
++				" request!\n");
+ 		idefloppy_do_end_request(drive, 0, 0);
+ 	}
+ }
+ 
+-/*
+- *	General packet command callback function.
+- */
+-static void idefloppy_pc_callback (ide_drive_t *drive)
++/* General packet command callback function. */
++static void idefloppy_pc_callback(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+-	
+-	debug_log(KERN_INFO "ide-floppy: Reached %s\n", __FUNCTION__);
++
++	debug_log("Reached %s\n", __func__);
+ 
+ 	idefloppy_do_end_request(drive, floppy->pc->error ? 0 : 1, 0);
+ }
+ 
+-/*
+- *	idefloppy_init_pc initializes a packet command.
+- */
+-static void idefloppy_init_pc (idefloppy_pc_t *pc)
++static void idefloppy_init_pc(idefloppy_pc_t *pc)
+ {
+ 	memset(pc->c, 0, 12);
+ 	pc->retries = 0;
+@@ -775,76 +447,75 @@ static void idefloppy_init_pc (idefloppy_pc_t *pc)
+ 	pc->callback = &idefloppy_pc_callback;
+ }
+ 
+-static void idefloppy_create_request_sense_cmd (idefloppy_pc_t *pc)
++static void idefloppy_create_request_sense_cmd(idefloppy_pc_t *pc)
+ {
+-	idefloppy_init_pc(pc);	
+-	pc->c[0] = IDEFLOPPY_REQUEST_SENSE_CMD;
++	idefloppy_init_pc(pc);
++	pc->c[0] = GPCMD_REQUEST_SENSE;
+ 	pc->c[4] = 255;
+ 	pc->request_transfer = 18;
+ 	pc->callback = &idefloppy_request_sense_callback;
+ }
+ 
+ /*
+- *	idefloppy_retry_pc is called when an error was detected during the
+- *	last packet command. We queue a request sense packet command in
+- *	the head of the request list.
++ * Called when an error was detected during the last packet command. We queue a
++ * request sense packet command in the head of the request list.
+  */
+-static void idefloppy_retry_pc (ide_drive_t *drive)
++static void idefloppy_retry_pc(ide_drive_t *drive)
  {
  	idefloppy_pc_t *pc;
  	struct request *rq;
@@ -402966,7 +404400,14 @@
  	pc = idefloppy_next_pc_storage(drive);
  	rq = idefloppy_next_rq_storage(drive);
  	idefloppy_create_request_sense_cmd(pc);
-@@ -809,12 +727,12 @@ static void idefloppy_retry_pc (ide_drive_t *drive)
+ 	idefloppy_queue_pc_head(drive, pc, rq);
+ }
+ 
+-/*
+- *	idefloppy_pc_intr is the usual interrupt handler which will be called
+- *	during a packet command.
+- */
++/* The usual interrupt handler called during a packet command. */
  static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
  {
  	idefloppy_floppy_t *floppy = drive->driver_data;
@@ -402976,13 +404417,33 @@
 +	ide_hwif_t *hwif = drive->hwif;
  	idefloppy_pc_t *pc = floppy->pc;
  	struct request *rq = pc->rq;
++	xfer_func_t *xferfunc;
  	unsigned int temp;
+-
+-	debug_log(KERN_INFO "ide-floppy: Reached %s interrupt handler\n",
+-		__FUNCTION__);
+-
+-	if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
+-		if (HWIF(drive)->ide_dma_end(drive)) {
+-			set_bit(PC_DMA_ERROR, &pc->flags);
++	int dma_error = 0;
 +	u16 bcount;
 +	u8 stat, ireason;
- 
- 	debug_log(KERN_INFO "ide-floppy: Reached %s interrupt handler\n",
- 		__FUNCTION__);
-@@ -830,16 +748,16 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
++
++	debug_log("Reached %s interrupt handler\n", __func__);
++
++	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
++		dma_error = hwif->ide_dma_end(drive);
++		if (dma_error) {
++			printk(KERN_ERR "%s: DMA %s error\n", drive->name,
++					rq_data_dir(rq) ? "write" : "read");
++			pc->flags |= PC_FLAG_DMA_ERROR;
+ 		} else {
+ 			pc->actually_transferred = pc->request_transfer;
+ 			idefloppy_update_buffers(drive, pc);
+ 		}
+-		debug_log(KERN_INFO "ide-floppy: DMA finished\n");
++		debug_log("DMA finished\n");
  	}
  
  	/* Clear the interrupt */
@@ -402990,19 +404451,40 @@
 +	stat = drive->hwif->INB(IDE_STATUS_REG);
  
 -	if (!status.b.drq) {			/* No more interrupts */
-+	if ((stat & DRQ_STAT) == 0) {		/* No more interrupts */
- 		debug_log(KERN_INFO "Packet command completed, %d bytes "
- 			"transferred\n", pc->actually_transferred);
- 		clear_bit(PC_DMA_IN_PROGRESS, &pc->flags);
+-		debug_log(KERN_INFO "Packet command completed, %d bytes "
+-			"transferred\n", pc->actually_transferred);
+-		clear_bit(PC_DMA_IN_PROGRESS, &pc->flags);
++	/* No more interrupts */
++	if ((stat & DRQ_STAT) == 0) {
++		debug_log("Packet command completed, %d bytes transferred\n",
++				pc->actually_transferred);
++		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
  
  		local_irq_enable_in_hardirq();
  
 -		if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) {
-+		if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) {
++		if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
  			/* Error detected */
- 			debug_log(KERN_INFO "ide-floppy: %s: I/O error\n",
- 				drive->name);
-@@ -870,32 +788,32 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
+-			debug_log(KERN_INFO "ide-floppy: %s: I/O error\n",
+-				drive->name);
++			debug_log("%s: I/O error\n", drive->name);
+ 			rq->errors++;
+-			if (pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
++			if (pc->c[0] == GPCMD_REQUEST_SENSE) {
+ 				printk(KERN_ERR "ide-floppy: I/O error in "
+ 					"request sense command\n");
+ 				return ide_do_reset(drive);
+@@ -862,7 +533,8 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
+ 		return ide_stopped;
+ 	}
+ 
+-	if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
++	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
++		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
+ 		printk(KERN_ERR "ide-floppy: The floppy wants to issue "
+ 			"more interrupts in DMA mode\n");
+ 		ide_dma_off(drive);
+@@ -870,67 +542,60 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
  	}
  
  	/* Get the number of bytes to transfer */
@@ -403015,12 +404497,13 @@
 +	ireason = hwif->INB(IDE_IREASON_REG);
  
 -	if (ireason.b.cod) {
+-		printk(KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n");
 +	if (ireason & CD) {
- 		printk(KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n");
++		printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__);
  		return ide_do_reset(drive);
  	}
 -	if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) {
-+	if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) {
++	if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
  		/* Hopefully, we will never get here */
  		printk(KERN_ERR "ide-floppy: We wanted to %s, ",
 -			ireason.b.io ? "Write":"Read");
@@ -403030,7 +404513,8 @@
 +				(ireason & IO) ? "Read" : "Write");
  		return ide_do_reset(drive);
  	}
- 	if (!test_bit(PC_WRITING, &pc->flags)) {
+-	if (!test_bit(PC_WRITING, &pc->flags)) {
++	if (!(pc->flags & PC_FLAG_WRITING)) {
  		/* Reading - Check that we have enough space */
 -		temp = pc->actually_transferred + bcount.all;
 +		temp = pc->actually_transferred + bcount;
@@ -403040,43 +404524,69 @@
  					"to send us more data than expected "
  					"- discarding data\n");
 -				idefloppy_discard_data(drive,bcount.all);
+-				BUG_ON(HWGROUP(drive)->handler != NULL);
 +				idefloppy_discard_data(drive, bcount);
- 				BUG_ON(HWGROUP(drive)->handler != NULL);
++
  				ide_set_handler(drive,
  						&idefloppy_pc_intr,
-@@ -911,23 +829,21 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
- 	if (test_bit(PC_WRITING, &pc->flags)) {
- 		if (pc->buffer != NULL)
- 			/* Write the current buffer */
+ 						IDEFLOPPY_WAIT_CMD,
+ 						NULL);
+ 				return ide_started;
+ 			}
+-			debug_log(KERN_NOTICE "ide-floppy: The floppy wants to "
+-				"send us more data than expected - "
+-				"allowing transfer\n");
++			debug_log("The floppy wants to send us more data than"
++					" expected - allowing transfer\n");
+ 		}
+ 	}
+-	if (test_bit(PC_WRITING, &pc->flags)) {
+-		if (pc->buffer != NULL)
+-			/* Write the current buffer */
 -			HWIF(drive)->atapi_output_bytes(drive,
 -						pc->current_position,
 -						bcount.all);
-+			hwif->atapi_output_bytes(drive, pc->current_position,
-+						 bcount);
- 		else
+-		else
 -			idefloppy_output_buffers(drive, pc, bcount.all);
-+			idefloppy_output_buffers(drive, pc, bcount);
- 	} else {
- 		if (pc->buffer != NULL)
- 			/* Read the current buffer */
+-	} else {
+-		if (pc->buffer != NULL)
+-			/* Read the current buffer */
 -			HWIF(drive)->atapi_input_bytes(drive,
 -						pc->current_position,
 -						bcount.all);
-+			hwif->atapi_input_bytes(drive, pc->current_position,
-+						bcount);
- 		else
+-		else
 -			idefloppy_input_buffers(drive, pc, bcount.all);
-+			idefloppy_input_buffers(drive, pc, bcount);
- 	}
+-	}
++	if (pc->flags & PC_FLAG_WRITING)
++		xferfunc = hwif->atapi_output_bytes;
++	else
++		xferfunc = hwif->atapi_input_bytes;
++
++	if (pc->buffer)
++		xferfunc(drive, pc->current_position, bcount);
++	else
++		ide_floppy_io_buffers(drive, pc, bcount,
++				      !!(pc->flags & PC_FLAG_WRITING));
++
  	/* Update the current position */
 -	pc->actually_transferred += bcount.all;
 -	pc->current_position += bcount.all;
 +	pc->actually_transferred += bcount;
 +	pc->current_position += bcount;
  
- 	BUG_ON(HWGROUP(drive)->handler != NULL);
- 	ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);		/* And set the interrupt handler again */
-@@ -943,15 +859,15 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive)
+-	BUG_ON(HWGROUP(drive)->handler != NULL);
+-	ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);		/* And set the interrupt handler again */
++	/* And set the interrupt handler again */
++	ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
+ 	return ide_started;
+ }
+ 
+@@ -939,24 +604,24 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
+  * It fails at high speeds on the Iomega ZIP drive, so there's a slower version
+  * for that drive below. The algorithm is chosen based on drive type
+  */
+-static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive)
++static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive)
  {
  	ide_startstop_t startstop;
  	idefloppy_floppy_t *floppy = drive->driver_data;
@@ -403095,7 +404605,45 @@
  		printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while "
  				"issuing a packet command\n");
  		return ide_do_reset(drive);
-@@ -991,15 +907,15 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive)
+ 	}
+-	BUG_ON(HWGROUP(drive)->handler != NULL);
++
+ 	/* Set the interrupt routine */
+ 	ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
+ 	/* Send the actual packet */
+@@ -966,18 +631,16 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive)
+ 
+ 
+ /*
+- * What we have here is a classic case of a top half / bottom half
+- * interrupt service routine. In interrupt mode, the device sends
+- * an interrupt to signal it's ready to receive a packet. However,
+- * we need to delay about 2-3 ticks before issuing the packet or we
+- * gets in trouble.
++ * What we have here is a classic case of a top half / bottom half interrupt
++ * service routine. In interrupt mode, the device sends an interrupt to signal
++ * that it is ready to receive a packet. However, we need to delay about 2-3
++ * ticks before issuing the packet or we gets in trouble.
+  *
+- * So, follow carefully. transfer_pc1 is called as an interrupt (or
+- * directly). In either case, when the device says it's ready for a 
+- * packet, we schedule the packet transfer to occur about 2-3 ticks
+- * later in transfer_pc2.
++ * So, follow carefully. transfer_pc1 is called as an interrupt (or directly).
++ * In either case, when the device says it's ready for a packet, we schedule
++ * the packet transfer to occur about 2-3 ticks later in transfer_pc2.
+  */
+-static int idefloppy_transfer_pc2 (ide_drive_t *drive)
++static int idefloppy_transfer_pc2(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 
+@@ -987,24 +650,24 @@ static int idefloppy_transfer_pc2 (ide_drive_t *drive)
+ 	return IDEFLOPPY_WAIT_CMD;
+ }
+ 
+-static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive)
++static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive)
  {
  	idefloppy_floppy_t *floppy = drive->driver_data;
  	ide_startstop_t startstop;
@@ -403114,7 +404662,57 @@
  		printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) "
  				"while issuing a packet command\n");
  		return ide_do_reset(drive);
-@@ -1041,21 +957,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
+ 	}
+-	/* 
++	/*
+ 	 * The following delay solves a problem with ATAPI Zip 100 drives
+ 	 * where the Busy flag was apparently being deasserted before the
+ 	 * unit was ready to receive data. This was happening on a
+@@ -1012,112 +675,82 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive)
+ 	 * 40 and 50msec work well. idefloppy_pc_intr will not be actually
+ 	 * used until after the packet is moved in about 50 msec.
+ 	 */
+-	BUG_ON(HWGROUP(drive)->handler != NULL);
+-	ide_set_handler(drive, 
+-	  &idefloppy_pc_intr, 		/* service routine for packet command */
+-	  floppy->ticks,		/* wait this long before "failing" */
+-	  &idefloppy_transfer_pc2);	/* fail == transfer_pc2 */
++
++	ide_set_handler(drive, &idefloppy_pc_intr, floppy->ticks,
++			&idefloppy_transfer_pc2);
+ 	return ide_started;
+ }
+ 
+-/**
+- * idefloppy_should_report_error()
+- *
+- * Supresses error messages resulting from Medium not present
+- */
+-static inline int idefloppy_should_report_error(idefloppy_floppy_t *floppy)
++static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
++				    idefloppy_pc_t *pc)
+ {
++	/* supress error messages resulting from Medium not present */
+ 	if (floppy->sense_key == 0x02 &&
+ 	    floppy->asc       == 0x3a &&
+ 	    floppy->ascq      == 0x00)
+-		return 0;
+-	return 1;
++		return;
++
++	printk(KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, "
++			"asc = %2x, ascq = %2x\n",
++			floppy->drive->name, pc->c[0], floppy->sense_key,
++			floppy->asc, floppy->ascq);
++
+ }
+ 
+-/*
+- *	Issue a packet command
+- */
+-static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *pc)
++static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
++		idefloppy_pc_t *pc)
  {
  	idefloppy_floppy_t *floppy = drive->driver_data;
  	ide_hwif_t *hwif = drive->hwif;
@@ -403137,22 +404735,64 @@
 +	u8 dma;
  
  	if (floppy->failed_pc == NULL &&
- 	    pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD)
-@@ -1093,25 +997,20 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
+-	    pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD)
++	    pc->c[0] != GPCMD_REQUEST_SENSE)
+ 		floppy->failed_pc = pc;
+ 	/* Set the current packet command */
+ 	floppy->pc = pc;
+ 
+-	if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES ||
+-	    test_bit(PC_ABORT, &pc->flags)) {
+-		/*
+-		 *	We will "abort" retrying a packet command in case
+-		 *	a legitimate error code was received.
+-		 */
+-		if (!test_bit(PC_ABORT, &pc->flags)) {
+-			if (!test_bit(PC_SUPPRESS_ERROR, &pc->flags)) {
+-				if (idefloppy_should_report_error(floppy))
+-					printk(KERN_ERR "ide-floppy: %s: I/O error, "
+-					       "pc = %2x, key = %2x, "
+-					       "asc = %2x, ascq = %2x\n",
+-					       drive->name, pc->c[0],
+-					       floppy->sense_key,
+-					       floppy->asc, floppy->ascq);
+-			}
+-			/* Giving up */
+-			pc->error = IDEFLOPPY_ERROR_GENERAL;
+-		}
++	if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) {
++		if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
++			ide_floppy_report_error(floppy, pc);
++		/* Giving up */
++		pc->error = IDEFLOPPY_ERROR_GENERAL;
++
+ 		floppy->failed_pc = NULL;
+ 		pc->callback(drive);
+ 		return ide_stopped;
+ 	}
+ 
+-	debug_log(KERN_INFO "Retry number - %d\n",pc->retries);
++	debug_log("Retry number - %d\n", pc->retries);
+ 
+ 	pc->retries++;
  	/* We haven't transferred any data yet */
  	pc->actually_transferred = 0;
  	pc->current_position = pc->buffer;
 -	bcount.all = min(pc->request_transfer, 63 * 1024);
 +	bcount = min(pc->request_transfer, 63 * 1024);
  
- 	if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags))
+-	if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags))
++	if (pc->flags & PC_FLAG_DMA_ERROR) {
++		pc->flags &= ~PC_FLAG_DMA_ERROR;
  		ide_dma_off(drive);
- 
--	feature.all = 0;
++	}
 +	dma = 0;
  
- 	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
+-	feature.all = 0;
+-
+-	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
 -		feature.b.dma = !hwif->dma_setup(drive);
++	if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma)
 +		dma = !hwif->dma_setup(drive);
  
 -	if (IDE_CONTROL_REG)
@@ -403166,13 +404806,691 @@
 +			   IDE_TFLAG_OUT_DEVICE, bcount, dma);
  
 -	if (feature.b.dma) {	/* Begin DMA, if necessary */
-+	if (dma) {	/* Begin DMA, if necessary */
- 		set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
+-		set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
++	if (dma) {
++		/* Begin DMA, if necessary */
++		pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
  		hwif->dma_start(drive);
  	}
-@@ -1665,14 +1564,14 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
- 		/* Else assume format_unit has finished, and we're
- 		** at 0x10000 */
+ 
+ 	/* Can we transfer the packet when we get the interrupt or wait? */
+-	if (test_bit(IDEFLOPPY_ZIP_DRIVE, &floppy->flags)) {
++	if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) {
+ 		/* wait */
+ 		pkt_xfer_routine = &idefloppy_transfer_pc1;
+ 	} else {
+@@ -1125,7 +758,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
+ 		pkt_xfer_routine = &idefloppy_transfer_pc;
+ 	}
+ 	
+-	if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
++	if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) {
+ 		/* Issue the packet command */
+ 		ide_execute_command(drive, WIN_PACKETCMD,
+ 				pkt_xfer_routine,
+@@ -1139,38 +772,37 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
+ 	}
+ }
+ 
+-static void idefloppy_rw_callback (ide_drive_t *drive)
++static void idefloppy_rw_callback(ide_drive_t *drive)
+ {
+-	debug_log(KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n");
++	debug_log("Reached %s\n", __func__);
+ 
+ 	idefloppy_do_end_request(drive, 1, 0);
+ 	return;
+ }
+ 
+-static void idefloppy_create_prevent_cmd (idefloppy_pc_t *pc, int prevent)
++static void idefloppy_create_prevent_cmd(idefloppy_pc_t *pc, int prevent)
+ {
+-	debug_log(KERN_INFO "ide-floppy: creating prevent removal command, "
+-		"prevent = %d\n", prevent);
++	debug_log("creating prevent removal command, prevent = %d\n", prevent);
+ 
+ 	idefloppy_init_pc(pc);
+-	pc->c[0] = IDEFLOPPY_PREVENT_REMOVAL_CMD;
++	pc->c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
+ 	pc->c[4] = prevent;
+ }
+ 
+-static void idefloppy_create_read_capacity_cmd (idefloppy_pc_t *pc)
++static void idefloppy_create_read_capacity_cmd(idefloppy_pc_t *pc)
+ {
+ 	idefloppy_init_pc(pc);
+-	pc->c[0] = IDEFLOPPY_READ_CAPACITY_CMD;
++	pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES;
+ 	pc->c[7] = 255;
+ 	pc->c[8] = 255;
+ 	pc->request_transfer = 255;
+ }
+ 
+-static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l,
++static void idefloppy_create_format_unit_cmd(idefloppy_pc_t *pc, int b, int l,
+ 					      int flags)
+ {
+ 	idefloppy_init_pc(pc);
+-	pc->c[0] = IDEFLOPPY_FORMAT_UNIT_CMD;
++	pc->c[0] = GPCMD_FORMAT_UNIT;
+ 	pc->c[1] = 0x17;
+ 
+ 	memset(pc->buffer, 0, 12);
+@@ -1181,83 +813,79 @@ static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l,
+ 		pc->buffer[1] ^= 0x20;		/* ... turn off DCRT bit */
+ 	pc->buffer[3] = 8;
+ 
+-	put_unaligned(htonl(b), (unsigned int *)(&pc->buffer[4]));
+-	put_unaligned(htonl(l), (unsigned int *)(&pc->buffer[8]));
+-	pc->buffer_size=12;
+-	set_bit(PC_WRITING, &pc->flags);
++	put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buffer[4]));
++	put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buffer[8]));
++	pc->buffer_size = 12;
++	pc->flags |= PC_FLAG_WRITING;
+ }
+ 
+-/*
+- *	A mode sense command is used to "sense" floppy parameters.
+- */
+-static void idefloppy_create_mode_sense_cmd (idefloppy_pc_t *pc, u8 page_code, u8 type)
++/* A mode sense command is used to "sense" floppy parameters. */
++static void idefloppy_create_mode_sense_cmd(idefloppy_pc_t *pc, u8 page_code,
++		u8 type)
+ {
+-	u16 length = sizeof(idefloppy_mode_parameter_header_t);
+-	
++	u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */
++
+ 	idefloppy_init_pc(pc);
+-	pc->c[0] = IDEFLOPPY_MODE_SENSE_CMD;
++	pc->c[0] = GPCMD_MODE_SENSE_10;
+ 	pc->c[1] = 0;
+ 	pc->c[2] = page_code + (type << 6);
+ 
+ 	switch (page_code) {
+-		case IDEFLOPPY_CAPABILITIES_PAGE:
+-			length += 12;
+-			break;
+-		case IDEFLOPPY_FLEXIBLE_DISK_PAGE:
+-			length += 32;
+-			break;
+-		default:
+-			printk(KERN_ERR "ide-floppy: unsupported page code "
++	case IDEFLOPPY_CAPABILITIES_PAGE:
++		length += 12;
++		break;
++	case IDEFLOPPY_FLEXIBLE_DISK_PAGE:
++		length += 32;
++		break;
++	default:
++		printk(KERN_ERR "ide-floppy: unsupported page code "
+ 				"in create_mode_sense_cmd\n");
+ 	}
+-	put_unaligned(htons(length), (u16 *) &pc->c[7]);
++	put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]);
+ 	pc->request_transfer = length;
+ }
+ 
+-static void idefloppy_create_start_stop_cmd (idefloppy_pc_t *pc, int start)
++static void idefloppy_create_start_stop_cmd(idefloppy_pc_t *pc, int start)
+ {
+ 	idefloppy_init_pc(pc);
+-	pc->c[0] = IDEFLOPPY_START_STOP_CMD;
++	pc->c[0] = GPCMD_START_STOP_UNIT;
+ 	pc->c[4] = start;
+ }
+ 
+ static void idefloppy_create_test_unit_ready_cmd(idefloppy_pc_t *pc)
+ {
+ 	idefloppy_init_pc(pc);
+-	pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD;
++	pc->c[0] = GPCMD_TEST_UNIT_READY;
+ }
+ 
+-static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector)
++static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
++				    idefloppy_pc_t *pc, struct request *rq,
++				    unsigned long sector)
+ {
+ 	int block = sector / floppy->bs_factor;
+ 	int blocks = rq->nr_sectors / floppy->bs_factor;
+ 	int cmd = rq_data_dir(rq);
+ 
+-	debug_log("create_rw1%d_cmd: block == %d, blocks == %d\n",
+-		2 * test_bit (IDEFLOPPY_USE_READ12, &floppy->flags),
++	debug_log("create_rw10_cmd: block == %d, blocks == %d\n",
+ 		block, blocks);
+ 
+ 	idefloppy_init_pc(pc);
+-	if (test_bit(IDEFLOPPY_USE_READ12, &floppy->flags)) {
+-		pc->c[0] = cmd == READ ? IDEFLOPPY_READ12_CMD : IDEFLOPPY_WRITE12_CMD;
+-		put_unaligned(htonl(blocks), (unsigned int *) &pc->c[6]);
+-	} else {
+-		pc->c[0] = cmd == READ ? IDEFLOPPY_READ10_CMD : IDEFLOPPY_WRITE10_CMD;
+-		put_unaligned(htons(blocks), (unsigned short *) &pc->c[7]);
+-	}
+-	put_unaligned(htonl(block), (unsigned int *) &pc->c[2]);
++	pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10;
++	put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]);
++	put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]);
++
+ 	pc->callback = &idefloppy_rw_callback;
+ 	pc->rq = rq;
+ 	pc->b_count = cmd == READ ? 0 : rq->bio->bi_size;
+ 	if (rq->cmd_flags & REQ_RW)
+-		set_bit(PC_WRITING, &pc->flags);
++		pc->flags |= PC_FLAG_WRITING;
+ 	pc->buffer = NULL;
+ 	pc->request_transfer = pc->buffer_size = blocks * floppy->block_size;
+-	set_bit(PC_DMA_RECOMMENDED, &pc->flags);
++	pc->flags |= PC_FLAG_DMA_RECOMMENDED;
+ }
+ 
+-static void
+-idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq)
++static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
++		idefloppy_pc_t *pc, struct request *rq)
+ {
+ 	idefloppy_init_pc(pc);
+ 	pc->callback = &idefloppy_rw_callback;
+@@ -1265,11 +893,10 @@ idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct req
+ 	pc->rq = rq;
+ 	pc->b_count = rq->data_len;
+ 	if (rq->data_len && rq_data_dir(rq) == WRITE)
+-		set_bit(PC_WRITING, &pc->flags);
++		pc->flags |= PC_FLAG_WRITING;
+ 	pc->buffer = rq->data;
+ 	if (rq->bio)
+-		set_bit(PC_DMA_RECOMMENDED, &pc->flags);
+-		
++		pc->flags |= PC_FLAG_DMA_RECOMMENDED;
+ 	/*
+ 	 * possibly problematic, doesn't look like ide-floppy correctly
+ 	 * handled scattered requests if dma fails...
+@@ -1277,30 +904,23 @@ idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct req
+ 	pc->request_transfer = pc->buffer_size = rq->data_len;
+ }
+ 
+-/*
+- *	idefloppy_do_request is our request handling function.	
+- */
+-static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request *rq, sector_t block_s)
++static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
++		struct request *rq, sector_t block_s)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 	idefloppy_pc_t *pc;
+ 	unsigned long block = (unsigned long)block_s;
+ 
+-	debug_log(KERN_INFO "dev: %s, flags: %lx, errors: %d\n",
++	debug_log("dev: %s, cmd_type: %x, errors: %d\n",
+ 			rq->rq_disk ? rq->rq_disk->disk_name : "?",
+-			rq->flags, rq->errors);
+-	debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, "
++			rq->cmd_type, rq->errors);
++	debug_log("sector: %ld, nr_sectors: %ld, "
+ 			"current_nr_sectors: %d\n", (long)rq->sector,
+ 			rq->nr_sectors, rq->current_nr_sectors);
+ 
+ 	if (rq->errors >= ERROR_MAX) {
+-		if (floppy->failed_pc != NULL) {
+-			if (idefloppy_should_report_error(floppy))
+-				printk(KERN_ERR "ide-floppy: %s: I/O error, pc = %2x,"
+-				       " key = %2x, asc = %2x, ascq = %2x\n",
+-				       drive->name, floppy->failed_pc->c[0],
+-				       floppy->sense_key, floppy->asc, floppy->ascq);
+-		}
++		if (floppy->failed_pc)
++			ide_floppy_report_error(floppy, floppy->failed_pc);
+ 		else
+ 			printk(KERN_ERR "ide-floppy: %s: I/O error\n",
+ 				drive->name);
+@@ -1310,8 +930,8 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
+ 	if (blk_fs_request(rq)) {
+ 		if (((long)rq->sector % floppy->bs_factor) ||
+ 		    (rq->nr_sectors % floppy->bs_factor)) {
+-			printk("%s: unsupported r/w request size\n",
+-				drive->name);
++			printk(KERN_ERR "%s: unsupported r/w request size\n",
++					drive->name);
+ 			idefloppy_do_end_request(drive, 0, 0);
+ 			return ide_stopped;
+ 		}
+@@ -1334,15 +954,15 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
+ }
+ 
+ /*
+- *	idefloppy_queue_pc_tail adds a special packet command request to the
+- *	tail of the request queue, and waits for it to be serviced.
++ * Add a special packet command request to the tail of the request queue,
++ * and wait for it to be serviced.
+  */
+-static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc)
++static int idefloppy_queue_pc_tail(ide_drive_t *drive, idefloppy_pc_t *pc)
+ {
+ 	struct ide_floppy_obj *floppy = drive->driver_data;
+ 	struct request rq;
+ 
+-	ide_init_drive_cmd (&rq);
++	ide_init_drive_cmd(&rq);
+ 	rq.buffer = (char *) pc;
+ 	rq.cmd_type = REQ_TYPE_SPECIAL;
+ 	rq.rq_disk = floppy->disk;
+@@ -1351,88 +971,90 @@ static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc)
+ }
+ 
+ /*
+- *	Look at the flexible disk page parameters. We will ignore the CHS
+- *	capacity parameters and use the LBA parameters instead.
++ * Look at the flexible disk page parameters. We ignore the CHS capacity
++ * parameters and use the LBA parameters instead.
+  */
+-static int idefloppy_get_flexible_disk_page (ide_drive_t *drive)
++static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 	idefloppy_pc_t pc;
+-	idefloppy_mode_parameter_header_t *header;
+-	idefloppy_flexible_disk_page_t *page;
++	u8 *page;
+ 	int capacity, lba_capacity;
++	u16 transfer_rate, sector_size, cyls, rpm;
++	u8 heads, sectors;
++
++	idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE,
++					MODE_SENSE_CURRENT);
+ 
+-	idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE, MODE_SENSE_CURRENT);
+-	if (idefloppy_queue_pc_tail(drive,&pc)) {
+-		printk(KERN_ERR "ide-floppy: Can't get flexible disk "
+-			"page parameters\n");
++	if (idefloppy_queue_pc_tail(drive, &pc)) {
++		printk(KERN_ERR "ide-floppy: Can't get flexible disk page"
++				" parameters\n");
+ 		return 1;
+ 	}
+-	header = (idefloppy_mode_parameter_header_t *) pc.buffer;
+-	floppy->wp = header->wp;
++	floppy->wp = !!(pc.buffer[3] & 0x80);
+ 	set_disk_ro(floppy->disk, floppy->wp);
+-	page = (idefloppy_flexible_disk_page_t *) (header + 1);
+-
+-	page->transfer_rate = ntohs(page->transfer_rate);
+-	page->sector_size = ntohs(page->sector_size);
+-	page->cyls = ntohs(page->cyls);
+-	page->rpm = ntohs(page->rpm);
+-	capacity = page->cyls * page->heads * page->sectors * page->sector_size;
+-	if (memcmp (page, &floppy->flexible_disk_page, sizeof (idefloppy_flexible_disk_page_t)))
++	page = &pc.buffer[8];
++
++	transfer_rate = be16_to_cpu(*(u16 *)&pc.buffer[8 + 2]);
++	sector_size   = be16_to_cpu(*(u16 *)&pc.buffer[8 + 6]);
++	cyls          = be16_to_cpu(*(u16 *)&pc.buffer[8 + 8]);
++	rpm           = be16_to_cpu(*(u16 *)&pc.buffer[8 + 28]);
++	heads         = pc.buffer[8 + 4];
++	sectors       = pc.buffer[8 + 5];
++
++	capacity = cyls * heads * sectors * sector_size;
++
++	if (memcmp(page, &floppy->flexible_disk_page, 32))
+ 		printk(KERN_INFO "%s: %dkB, %d/%d/%d CHS, %d kBps, "
+ 				"%d sector size, %d rpm\n",
+-			drive->name, capacity / 1024, page->cyls,
+-			page->heads, page->sectors,
+-			page->transfer_rate / 8, page->sector_size, page->rpm);
+-
+-	floppy->flexible_disk_page = *page;
+-	drive->bios_cyl = page->cyls;
+-	drive->bios_head = page->heads;
+-	drive->bios_sect = page->sectors;
++				drive->name, capacity / 1024, cyls, heads,
++				sectors, transfer_rate / 8, sector_size, rpm);
++
++	memcpy(&floppy->flexible_disk_page, page, 32);
++	drive->bios_cyl = cyls;
++	drive->bios_head = heads;
++	drive->bios_sect = sectors;
+ 	lba_capacity = floppy->blocks * floppy->block_size;
++
+ 	if (capacity < lba_capacity) {
+ 		printk(KERN_NOTICE "%s: The disk reports a capacity of %d "
+ 			"bytes, but the drive only handles %d\n",
+ 			drive->name, lba_capacity, capacity);
+-		floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0;
++		floppy->blocks = floppy->block_size ?
++			capacity / floppy->block_size : 0;
+ 	}
+ 	return 0;
+ }
+ 
+-static int idefloppy_get_capability_page(ide_drive_t *drive)
++static int idefloppy_get_sfrp_bit(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 	idefloppy_pc_t pc;
+-	idefloppy_mode_parameter_header_t *header;
+-	idefloppy_capabilities_page_t *page;
+ 
+ 	floppy->srfp = 0;
+ 	idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE,
+ 						 MODE_SENSE_CURRENT);
+ 
+-	set_bit(PC_SUPPRESS_ERROR, &pc.flags);
+-	if (idefloppy_queue_pc_tail(drive,&pc)) {
++	pc.flags |= PC_FLAG_SUPPRESS_ERROR;
++	if (idefloppy_queue_pc_tail(drive, &pc))
+ 		return 1;
+-	}
+ 
+-	header = (idefloppy_mode_parameter_header_t *) pc.buffer;
+-	page= (idefloppy_capabilities_page_t *)(header+1);
+-	floppy->srfp = page->srfp;
++	floppy->srfp = pc.buffer[8 + 2] & 0x40;
+ 	return (0);
+ }
+ 
+ /*
+- *	Determine if a media is present in the floppy drive, and if so,
+- *	its LBA capacity.
++ * Determine if a media is present in the floppy drive, and if so, its LBA
++ * capacity.
+  */
+-static int idefloppy_get_capacity (ide_drive_t *drive)
++static int ide_floppy_get_capacity(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 	idefloppy_pc_t pc;
+-	idefloppy_capacity_header_t *header;
+-	idefloppy_capacity_descriptor_t *descriptor;
+-	int i, descriptors, rc = 1, blocks, length;
+-	
++	u8 *cap_desc;
++	u8 header_len, desc_cnt;
++	int i, rc = 1, blocks, length;
++
+ 	drive->bios_cyl = 0;
+ 	drive->bios_head = drive->bios_sect = 0;
+ 	floppy->blocks = 0;
+@@ -1444,44 +1066,55 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
+ 		printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
+ 		return 1;
+ 	}
+-	header = (idefloppy_capacity_header_t *) pc.buffer;
+-	descriptors = header->length / sizeof(idefloppy_capacity_descriptor_t);
+-	descriptor = (idefloppy_capacity_descriptor_t *) (header + 1);
++	header_len = pc.buffer[3];
++	cap_desc = &pc.buffer[4];
++	desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */
++
++	for (i = 0; i < desc_cnt; i++) {
++		unsigned int desc_start = 4 + i*8;
++
++		blocks = be32_to_cpu(*(u32 *)&pc.buffer[desc_start]);
++		length = be16_to_cpu(*(u16 *)&pc.buffer[desc_start + 6]);
+ 
+-	for (i = 0; i < descriptors; i++, descriptor++) {
+-		blocks = descriptor->blocks = ntohl(descriptor->blocks);
+-		length = descriptor->length = ntohs(descriptor->length);
++		debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n",
++				i, blocks * length / 1024, blocks, length);
++
++		if (i)
++			continue;
++		/*
++		 * the code below is valid only for the 1st descriptor, ie i=0
++		 */
+ 
+-		if (!i) 
+-		{
+-		switch (descriptor->dc) {
++		switch (pc.buffer[desc_start + 4] & 0x03) {
+ 		/* Clik! drive returns this instead of CAPACITY_CURRENT */
+ 		case CAPACITY_UNFORMATTED:
+-			if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags))
+-                                /*
++			if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE))
++				/*
+ 				 * If it is not a clik drive, break out
+ 				 * (maintains previous driver behaviour)
+ 				 */
+ 				break;
+ 		case CAPACITY_CURRENT:
+ 			/* Normal Zip/LS-120 disks */
+-			if (memcmp(descriptor, &floppy->capacity, sizeof (idefloppy_capacity_descriptor_t)))
++			if (memcmp(cap_desc, &floppy->cap_desc, 8))
+ 				printk(KERN_INFO "%s: %dkB, %d blocks, %d "
+ 					"sector size\n", drive->name,
+ 					blocks * length / 1024, blocks, length);
+-			floppy->capacity = *descriptor;
++			memcpy(&floppy->cap_desc, cap_desc, 8);
++
+ 			if (!length || length % 512) {
+ 				printk(KERN_NOTICE "%s: %d bytes block size "
+ 					"not supported\n", drive->name, length);
+ 			} else {
+-                                floppy->blocks = blocks;
+-                                floppy->block_size = length;
+-                                if ((floppy->bs_factor = length / 512) != 1)
+-                                        printk(KERN_NOTICE "%s: warning: non "
++				floppy->blocks = blocks;
++				floppy->block_size = length;
++				floppy->bs_factor = length / 512;
++				if (floppy->bs_factor != 1)
++					printk(KERN_NOTICE "%s: warning: non "
+ 						"512 bytes block size not "
+ 						"fully supported\n",
+ 						drive->name);
+-                                rc = 0;
++				rc = 0;
+ 			}
+ 			break;
+ 		case CAPACITY_NO_CARTRIDGE:
+@@ -1496,54 +1129,42 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
+ 				"in drive\n", drive->name);
+ 			break;
+ 		}
+-		}
+-		if (!i) {
+-			debug_log( "Descriptor 0 Code: %d\n",
+-				descriptor->dc);
+-		}
+-		debug_log( "Descriptor %d: %dkB, %d blocks, %d "
+-			"sector size\n", i, blocks * length / 1024, blocks,
+-			length);
++		debug_log("Descriptor 0 Code: %d\n",
++			  pc.buffer[desc_start + 4] & 0x03);
+ 	}
+ 
+ 	/* Clik! disk does not support get_flexible_disk_page */
+-        if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
+-		(void) idefloppy_get_flexible_disk_page(drive);
+-	}
++	if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE))
++		(void) ide_floppy_get_flexible_disk_page(drive);
+ 
+ 	set_capacity(floppy->disk, floppy->blocks * floppy->bs_factor);
+ 	return rc;
+ }
+ 
+ /*
+-** Obtain the list of formattable capacities.
+-** Very similar to idefloppy_get_capacity, except that we push the capacity
+-** descriptors to userland, instead of our own structures.
+-**
+-** Userland gives us the following structure:
+-**
+-** struct idefloppy_format_capacities {
+-**        int nformats;
+-**        struct {
+-**                int nblocks;
+-**                int blocksize;
+-**                } formats[];
+-**        } ;
+-**
+-** userland initializes nformats to the number of allocated formats[]
+-** records.  On exit we set nformats to the number of records we've
+-** actually initialized.
+-**
+-*/
+-
+-static int idefloppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
++ * Obtain the list of formattable capacities.
++ * Very similar to ide_floppy_get_capacity, except that we push the capacity
++ * descriptors to userland, instead of our own structures.
++ *
++ * Userland gives us the following structure:
++ *
++ * struct idefloppy_format_capacities {
++ *	int nformats;
++ *	struct {
++ *		int nblocks;
++ *		int blocksize;
++ *	} formats[];
++ * };
++ *
++ * userland initializes nformats to the number of allocated formats[] records.
++ * On exit we set nformats to the number of records we've actually initialized.
++ */
++
++static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
+ {
+-        idefloppy_pc_t pc;
+-	idefloppy_capacity_header_t *header;
+-        idefloppy_capacity_descriptor_t *descriptor;
+-	int i, descriptors, blocks, length;
+-	int u_array_size;
+-	int u_index;
++	idefloppy_pc_t pc;
++	u8 header_len, desc_cnt;
++	int i, blocks, length, u_array_size, u_index;
+ 	int __user *argp;
+ 
+ 	if (get_user(u_array_size, arg))
+@@ -1555,30 +1176,27 @@ static int idefloppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
+ 	idefloppy_create_read_capacity_cmd(&pc);
+ 	if (idefloppy_queue_pc_tail(drive, &pc)) {
+ 		printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
+-                return (-EIO);
+-        }
+-        header = (idefloppy_capacity_header_t *) pc.buffer;
+-        descriptors = header->length /
+-		sizeof(idefloppy_capacity_descriptor_t);
+-	descriptor = (idefloppy_capacity_descriptor_t *) (header + 1);
++		return (-EIO);
++	}
++	header_len = pc.buffer[3];
++	desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */
+ 
+ 	u_index = 0;
+ 	argp = arg + 1;
+ 
+ 	/*
+-	** We always skip the first capacity descriptor.  That's the
+-	** current capacity.  We are interested in the remaining descriptors,
+-	** the formattable capacities.
+-	*/
++	 * We always skip the first capacity descriptor.  That's the current
++	 * capacity.  We are interested in the remaining descriptors, the
++	 * formattable capacities.
++	 */
++	for (i = 1; i < desc_cnt; i++) {
++		unsigned int desc_start = 4 + i*8;
+ 
+-	for (i=0; i<descriptors; i++, descriptor++) {
+ 		if (u_index >= u_array_size)
+ 			break;	/* User-supplied buffer too small */
+-		if (i == 0)
+-			continue;	/* Skip the first descriptor */
+ 
+-		blocks = ntohl(descriptor->blocks);
+-		length = ntohs(descriptor->length);
++		blocks = be32_to_cpu(*(u32 *)&pc.buffer[desc_start]);
++		length = be16_to_cpu(*(u16 *)&pc.buffer[desc_start + 6]);
+ 
+ 		if (put_user(blocks, argp))
+ 			return(-EFAULT);
+@@ -1597,53 +1215,14 @@ static int idefloppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
+ }
+ 
+ /*
+-** Send ATAPI_FORMAT_UNIT to the drive.
+-**
+-** Userland gives us the following structure:
+-**
+-** struct idefloppy_format_command {
+-**        int nblocks;
+-**        int blocksize;
+-**        int flags;
+-**        } ;
+-**
+-** flags is a bitmask, currently, the only defined flag is:
+-**
+-**        0x01 - verify media after format.
+-*/
+-
+-static int idefloppy_begin_format(ide_drive_t *drive, int __user *arg)
+-{
+-	int blocks;
+-	int length;
+-	int flags;
+-	idefloppy_pc_t pc;
+-
+-	if (get_user(blocks, arg) ||
+-	    get_user(length, arg+1) ||
+-	    get_user(flags, arg+2)) {
+-		return (-EFAULT);
+-	}
+-
+-	/* Get the SFRP bit */
+-	(void) idefloppy_get_capability_page(drive);
+-	idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);
+-	if (idefloppy_queue_pc_tail(drive, &pc)) {
+-                return (-EIO);
+-	}
+-
+-	return (0);
+-}
+-
+-/*
+-** Get ATAPI_FORMAT_UNIT progress indication.
+-**
+-** Userland gives a pointer to an int.  The int is set to a progress
+-** indicator 0-65536, with 65536=100%.
+-**
+-** If the drive does not support format progress indication, we just check
+-** the dsc bit, and return either 0 or 65536.
+-*/
++ * Get ATAPI_FORMAT_UNIT progress indication.
++ *
++ * Userland gives a pointer to an int.  The int is set to a progress
++ * indicator 0-65536, with 65536=100%.
++ *
++ * If the drive does not support format progress indication, we just check
++ * the dsc bit, and return either 0 or 65536.
++ */
+ 
+ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
+ {
+@@ -1653,26 +1232,24 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
+ 
+ 	if (floppy->srfp) {
+ 		idefloppy_create_request_sense_cmd(&pc);
+-		if (idefloppy_queue_pc_tail(drive, &pc)) {
++		if (idefloppy_queue_pc_tail(drive, &pc))
+ 			return (-EIO);
+-		}
+ 
+ 		if (floppy->sense_key == 2 &&
+ 		    floppy->asc == 4 &&
+-		    floppy->ascq == 4) {
++		    floppy->ascq == 4)
+ 			progress_indication = floppy->progress_indication;
+-		}
+-		/* Else assume format_unit has finished, and we're
+-		** at 0x10000 */
++
++		/* Else assume format_unit has finished, and we're at 0x10000 */
  	} else {
 -		atapi_status_t status;
  		unsigned long flags;
@@ -403188,18 +405506,79 @@
  	}
  	if (put_user(progress_indication, arg))
  		return (-EFAULT);
-@@ -1699,7 +1598,6 @@ static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id)
+@@ -1680,10 +1257,7 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
+ 	return (0);
+ }
+ 
+-/*
+- *	Return the current floppy capacity.
+- */
+-static sector_t idefloppy_capacity (ide_drive_t *drive)
++static sector_t idefloppy_capacity(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 	unsigned long capacity = floppy->blocks * floppy->bs_factor;
+@@ -1692,16 +1266,12 @@ static sector_t idefloppy_capacity (ide_drive_t *drive)
+ }
+ 
+ /*
+- *	idefloppy_identify_device checks if we can support a drive,
+- *	based on the ATAPI IDENTIFY command results.
++ * Check whether we can support a drive, based on the ATAPI IDENTIFY command
++ * results.
+  */
+-static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id)
++static int idefloppy_identify_device(ide_drive_t *drive, struct hd_driveid *id)
  {
  	struct idefloppy_id_gcw gcw;
- #if IDEFLOPPY_DEBUG_INFO
+-#if IDEFLOPPY_DEBUG_INFO
 -	u16 mask,i;
- 	char buffer[80];
- #endif /* IDEFLOPPY_DEBUG_INFO */
+-	char buffer[80];
+-#endif /* IDEFLOPPY_DEBUG_INFO */
  
-@@ -1746,55 +1644,6 @@ static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id)
- 		default: sprintf(buffer, "Reserved");break;
- 	}
- 	printk(KERN_INFO "Command Packet Size: %s\n", buffer);
+ 	*((u16 *) &gcw) = id->config;
+ 
+@@ -1710,103 +1280,23 @@ static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id)
+ 	if ((gcw.device_type == 5) &&
+ 	    !strstr(id->model, "CD-ROM") &&
+ 	    strstr(id->model, "ZIP"))
+-		gcw.device_type = 0;			
++		gcw.device_type = 0;
+ #endif
+ 
+-#if IDEFLOPPY_DEBUG_INFO
+-	printk(KERN_INFO "Dumping ATAPI Identify Device floppy parameters\n");
+-	switch (gcw.protocol) {
+-		case 0: case 1: sprintf(buffer, "ATA");break;
+-		case 2:	sprintf(buffer, "ATAPI");break;
+-		case 3: sprintf(buffer, "Reserved (Unknown to ide-floppy)");break;
+-	}
+-	printk(KERN_INFO "Protocol Type: %s\n", buffer);
+-	switch (gcw.device_type) {
+-		case 0: sprintf(buffer, "Direct-access Device");break;
+-		case 1: sprintf(buffer, "Streaming Tape Device");break;
+-		case 2: case 3: case 4: sprintf (buffer, "Reserved");break;
+-		case 5: sprintf(buffer, "CD-ROM Device");break;
+-		case 6: sprintf(buffer, "Reserved");
+-		case 7: sprintf(buffer, "Optical memory Device");break;
+-		case 0x1f: sprintf(buffer, "Unknown or no Device type");break;
+-		default: sprintf(buffer, "Reserved");
+-	}
+-	printk(KERN_INFO "Device Type: %x - %s\n", gcw.device_type, buffer);
+-	printk(KERN_INFO "Removable: %s\n",gcw.removable ? "Yes":"No");	
+-	switch (gcw.drq_type) {
+-		case 0: sprintf(buffer, "Microprocessor DRQ");break;
+-		case 1: sprintf(buffer, "Interrupt DRQ");break;
+-		case 2: sprintf(buffer, "Accelerated DRQ");break;
+-		case 3: sprintf(buffer, "Reserved");break;
+-	}
+-	printk(KERN_INFO "Command Packet DRQ Type: %s\n", buffer);
+-	switch (gcw.packet_size) {
+-		case 0: sprintf(buffer, "12 bytes");break;
+-		case 1: sprintf(buffer, "16 bytes");break;
+-		default: sprintf(buffer, "Reserved");break;
+-	}
+-	printk(KERN_INFO "Command Packet Size: %s\n", buffer);
 -	printk(KERN_INFO "Model: %.40s\n",id->model);
 -	printk(KERN_INFO "Firmware Revision: %.8s\n",id->fw_rev);
 -	printk(KERN_INFO "Serial Number: %.20s\n",id->serial_no);
@@ -403249,11 +405628,443 @@
 -		printk(KERN_INFO "Minimum PIO cycle with IORDY: %s\n", buffer);
 -	} else
 -		printk(KERN_INFO "According to the device, fields 64-70 are not valid.\n");
- #endif /* IDEFLOPPY_DEBUG_INFO */
- 
+-#endif /* IDEFLOPPY_DEBUG_INFO */
+-
  	if (gcw.protocol != 2)
+-		printk(KERN_ERR "ide-floppy: Protocol is not ATAPI\n");
++		printk(KERN_ERR "ide-floppy: Protocol (0x%02x) is not ATAPI\n",
++				gcw.protocol);
+ 	else if (gcw.device_type != 0)
+-		printk(KERN_ERR "ide-floppy: Device type is not set to floppy\n");
++		printk(KERN_ERR "ide-floppy: Device type (0x%02x) is not set "
++				"to floppy\n", gcw.device_type);
+ 	else if (!gcw.removable)
+ 		printk(KERN_ERR "ide-floppy: The removable flag is not set\n");
+ 	else if (gcw.drq_type == 3) {
+-		printk(KERN_ERR "ide-floppy: Sorry, DRQ type %d not supported\n", gcw.drq_type);
++		printk(KERN_ERR "ide-floppy: Sorry, DRQ type (0x%02x) not "
++				"supported\n", gcw.drq_type);
+ 	} else if (gcw.packet_size != 0) {
+-		printk(KERN_ERR "ide-floppy: Packet size is not 12 bytes long\n");
++		printk(KERN_ERR "ide-floppy: Packet size (0x%02x) is not 12 "
++				"bytes long\n", gcw.packet_size);
+ 	} else
+ 		return 1;
+ 	return 0;
+@@ -1817,59 +1307,53 @@ static void idefloppy_add_settings(ide_drive_t *drive)
+ {
+ 	idefloppy_floppy_t *floppy = drive->driver_data;
+ 
+-/*
+- *			drive	setting name	read/write	data type	min	max	mul_factor	div_factor	data pointer		set function
+- */
+-	ide_add_setting(drive,	"bios_cyl",	SETTING_RW,	TYPE_INT,	0,	1023,		1,		1,	&drive->bios_cyl,	NULL);
+-	ide_add_setting(drive,	"bios_head",	SETTING_RW,	TYPE_BYTE,	0,	255,		1,		1,	&drive->bios_head,	NULL);
+-	ide_add_setting(drive,	"bios_sect",	SETTING_RW,	TYPE_BYTE,	0,	63,		1,		1,	&drive->bios_sect,	NULL);
+-	ide_add_setting(drive,	"ticks",	SETTING_RW,	TYPE_BYTE,	0,	255,		1,		1,	&floppy->ticks,		NULL);
++	ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 1023, 1, 1,
++			&drive->bios_cyl, NULL);
++	ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1,
++			&drive->bios_head, NULL);
++	ide_add_setting(drive, "bios_sect", SETTING_RW,	TYPE_BYTE, 0,  63, 1, 1,
++			&drive->bios_sect, NULL);
++	ide_add_setting(drive, "ticks",	   SETTING_RW, TYPE_BYTE, 0, 255, 1, 1,
++			&floppy->ticks,	 NULL);
+ }
+ #else
+ static inline void idefloppy_add_settings(ide_drive_t *drive) { ; }
+ #endif
+ 
+-/*
+- *	Driver initialization.
+- */
+-static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
++static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
+ {
+ 	struct idefloppy_id_gcw gcw;
+ 
+ 	*((u16 *) &gcw) = drive->id->config;
+ 	floppy->pc = floppy->pc_stack;
+ 	if (gcw.drq_type == 1)
+-		set_bit(IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags);
++		floppy->flags |= IDEFLOPPY_FLAG_DRQ_INTERRUPT;
+ 	/*
+-	 *	We used to check revisions here. At this point however
+-	 *	I'm giving up. Just assume they are all broken, its easier.
++	 * We used to check revisions here. At this point however I'm giving up.
++	 * Just assume they are all broken, its easier.
+ 	 *
+-	 *	The actual reason for the workarounds was likely
+-	 *	a driver bug after all rather than a firmware bug,
+-	 *	and the workaround below used to hide it. It should
+-	 *	be fixed as of version 1.9, but to be on the safe side
+-	 *	we'll leave the limitation below for the 2.2.x tree.
++	 * The actual reason for the workarounds was likely a driver bug after
++	 * all rather than a firmware bug, and the workaround below used to hide
++	 * it. It should be fixed as of version 1.9, but to be on the safe side
++	 * we'll leave the limitation below for the 2.2.x tree.
+ 	 */
+-
+ 	if (!strncmp(drive->id->model, "IOMEGA ZIP 100 ATAPI", 20)) {
+-		set_bit(IDEFLOPPY_ZIP_DRIVE, &floppy->flags);
++		floppy->flags |= IDEFLOPPY_FLAG_ZIP_DRIVE;
+ 		/* This value will be visible in the /proc/ide/hdx/settings */
+ 		floppy->ticks = IDEFLOPPY_TICKS_DELAY;
+ 		blk_queue_max_sectors(drive->queue, 64);
+ 	}
+ 
+ 	/*
+-	*      Guess what?  The IOMEGA Clik! drive also needs the
+-	*      above fix.  It makes nasty clicking noises without
+-	*      it, so please don't remove this.
+-	*/
++	 * Guess what? The IOMEGA Clik! drive also needs the above fix. It makes
++	 * nasty clicking noises without it, so please don't remove this.
++	 */
+ 	if (strncmp(drive->id->model, "IOMEGA Clik!", 11) == 0) {
+ 		blk_queue_max_sectors(drive->queue, 64);
+-		set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags);
++		floppy->flags |= IDEFLOPPY_FLAG_CLIK_DRIVE;
+ 	}
+ 
+-
+-	(void) idefloppy_get_capacity(drive);
++	(void) ide_floppy_get_capacity(drive);
+ 	idefloppy_add_settings(drive);
+ }
+ 
+@@ -1885,7 +1369,7 @@ static void ide_floppy_remove(ide_drive_t *drive)
+ 	ide_floppy_put(floppy);
+ }
+ 
+-static void ide_floppy_release(struct kref *kref)
++static void idefloppy_cleanup_obj(struct kref *kref)
+ {
+ 	struct ide_floppy_obj *floppy = to_ide_floppy(kref);
+ 	ide_drive_t *drive = floppy->drive;
+@@ -1898,19 +1382,19 @@ static void ide_floppy_release(struct kref *kref)
+ }
+ 
+ #ifdef CONFIG_IDE_PROC_FS
+-static int proc_idefloppy_read_capacity
+-	(char *page, char **start, off_t off, int count, int *eof, void *data)
++static int proc_idefloppy_read_capacity(char *page, char **start, off_t off,
++		int count, int *eof, void *data)
+ {
+ 	ide_drive_t*drive = (ide_drive_t *)data;
+ 	int len;
+ 
+-	len = sprintf(page,"%llu\n", (long long)idefloppy_capacity(drive));
+-	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
++	len = sprintf(page, "%llu\n", (long long)idefloppy_capacity(drive));
++	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ }
+ 
+ static ide_proc_entry_t idefloppy_proc[] = {
+-	{ "capacity",	S_IFREG|S_IRUGO,	proc_idefloppy_read_capacity, NULL },
+-	{ "geometry",	S_IFREG|S_IRUGO,	proc_ide_read_geometry,	NULL },
++	{ "capacity",	S_IFREG|S_IRUGO, proc_idefloppy_read_capacity,	NULL },
++	{ "geometry",	S_IFREG|S_IRUGO, proc_ide_read_geometry,	NULL },
+ 	{ NULL, 0, NULL, NULL }
+ };
+ #endif	/* CONFIG_IDE_PROC_FS */
+@@ -1945,9 +1429,10 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
+ 	idefloppy_pc_t pc;
+ 	int ret = 0;
+ 
+-	debug_log(KERN_INFO "Reached idefloppy_open\n");
++	debug_log("Reached %s\n", __func__);
+ 
+-	if (!(floppy = ide_floppy_get(disk)))
++	floppy = ide_floppy_get(disk);
++	if (!floppy)
+ 		return -ENXIO;
+ 
+ 	drive = floppy->drive;
+@@ -1955,7 +1440,7 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
+ 	floppy->openers++;
+ 
+ 	if (floppy->openers == 1) {
+-		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
++		floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
+ 		/* Just in case */
+ 
+ 		idefloppy_create_test_unit_ready_cmd(&pc);
+@@ -1964,13 +1449,13 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
+ 			(void) idefloppy_queue_pc_tail(drive, &pc);
+ 		}
+ 
+-		if (idefloppy_get_capacity (drive)
++		if (ide_floppy_get_capacity(drive)
+ 		   && (filp->f_flags & O_NDELAY) == 0
+ 		    /*
+-		    ** Allow O_NDELAY to open a drive without a disk, or with
+-		    ** an unreadable disk, so that we can get the format
+-		    ** capacity of the drive or begin the format - Sam
+-		    */
++		     * Allow O_NDELAY to open a drive without a disk, or with an
++		     * unreadable disk, so that we can get the format capacity
++		     * of the drive or begin the format - Sam
++		     */
+ 		    ) {
+ 			ret = -EIO;
+ 			goto out_put_floppy;
+@@ -1980,14 +1465,14 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
+ 			ret = -EROFS;
+ 			goto out_put_floppy;
+ 		}
+-		set_bit(IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
++		floppy->flags |= IDEFLOPPY_FLAG_MEDIA_CHANGED;
+ 		/* IOMEGA Clik! drives do not support lock/unlock commands */
+-                if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
++		if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) {
+ 			idefloppy_create_prevent_cmd(&pc, 1);
+ 			(void) idefloppy_queue_pc_tail(drive, &pc);
+ 		}
+ 		check_disk_change(inode->i_bdev);
+-	} else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) {
++	} else if (floppy->flags & IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS) {
+ 		ret = -EBUSY;
+ 		goto out_put_floppy;
+ 	}
+@@ -2005,17 +1490,17 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
+ 	struct ide_floppy_obj *floppy = ide_floppy_g(disk);
+ 	ide_drive_t *drive = floppy->drive;
+ 	idefloppy_pc_t pc;
+-	
+-	debug_log(KERN_INFO "Reached idefloppy_release\n");
++
++	debug_log("Reached %s\n", __func__);
+ 
+ 	if (floppy->openers == 1) {
+ 		/* IOMEGA Clik! drives do not support lock/unlock commands */
+-                if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
++		if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) {
+ 			idefloppy_create_prevent_cmd(&pc, 0);
+ 			(void) idefloppy_queue_pc_tail(drive, &pc);
+ 		}
+ 
+-		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
++		floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
+ 	}
+ 
+ 	floppy->openers--;
+@@ -2036,64 +1521,105 @@ static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+ 	return 0;
+ }
+ 
++static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc,
++			       unsigned long arg, unsigned int cmd)
++{
++	if (floppy->openers > 1)
++		return -EBUSY;
++
++	/* The IOMEGA Clik! Drive doesn't support this command -
++	 * no room for an eject mechanism */
++	if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) {
++		int prevent = arg ? 1 : 0;
++
++		if (cmd == CDROMEJECT)
++			prevent = 0;
++
++		idefloppy_create_prevent_cmd(pc, prevent);
++		(void) idefloppy_queue_pc_tail(floppy->drive, pc);
++	}
++
++	if (cmd == CDROMEJECT) {
++		idefloppy_create_start_stop_cmd(pc, 2);
++		(void) idefloppy_queue_pc_tail(floppy->drive, pc);
++	}
++
++	return 0;
++}
++
++static int ide_floppy_format_unit(idefloppy_floppy_t *floppy,
++				  int __user *arg)
++{
++	int blocks, length, flags, err = 0;
++	idefloppy_pc_t pc;
++
++	if (floppy->openers > 1) {
++		/* Don't format if someone is using the disk */
++		floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
++		return -EBUSY;
++	}
++
++	floppy->flags |= IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
++
++	/*
++	 * Send ATAPI_FORMAT_UNIT to the drive.
++	 *
++	 * Userland gives us the following structure:
++	 *
++	 * struct idefloppy_format_command {
++	 *        int nblocks;
++	 *        int blocksize;
++	 *        int flags;
++	 *        } ;
++	 *
++	 * flags is a bitmask, currently, the only defined flag is:
++	 *
++	 *        0x01 - verify media after format.
++	 */
++	if (get_user(blocks, arg) ||
++			get_user(length, arg+1) ||
++			get_user(flags, arg+2)) {
++		err = -EFAULT;
++		goto out;
++	}
++
++	(void) idefloppy_get_sfrp_bit(floppy->drive);
++	idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);
++
++	if (idefloppy_queue_pc_tail(floppy->drive, &pc))
++		err = -EIO;
++
++out:
++	if (err)
++		floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
++	return err;
++}
++
++
+ static int idefloppy_ioctl(struct inode *inode, struct file *file,
+ 			unsigned int cmd, unsigned long arg)
+ {
+ 	struct block_device *bdev = inode->i_bdev;
+ 	struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
+ 	ide_drive_t *drive = floppy->drive;
++	idefloppy_pc_t pc;
+ 	void __user *argp = (void __user *)arg;
+ 	int err;
+-	int prevent = (arg) ? 1 : 0;
+-	idefloppy_pc_t pc;
+ 
+ 	switch (cmd) {
+ 	case CDROMEJECT:
+-		prevent = 0;
+ 		/* fall through */
+ 	case CDROM_LOCKDOOR:
+-		if (floppy->openers > 1)
+-			return -EBUSY;
+-
+-		/* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
+-                if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
+-			idefloppy_create_prevent_cmd(&pc, prevent);
+-			(void) idefloppy_queue_pc_tail(drive, &pc);
+-		}
+-		if (cmd == CDROMEJECT) {
+-			idefloppy_create_start_stop_cmd(&pc, 2);
+-			(void) idefloppy_queue_pc_tail(drive, &pc);
+-		}
+-		return 0;
++		return ide_floppy_lockdoor(floppy, &pc, arg, cmd);
+ 	case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:
+ 		return 0;
+ 	case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
+-		return idefloppy_get_format_capacities(drive, argp);
++		return ide_floppy_get_format_capacities(drive, argp);
+ 	case IDEFLOPPY_IOCTL_FORMAT_START:
+-
+ 		if (!(file->f_mode & 2))
+ 			return -EPERM;
+ 
+-		if (floppy->openers > 1) {
+-			/* Don't format if someone is using the disk */
+-
+-			clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,
+-				  &floppy->flags);
+-			return -EBUSY;
+-		}
+-
+-		set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
+-
+-		err = idefloppy_begin_format(drive, argp);
+-		if (err)
+-			clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
+-		return err;
+-		/*
+-		** Note, the bit will be cleared when the device is
+-		** closed.  This is the cleanest way to handle the
+-		** situation where the drive does not support
+-		** format progress reporting.
+-		*/
++		return ide_floppy_format_unit(floppy, (int __user *)arg);
+ 	case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
+ 		return idefloppy_get_format_progress(drive, argp);
+ 	}
+@@ -2118,13 +1644,16 @@ static int idefloppy_media_changed(struct gendisk *disk)
+ {
+ 	struct ide_floppy_obj *floppy = ide_floppy_g(disk);
+ 	ide_drive_t *drive = floppy->drive;
++	int ret;
+ 
+ 	/* do not scan partitions twice if this is a removable device */
+ 	if (drive->attach) {
+ 		drive->attach = 0;
+ 		return 0;
+ 	}
+-	return test_and_clear_bit(IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
++	ret = !!(floppy->flags & IDEFLOPPY_FLAG_MEDIA_CHANGED);
++	floppy->flags &= ~IDEFLOPPY_FLAG_MEDIA_CHANGED;
++	return ret;
+ }
+ 
+ static int idefloppy_revalidate_disk(struct gendisk *disk)
+@@ -2155,16 +1684,20 @@ static int ide_floppy_probe(ide_drive_t *drive)
+ 		goto failed;
+ 	if (drive->media != ide_floppy)
+ 		goto failed;
+-	if (!idefloppy_identify_device (drive, drive->id)) {
+-		printk (KERN_ERR "ide-floppy: %s: not supported by this version of ide-floppy\n", drive->name);
++	if (!idefloppy_identify_device(drive, drive->id)) {
++		printk(KERN_ERR "ide-floppy: %s: not supported by this version"
++				" of ide-floppy\n", drive->name);
+ 		goto failed;
+ 	}
+ 	if (drive->scsi) {
+-		printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);
++		printk(KERN_INFO "ide-floppy: passing drive %s to ide-scsi"
++				" emulation.\n", drive->name);
+ 		goto failed;
+ 	}
+-	if ((floppy = kzalloc(sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
+-		printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
++	floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL);
++	if (!floppy) {
++		printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy"
++				" structure\n", drive->name);
+ 		goto failed;
+ 	}
+ 
+@@ -2186,7 +1719,7 @@ static int ide_floppy_probe(ide_drive_t *drive)
+ 
+ 	drive->driver_data = floppy;
+ 
+-	idefloppy_setup (drive, floppy);
++	idefloppy_setup(drive, floppy);
+ 
+ 	g->minors = 1 << PARTN_BITS;
+ 	g->driverfs_dev = &drive->gendev;
+@@ -2202,9 +1735,7 @@ failed:
+ 	return -ENODEV;
+ }
+ 
+-MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
+-
+-static void __exit idefloppy_exit (void)
++static void __exit idefloppy_exit(void)
+ {
+ 	driver_unregister(&idefloppy_driver.gen_driver);
+ }
+@@ -2219,3 +1750,5 @@ MODULE_ALIAS("ide:*m-floppy*");
+ module_init(idefloppy_init);
+ module_exit(idefloppy_exit);
+ MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
++
 diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
-index 0f72b98..bb30c29 100644
+index 0f72b98..be469db 100644
 --- a/drivers/ide/ide-generic.c
 +++ b/drivers/ide/ide-generic.c
 @@ -14,10 +14,16 @@
@@ -403270,7 +406081,7 @@
 +	for (i = 0; i < MAX_HWIFS; i++)
 +		idx[i] = ide_hwifs[i].present ? 0xff : i;
 +
-+	ide_device_add_all(idx);
++	ide_device_add_all(idx, NULL);
  
  	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET])
  		ide_release_lock();	/* for atari only */
@@ -403861,7 +406672,7 @@
 +
 +EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);
 diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
-index bb9693d..16b1f6e 100644
+index bb9693d..a95178f 100644
 --- a/drivers/ide/ide-iops.c
 +++ b/drivers/ide/ide-iops.c
 @@ -1,6 +1,4 @@
@@ -403886,10 +406697,12 @@
  void SELECT_DRIVE (ide_drive_t *drive)
  {
  	if (HWIF(drive)->selectproc)
-@@ -175,26 +165,12 @@ void SELECT_DRIVE (ide_drive_t *drive)
- 
- EXPORT_SYMBOL(SELECT_DRIVE);
+@@ -173,28 +163,12 @@ void SELECT_DRIVE (ide_drive_t *drive)
+ 	HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG);
+ }
  
+-EXPORT_SYMBOL(SELECT_DRIVE);
+-
 -void SELECT_INTERRUPT (ide_drive_t *drive)
 -{
 -	if (HWIF(drive)->intrproc)
@@ -403913,7 +406726,7 @@
  /*
   * Some localbus EIDE interfaces require a special access sequence
   * when using 32-bit I/O instructions to transfer data.  We call this
-@@ -449,7 +425,6 @@ int drive_is_ready (ide_drive_t *drive)
+@@ -449,7 +423,6 @@ int drive_is_ready (ide_drive_t *drive)
  	udelay(1);
  #endif
  
@@ -403921,7 +406734,7 @@
  	/*
  	 * We do a passive status test under shared PCI interrupts on
  	 * cards that truly share the ATA side interrupt, but may also share
-@@ -459,7 +434,6 @@ int drive_is_ready (ide_drive_t *drive)
+@@ -459,7 +432,6 @@ int drive_is_ready (ide_drive_t *drive)
  	if (IDE_CONTROL_REG)
  		stat = hwif->INB(IDE_ALTSTATUS_REG);
  	else
@@ -403929,33 +406742,74 @@
  		/* Note: this may clear a pending IRQ!! */
  		stat = hwif->INB(IDE_STATUS_REG);
  
-@@ -642,9 +616,9 @@ no_80w:
+@@ -640,66 +612,6 @@ no_80w:
+ 	return 0;
+ }
  
- int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
- {
+-int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
+-{
 -	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
 -	    (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
 -	    (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
-+	if (args->tf.command == WIN_SETFEATURES &&
-+	    args->tf.nsect > XFER_UDMA_2 &&
-+	    args->tf.feature == SETFEATURES_XFER) {
- 		if (eighty_ninty_three(drive) == 0) {
- 			printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
- 					    "be set\n", drive->name);
-@@ -662,9 +636,9 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
-  */
- int set_transfer (ide_drive_t *drive, ide_task_t *args)
- {
+-		if (eighty_ninty_three(drive) == 0) {
+-			printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
+-					    "be set\n", drive->name);
+-			return 1;
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-/*
+- * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER.
+- * 1 : Safe to update drive->id DMA registers.
+- * 0 : OOPs not allowed.
+- */
+-int set_transfer (ide_drive_t *drive, ide_task_t *args)
+-{
 -	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
 -	    (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
 -	    (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
-+	if (args->tf.command == WIN_SETFEATURES &&
-+	    args->tf.nsect >= XFER_SW_DMA_0 &&
-+	    args->tf.feature == SETFEATURES_XFER &&
- 	    (drive->id->dma_ultra ||
- 	     drive->id->dma_mword ||
- 	     drive->id->dma_1word))
-@@ -712,8 +686,7 @@ int ide_driveid_update(ide_drive_t *drive)
+-	    (drive->id->dma_ultra ||
+-	     drive->id->dma_mword ||
+-	     drive->id->dma_1word))
+-		return 1;
+-
+-	return 0;
+-}
+-
+-#ifdef CONFIG_BLK_DEV_IDEDMA
+-static u8 ide_auto_reduce_xfer (ide_drive_t *drive)
+-{
+-	if (!drive->crc_count)
+-		return drive->current_speed;
+-	drive->crc_count = 0;
+-
+-	switch(drive->current_speed) {
+-		case XFER_UDMA_7:	return XFER_UDMA_6;
+-		case XFER_UDMA_6:	return XFER_UDMA_5;
+-		case XFER_UDMA_5:	return XFER_UDMA_4;
+-		case XFER_UDMA_4:	return XFER_UDMA_3;
+-		case XFER_UDMA_3:	return XFER_UDMA_2;
+-		case XFER_UDMA_2:	return XFER_UDMA_1;
+-		case XFER_UDMA_1:	return XFER_UDMA_0;
+-			/*
+-			 * OOPS we do not goto non Ultra DMA modes
+-			 * without iCRC's available we force
+-			 * the system to PIO and make the user
+-			 * invoke the ATA-1 ATA-2 DMA modes.
+-			 */
+-		case XFER_UDMA_0:
+-		default:		return XFER_PIO_4;
+-	}
+-}
+-#endif /* CONFIG_BLK_DEV_IDEDMA */
+-
+ int ide_driveid_update(ide_drive_t *drive)
+ {
+ 	ide_hwif_t *hwif = drive->hwif;
+@@ -712,8 +624,7 @@ int ide_driveid_update(ide_drive_t *drive)
  	 */
  
  	SELECT_MASK(drive, 1);
@@ -403965,7 +406819,7 @@
  	msleep(50);
  	hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG);
  	timeout = jiffies + WAIT_WORSTCASE;
-@@ -766,8 +739,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
+@@ -766,8 +677,8 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
  //		msleep(50);
  
  #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -403976,7 +406830,7 @@
  #endif
  
  	/* Skip setting PIO flow-control modes on pre-EIDE drives */
-@@ -796,13 +769,12 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
+@@ -796,13 +707,12 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
  	SELECT_DRIVE(drive);
  	SELECT_MASK(drive, 0);
  	udelay(1);
@@ -403993,7 +406847,7 @@
  
  	error = __ide_wait_stat(drive, drive->ready_stat,
  				BUSY_STAT|DRQ_STAT|ERR_STAT,
-@@ -823,10 +795,11 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
+@@ -823,10 +733,11 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
  
   skip:
  #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -404009,7 +406863,7 @@
  #endif
  
  	switch(speed) {
-@@ -902,8 +875,9 @@ EXPORT_SYMBOL(ide_set_handler);
+@@ -902,28 +813,24 @@ EXPORT_SYMBOL(ide_set_handler);
   *	handler and IRQ setup do not race. All IDE command kick off
   *	should go via this function or do equivalent locking.
   */
@@ -404021,20 +406875,55 @@
  {
  	unsigned long flags;
  	ide_hwgroup_t *hwgroup = HWGROUP(drive);
-@@ -1035,10 +1009,10 @@ static void check_dma_crc(ide_drive_t *drive)
- {
- #ifdef CONFIG_BLK_DEV_IDEDMA
- 	if (drive->crc_count) {
+ 	ide_hwif_t *hwif = HWIF(drive);
+-	
++
+ 	spin_lock_irqsave(&ide_lock, flags);
+-	
+ 	BUG_ON(hwgroup->handler);
+-	hwgroup->handler	= handler;
+-	hwgroup->expiry		= expiry;
+-	hwgroup->timer.expires	= jiffies + timeout;
+-	hwgroup->req_gen_timer = hwgroup->req_gen;
+-	add_timer(&hwgroup->timer);
++	__ide_set_handler(drive, handler, timeout, expiry);
+ 	hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG);
+-	/* Drive takes 400nS to respond, we must avoid the IRQ being
+-	   serviced before that. 
+-	   
+-	   FIXME: we could skip this delay with care on non shared
+-	   devices 
+-	*/
++	/*
++	 * Drive takes 400nS to respond, we must avoid the IRQ being
++	 * serviced before that.
++	 *
++	 * FIXME: we could skip this delay with care on non shared devices
++	 */
+ 	ndelay(400);
+ 	spin_unlock_irqrestore(&ide_lock, flags);
+ }
+@@ -1031,19 +938,6 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
+ 	return ide_stopped;
+ }
+ 
+-static void check_dma_crc(ide_drive_t *drive)
+-{
+-#ifdef CONFIG_BLK_DEV_IDEDMA
+-	if (drive->crc_count) {
 -		drive->hwif->dma_off_quietly(drive);
-+		ide_dma_off_quietly(drive);
- 		ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
- 		if (drive->current_speed >= XFER_SW_DMA_0)
+-		ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
+-		if (drive->current_speed >= XFER_SW_DMA_0)
 -			(void) HWIF(drive)->ide_dma_on(drive);
-+			ide_dma_on(drive);
- 	} else
- 		ide_dma_off(drive);
- #endif
-@@ -1051,8 +1025,7 @@ static void ide_disk_pre_reset(ide_drive_t *drive)
+-	} else
+-		ide_dma_off(drive);
+-#endif
+-}
+-
+ static void ide_disk_pre_reset(ide_drive_t *drive)
+ {
+ 	int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1;
+@@ -1051,8 +945,7 @@ static void ide_disk_pre_reset(ide_drive_t *drive)
  	drive->special.all = 0;
  	drive->special.b.set_geometry = legacy;
  	drive->special.b.recalibrate  = legacy;
@@ -404044,7 +406933,33 @@
  	if (!drive->keep_settings && !drive->using_dma)
  		drive->mult_req = 0;
  	if (drive->mult_req != drive->mult_count)
-@@ -1137,7 +1110,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
+@@ -1066,17 +959,20 @@ static void pre_reset(ide_drive_t *drive)
+ 	else
+ 		drive->post_reset = 1;
+ 
++	if (drive->using_dma) {
++		if (drive->crc_count)
++			ide_check_dma_crc(drive);
++		else
++			ide_dma_off(drive);
++	}
++
+ 	if (!drive->keep_settings) {
+-		if (drive->using_dma) {
+-			check_dma_crc(drive);
+-		} else {
++		if (!drive->using_dma) {
+ 			drive->unmask = 0;
+ 			drive->io_32bit = 0;
+ 		}
+ 		return;
+ 	}
+-	if (drive->using_dma)
+-		check_dma_crc(drive);
+ 
+ 	if (HWIF(drive)->pre_reset != NULL)
+ 		HWIF(drive)->pre_reset(drive);
+@@ -1137,7 +1033,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
  	for (unit = 0; unit < MAX_DRIVES; ++unit)
  		pre_reset(&hwif->drives[unit]);
  
@@ -404052,7 +406967,7 @@
  	if (!IDE_CONTROL_REG) {
  		spin_unlock_irqrestore(&ide_lock, flags);
  		return ide_stopped;
-@@ -1174,11 +1146,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
+@@ -1174,11 +1069,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
  	 * state when the disks are reset this way. At least, the Winbond
  	 * 553 documentation says that
  	 */
@@ -404065,7 +406980,7 @@
  
  	spin_unlock_irqrestore(&ide_lock, flags);
  	return ide_started;
-@@ -1197,7 +1166,7 @@ EXPORT_SYMBOL(ide_do_reset);
+@@ -1197,7 +1089,7 @@ EXPORT_SYMBOL(ide_do_reset);
  
  /*
   * ide_wait_not_busy() waits for the currently selected device on the hwif
@@ -404372,7 +407287,7 @@
  
  EXPORT_SYMBOL(ide_dump_status);
 diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
-index e245521..4bda5cf 100644
+index e245521..b163b2e 100644
 --- a/drivers/ide/ide-pnp.c
 +++ b/drivers/ide/ide-pnp.c
 @@ -1,6 +1,4 @@
@@ -404408,12 +407323,26 @@
 +		printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
  		pnp_set_drvdata(dev,hwif);
 +
-+		ide_device_add(idx);
++		ide_device_add(idx, NULL);
 +
  		return 0;
  	}
  
-@@ -68,12 +73,15 @@ static struct pnp_driver idepnp_driver = {
+@@ -55,9 +60,10 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
+ static void idepnp_remove(struct pnp_dev * dev)
+ {
+ 	ide_hwif_t *hwif = pnp_get_drvdata(dev);
+-	if (hwif) {
+-		ide_unregister(hwif->index);
+-	} else
++
++	if (hwif)
++		ide_unregister(hwif->index, 0, 0);
++	else
+ 		printk(KERN_ERR "idepnp: Unable to remove device, please report.\n");
+ }
+ 
+@@ -68,12 +74,15 @@ static struct pnp_driver idepnp_driver = {
  	.remove		= idepnp_remove,
  };
  
@@ -404433,7 +407362,7 @@
 +module_init(pnpide_init);
 +module_exit(pnpide_exit);
 diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
-index 2994523..98a8af4 100644
+index 2994523..9c07bdb 100644
 --- a/drivers/ide/ide-probe.c
 +++ b/drivers/ide/ide-probe.c
 @@ -1,7 +1,6 @@
@@ -404526,15 +407455,38 @@
  
  /**
   *	do_probe		-	probe an IDE device
-@@ -453,7 +467,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
+@@ -409,8 +423,9 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
+ 
+ static int do_probe (ide_drive_t *drive, u8 cmd)
+ {
+-	int rc;
+ 	ide_hwif_t *hwif = HWIF(drive);
++	int rc;
++	u8 stat;
+ 
+ 	if (drive->present) {
+ 		/* avoid waiting for inappropriate probes */
+@@ -447,31 +462,31 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
+ 			/* failed: try again */
+ 			rc = try_to_identify(drive,cmd);
+ 		}
+-		if (hwif->INB(IDE_STATUS_REG) == (BUSY_STAT|READY_STAT))
++
++		stat = hwif->INB(IDE_STATUS_REG);
++
++		if (stat == (BUSY_STAT | READY_STAT))
+ 			return 4;
+ 
  		if ((rc == 1 && cmd == WIN_PIDENTIFY) &&
  			((drive->autotune == IDE_TUNE_DEFAULT) ||
  			(drive->autotune == IDE_TUNE_AUTO))) {
 -			unsigned long timeout;
- 			printk("%s: no response (status = 0x%02x), "
- 				"resetting drive\n", drive->name,
- 				hwif->INB(IDE_STATUS_REG));
-@@ -461,10 +474,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
+-			printk("%s: no response (status = 0x%02x), "
+-				"resetting drive\n", drive->name,
+-				hwif->INB(IDE_STATUS_REG));
++			printk(KERN_ERR "%s: no response (status = 0x%02x), "
++					"resetting drive\n", drive->name, stat);
+ 			msleep(50);
  			hwif->OUTB(drive->select.all, IDE_SELECT_REG);
  			msleep(50);
  			hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
@@ -404545,12 +407497,26 @@
 +			(void)ide_busy_sleep(hwif);
  			rc = try_to_identify(drive, cmd);
  		}
++
++		/* ensure drive IRQ is clear */
++		stat = hwif->INB(IDE_STATUS_REG);
++
  		if (rc == 1)
-@@ -492,20 +502,16 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
+-			printk("%s: no response (status = 0x%02x)\n",
+-				drive->name, hwif->INB(IDE_STATUS_REG));
+-		/* ensure drive irq is clear */
+-		(void) hwif->INB(IDE_STATUS_REG);
++			printk(KERN_ERR "%s: no response (status = 0x%02x)\n",
++					drive->name, stat);
+ 	} else {
+ 		/* not present or maybe ATAPI */
+ 		rc = 3;
+@@ -492,28 +507,26 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
  static void enable_nest (ide_drive_t *drive)
  {
  	ide_hwif_t *hwif = HWIF(drive);
 -	unsigned long timeout;
++	u8 stat;
  
  	printk("%s: enabling %s -- ", hwif->name, drive->id->model);
  	SELECT_DRIVE(drive);
@@ -404572,7 +407538,21 @@
  
  	msleep(50);
  
-@@ -607,7 +613,7 @@ static void hwif_release_dev (struct device *dev)
+-	if (!OK_STAT((hwif->INB(IDE_STATUS_REG)), 0, BAD_STAT)) {
+-		printk("failed (status = 0x%02x)\n", hwif->INB(IDE_STATUS_REG));
+-	} else {
+-		printk("success\n");
+-	}
++	stat = hwif->INB(IDE_STATUS_REG);
++
++	if (!OK_STAT(stat, 0, BAD_STAT))
++		printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
++	else
++		printk(KERN_CONT "success\n");
+ 
+ 	/* if !(success||timed-out) */
+ 	if (do_probe(drive, WIN_IDENTIFY) >= 2) {
+@@ -607,7 +620,7 @@ static void hwif_release_dev (struct device *dev)
  	complete(&hwif->gendev_rel_comp);
  }
  
@@ -404581,7 +407561,7 @@
  {
  	int ret;
  
-@@ -615,8 +621,8 @@ static void hwif_register (ide_hwif_t *hwif)
+@@ -615,8 +628,8 @@ static void hwif_register (ide_hwif_t *hwif)
  	strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE);
  	hwif->gendev.driver_data = hwif;
  	if (hwif->gendev.parent == NULL) {
@@ -404592,7 +407572,7 @@
  		else
  			/* Would like to do = &device_legacy */
  			hwif->gendev.parent = NULL;
-@@ -628,7 +634,33 @@ static void hwif_register (ide_hwif_t *hwif)
+@@ -628,7 +641,33 @@ static void hwif_register (ide_hwif_t *hwif)
  			__FUNCTION__, ret);
  }
  
@@ -404627,7 +407607,7 @@
  {
  	int unit, rc;
  
-@@ -653,8 +685,7 @@ static int wait_hwif_ready(ide_hwif_t *hwif)
+@@ -653,8 +692,7 @@ static int wait_hwif_ready(ide_hwif_t *hwif)
  		/* Ignore disks that we will not probe for later. */
  		if (!drive->noprobe || drive->present) {
  			SELECT_DRIVE(drive);
@@ -404637,7 +407617,7 @@
  			mdelay(2);
  			rc = ide_wait_not_busy(hwif, 35000);
  			if (rc)
-@@ -673,19 +704,18 @@ out:
+@@ -673,19 +711,18 @@ out:
  
  /**
   *	ide_undecoded_slave	-	look for bad CF adapters
@@ -404661,7 +407641,7 @@
  		return;
  
  	/* If the models don't match they are not the same product */
-@@ -708,36 +738,16 @@ void ide_undecoded_slave(ide_hwif_t *hwif)
+@@ -708,36 +745,16 @@ void ide_undecoded_slave(ide_hwif_t *hwif)
  
  EXPORT_SYMBOL_GPL(ide_undecoded_slave);
  
@@ -404703,7 +407683,7 @@
  
  	/*
  	 * We must always disable IRQ, as probe_for_drive will assert IRQ, but
-@@ -749,26 +759,7 @@ static void probe_hwif(ide_hwif_t *hwif)
+@@ -749,26 +766,7 @@ static void probe_hwif(ide_hwif_t *hwif)
  
  	local_irq_set(flags);
  
@@ -404731,7 +407711,7 @@
  		printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
  
  	/*
-@@ -778,28 +769,15 @@ static void probe_hwif(ide_hwif_t *hwif)
+@@ -778,28 +776,15 @@ static void probe_hwif(ide_hwif_t *hwif)
  		ide_drive_t *drive = &hwif->drives[unit];
  		drive->dn = (hwif->channel ? 2 : 0) + unit;
  		(void) probe_for_drive(drive);
@@ -404763,7 +407743,7 @@
  	}
  	local_irq_restore(flags);
  	/*
-@@ -809,13 +787,19 @@ static void probe_hwif(ide_hwif_t *hwif)
+@@ -809,13 +794,19 @@ static void probe_hwif(ide_hwif_t *hwif)
  	if (irqd)
  		enable_irq(irqd);
  
@@ -404789,7 +407769,7 @@
  
  	for (unit = 0; unit < MAX_DRIVES; ++unit) {
  		ide_drive_t *drive = &hwif->drives[unit];
-@@ -830,16 +814,8 @@ static void probe_hwif(ide_hwif_t *hwif)
+@@ -830,48 +821,21 @@ static void probe_hwif(ide_hwif_t *hwif)
  
  			drive->nice1 = 1;
  
@@ -404807,7 +407787,14 @@
  		}
  	}
  
-@@ -853,25 +829,6 @@ static void probe_hwif(ide_hwif_t *hwif)
+ 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
+ 		ide_drive_t *drive = &hwif->drives[unit];
+ 
+-		if (hwif->no_io_32bit)
++		if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
+ 			drive->no_io_32bit = 1;
+ 		else
+ 			drive->no_io_32bit = drive->id->dword_io ? 1 : 0;
  	}
  }
  
@@ -404833,7 +407820,70 @@
  #if MAX_HWIFS > 1
  /*
   * save_match() is used to simplify logic in init_irq() below.
-@@ -968,11 +925,6 @@ static int ide_init_queue(ide_drive_t *drive)
+@@ -924,13 +888,6 @@ static int ide_init_queue(ide_drive_t *drive)
+ 	q->queuedata = drive;
+ 	blk_queue_segment_boundary(q, 0xffff);
+ 
+-	if (!hwif->rqsize) {
+-		if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
+-		    (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
+-			hwif->rqsize = 256;
+-		else
+-			hwif->rqsize = 65536;
+-	}
+ 	if (hwif->rqsize < max_sectors)
+ 		max_sectors = hwif->rqsize;
+ 	blk_queue_max_sectors(q, max_sectors);
+@@ -961,6 +918,48 @@ static int ide_init_queue(ide_drive_t *drive)
+ 	return 0;
+ }
+ 
++static void ide_add_drive_to_hwgroup(ide_drive_t *drive)
++{
++	ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
++
++	spin_lock_irq(&ide_lock);
++	if (!hwgroup->drive) {
++		/* first drive for hwgroup. */
++		drive->next = drive;
++		hwgroup->drive = drive;
++		hwgroup->hwif = HWIF(hwgroup->drive);
++	} else {
++		drive->next = hwgroup->drive->next;
++		hwgroup->drive->next = drive;
++	}
++	spin_unlock_irq(&ide_lock);
++}
++
++/*
++ * For any present drive:
++ * - allocate the block device queue
++ * - link drive into the hwgroup
++ */
++static void ide_port_setup_devices(ide_hwif_t *hwif)
++{
++	int i;
++
++	for (i = 0; i < MAX_DRIVES; i++) {
++		ide_drive_t *drive = &hwif->drives[i];
++
++		if (!drive->present)
++			continue;
++
++		if (ide_init_queue(drive)) {
++			printk(KERN_ERR "ide: failed to init %s\n",
++					drive->name);
++			continue;
++		}
++
++		ide_add_drive_to_hwgroup(drive);
++	}
++}
++
+ /*
+  * This routine sets up the irq for an ide interface, and creates a new
+  * hwgroup for the irq/hwif if none was previously assigned.
+@@ -968,11 +967,6 @@ static int ide_init_queue(ide_drive_t *drive)
   * Much of the code is for correctly detecting/handling irq sharing
   * and irq serialization situations.  This is somewhat complex because
   * it handles static as well as dynamic (PCMCIA) IDE interfaces.
@@ -404845,7 +407895,7 @@
   */
  static int init_irq (ide_hwif_t *hwif)
  {
-@@ -1031,21 +983,17 @@ static int init_irq (ide_hwif_t *hwif)
+@@ -1031,21 +1025,17 @@ static int init_irq (ide_hwif_t *hwif)
  		spin_lock_irq(&ide_lock);
  		hwif->next = hwgroup->hwif->next;
  		hwgroup->hwif->next = hwif;
@@ -404873,7 +407923,7 @@
  		init_timer(&hwgroup->timer);
  		hwgroup->timer.function = &ide_timer_expiry;
  		hwgroup->timer.data = (unsigned long) hwgroup;
-@@ -1055,17 +1003,13 @@ static int init_irq (ide_hwif_t *hwif)
+@@ -1055,17 +1045,13 @@ static int init_irq (ide_hwif_t *hwif)
  	 * Allocate the irq, if not already obtained for another hwif
  	 */
  	if (!match || match->irq != hwif->irq) {
@@ -404893,7 +407943,50 @@
  
  		if (hwif->io_ports[IDE_CONTROL_OFFSET])
  			/* clear nIEN */
-@@ -1117,25 +1061,7 @@ static int init_irq (ide_hwif_t *hwif)
+@@ -1075,30 +1061,12 @@ static int init_irq (ide_hwif_t *hwif)
+ 	       		goto out_unlink;
+ 	}
+ 
+-	/*
+-	 * For any present drive:
+-	 * - allocate the block device queue
+-	 * - link drive into the hwgroup
+-	 */
+-	for (index = 0; index < MAX_DRIVES; ++index) {
+-		ide_drive_t *drive = &hwif->drives[index];
+-		if (!drive->present)
+-			continue;
+-		if (ide_init_queue(drive)) {
+-			printk(KERN_ERR "ide: failed to init %s\n",drive->name);
+-			continue;
+-		}
+-		spin_lock_irq(&ide_lock);
+-		if (!hwgroup->drive) {
+-			/* first drive for hwgroup. */
+-			drive->next = drive;
+-			hwgroup->drive = drive;
+-			hwgroup->hwif = HWIF(hwgroup->drive);
+-		} else {
+-			drive->next = hwgroup->drive->next;
+-			hwgroup->drive->next = drive;
+-		}
+-		spin_unlock_irq(&ide_lock);
++	if (!hwif->rqsize) {
++		if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
++		    (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
++			hwif->rqsize = 256;
++		else
++			hwif->rqsize = 65536;
+ 	}
+ 
+ #if !defined(__mc68000__) && !defined(CONFIG_APUS)
+@@ -1114,28 +1082,13 @@ static int init_irq (ide_hwif_t *hwif)
+ 		printk(" (%sed with %s)",
+ 			hwif->sharing_irq ? "shar" : "serializ", match->name);
+ 	printk("\n");
++
++	ide_port_setup_devices(hwif);
++
  	mutex_unlock(&ide_cfg_mtx);
  	return 0;
  out_unlink:
@@ -404920,7 +408013,7 @@
  out_up:
  	mutex_unlock(&ide_cfg_mtx);
  	return 1;
-@@ -1173,7 +1099,7 @@ static struct kobject *exact_match(dev_t dev, int *part, void *data)
+@@ -1173,7 +1126,7 @@ static struct kobject *exact_match(dev_t dev, int *part, void *data)
  {
  	struct gendisk *p = data;
  	*part &= (1 << PARTN_BITS) - 1;
@@ -404929,7 +408022,35 @@
  }
  
  static int exact_lock(dev_t dev, void *data)
-@@ -1284,28 +1210,21 @@ static int hwif_init(ide_hwif_t *hwif)
+@@ -1256,56 +1209,25 @@ static void drive_release_dev (struct device *dev)
+ 	complete(&drive->gendev_rel_comp);
+ }
+ 
+-/*
+- * init_gendisk() (as opposed to ide_geninit) is called for each major device,
+- * after probing for drives, to allocate partition tables and other data
+- * structures needed for the routines in genhd.c.  ide_geninit() gets called
+- * somewhat later, during the partition check.
+- */
+-static void init_gendisk (ide_hwif_t *hwif)
+-{
+-	unsigned int unit;
+-
+-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
+-		ide_drive_t * drive = &hwif->drives[unit];
+-		ide_add_generic_settings(drive);
+-		snprintf(drive->gendev.bus_id,BUS_ID_SIZE,"%u.%u",
+-			 hwif->index,unit);
+-		drive->gendev.parent = &hwif->gendev;
+-		drive->gendev.bus = &ide_bus_type;
+-		drive->gendev.driver_data = drive;
+-		drive->gendev.release = drive_release_dev;
+-	}
+-	blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
+-			THIS_MODULE, ata_probe, ata_lock, hwif);
+-}
+-
+ static int hwif_init(ide_hwif_t *hwif)
  {
  	int old_irq;
  
@@ -404960,23 +408081,54 @@
  	if (register_blkdev(hwif->major, hwif->name))
  		return 0;
  
-@@ -1344,10 +1263,7 @@ static int hwif_init(ide_hwif_t *hwif)
+@@ -1343,11 +1265,8 @@ static int hwif_init(ide_hwif_t *hwif)
+ 		hwif->name, hwif->irq);
  
  done:
- 	init_gendisk(hwif);
+-	init_gendisk(hwif);
 -
- 	ide_acpi_init(hwif);
+-	ide_acpi_init(hwif);
 -
 -	hwif->present = 1;	/* success */
++	blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
++			    THIS_MODULE, ata_probe, ata_lock, hwif);
  	return 1;
  
  out:
-@@ -1373,54 +1289,87 @@ static void hwif_register_devices(ide_hwif_t *hwif)
+@@ -1361,66 +1280,204 @@ static void hwif_register_devices(ide_hwif_t *hwif)
+ 
+ 	for (i = 0; i < MAX_DRIVES; i++) {
+ 		ide_drive_t *drive = &hwif->drives[i];
++		struct device *dev = &drive->gendev;
++		int ret;
+ 
+-		if (drive->present) {
+-			int ret = device_register(&drive->gendev);
++		if (!drive->present)
++			continue;
+ 
+-			if (ret < 0)
+-				printk(KERN_WARNING "IDE: %s: "
+-					"device_register error: %d\n",
+-					__FUNCTION__, ret);
+-		}
++		ide_add_generic_settings(drive);
++
++		snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i);
++		dev->parent = &hwif->gendev;
++		dev->bus = &ide_bus_type;
++		dev->driver_data = drive;
++		dev->release = drive_release_dev;
++
++		ret = device_register(dev);
++		if (ret < 0)
++			printk(KERN_WARNING "IDE: %s: device_register error: "
++					    "%d\n", __func__, ret);
  	}
  }
  
 -int ideprobe_init (void)
-+int ide_device_add_all(u8 *idx)
++static void ide_port_init_devices(ide_hwif_t *hwif)
  {
 -	unsigned int index;
 -	int probe[MAX_HWIFS];
@@ -404999,9 +408151,108 @@
 -			if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced)
 -				hwif->chipset = ide_generic;
 -			hwif_register_devices(hwif);
-+	ide_hwif_t *hwif;
-+	int i, rc = 0;
+-		}
++	int i;
++
++	for (i = 0; i < MAX_DRIVES; i++) {
++		ide_drive_t *drive = &hwif->drives[i];
++
++		if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
++			drive->io_32bit = 1;
++		if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
++			drive->unmask = 1;
++		if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
++			drive->no_unmask = 1;
++		if ((hwif->host_flags & IDE_HFLAG_NO_AUTOTUNE) == 0)
++			drive->autotune = 1;
+ 	}
+-	for (index = 0; index < MAX_HWIFS; ++index)
+-		if (probe[index])
+-			ide_proc_register_port(&ide_hwifs[index]);
+-	return 0;
++
++	if (hwif->port_init_devs)
++		hwif->port_init_devs(hwif);
+ }
+ 
+-EXPORT_SYMBOL_GPL(ideprobe_init);
++static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
++			  const struct ide_port_info *d)
++{
++	if (d->chipset != ide_etrax100)
++		hwif->channel = port;
+ 
+-int ide_device_add(u8 idx[4])
++	if (d->chipset)
++		hwif->chipset = d->chipset;
++
++	if (d->init_iops)
++		d->init_iops(hwif);
++
++	if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
++		ide_hwif_setup_dma(hwif, d);
++
++	if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
++	    (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
++		hwif->irq = port ? 15 : 14;
++
++	hwif->host_flags = d->host_flags;
++	hwif->pio_mask = d->pio_mask;
++
++	if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)
++		hwif->mate->serialized = hwif->serialized = 1;
++
++	hwif->swdma_mask = d->swdma_mask;
++	hwif->mwdma_mask = d->mwdma_mask;
++	hwif->ultra_mask = d->udma_mask;
++
++	/* reset DMA masks only for SFF-style DMA controllers */
++	if ((d->host_flags && IDE_HFLAG_NO_DMA) == 0 && hwif->dma_base == 0)
++		hwif->swdma_mask = hwif->mwdma_mask = hwif->ultra_mask = 0;
++
++	if (d->host_flags & IDE_HFLAG_RQSIZE_256)
++		hwif->rqsize = 256;
++
++	/* call chipset specific routine for each enabled port */
++	if (d->init_hwif)
++		d->init_hwif(hwif);
++
++	if (hwif->cable_detect && (hwif->ultra_mask & 0x78)) {
++		if (hwif->cbl != ATA_CBL_PATA40_SHORT)
++			hwif->cbl = hwif->cable_detect(hwif);
++	}
++}
++
++int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
+ {
++	ide_hwif_t *hwif, *mate = NULL;
+ 	int i, rc = 0;
+ 
+-	for (i = 0; i < 4; i++) {
+-		if (idx[i] != 0xff)
+-			rc |= probe_hwif_init(&ide_hwifs[idx[i]]);
++	for (i = 0; i < MAX_HWIFS; i++) {
++		if (d == NULL || idx[i] == 0xff) {
++			mate = NULL;
++			continue;
++		}
++
++		hwif = &ide_hwifs[idx[i]];
++
++		if (d->chipset != ide_etrax100 && (i & 1) && mate) {
++			hwif->mate = mate;
++			mate->mate = hwif;
++		}
 +
++		mate = (i & 1) ? NULL : hwif;
++
++		ide_init_port(hwif, i & 1, d);
++		ide_port_init_devices(hwif);
+ 	}
+ 
+-	for (i = 0; i < 4; i++) {
+-		if (idx[i] != 0xff)
+-			ide_proc_register_port(&ide_hwifs[idx[i]]);
 +	for (i = 0; i < MAX_HWIFS; i++) {
 +		if (idx[i] == 0xff)
 +			continue;
@@ -405018,7 +408269,7 @@
 +		if (ide_probe_port(hwif) < 0) {
 +			ide_hwif_release_regions(hwif);
 +			continue;
- 		}
++		}
 +
 +		hwif->present = 1;
 +
@@ -405027,26 +408278,14 @@
 +			ide_register_port(hwif);
 +
 +		ide_port_tune_devices(hwif);
- 	}
--	for (index = 0; index < MAX_HWIFS; ++index)
--		if (probe[index])
--			ide_proc_register_port(&ide_hwifs[index]);
--	return 0;
--}
- 
--EXPORT_SYMBOL_GPL(ideprobe_init);
++	}
++
 +	for (i = 0; i < MAX_HWIFS; i++) {
 +		if (idx[i] == 0xff)
 +			continue;
- 
--int ide_device_add(u8 idx[4])
--{
--	int i, rc = 0;
++
 +		hwif = &ide_hwifs[idx[i]];
- 
--	for (i = 0; i < 4; i++) {
--		if (idx[i] != 0xff)
--			rc |= probe_hwif_init(&ide_hwifs[idx[i]]);
++
 +		if (!hwif->present)
 +			continue;
 +
@@ -405057,9 +408296,11 @@
 +			rc = -1;
 +			continue;
 +		}
- 	}
- 
--	for (i = 0; i < 4; i++) {
++
++		ide_acpi_init(hwif);
++		ide_acpi_port_init_devices(hwif);
++	}
++
 +	for (i = 0; i < MAX_HWIFS; i++) {
 +		if (idx[i] == 0xff)
 +			continue;
@@ -405075,15 +408316,22 @@
 +	}
 +
 +	for (i = 0; i < MAX_HWIFS; i++) {
- 		if (idx[i] != 0xff)
- 			ide_proc_register_port(&ide_hwifs[idx[i]]);
++		if (idx[i] == 0xff)
++			continue;
++
++		hwif = &ide_hwifs[idx[i]];
++
++		if (hwif->present) {
++			ide_proc_register_port(hwif);
++			ide_proc_port_register_devices(hwif);
++		}
  	}
  
  	return rc;
  }
 +EXPORT_SYMBOL_GPL(ide_device_add_all);
  
-+int ide_device_add(u8 idx[4])
++int ide_device_add(u8 idx[4], const struct ide_port_info *d)
 +{
 +	u8 idx_all[MAX_HWIFS];
 +	int i;
@@ -405091,11 +408339,11 @@
 +	for (i = 0; i < MAX_HWIFS; i++)
 +		idx_all[i] = (i < 4) ? idx[i] : 0xff;
 +
-+	return ide_device_add_all(idx_all);
++	return ide_device_add_all(idx_all, d);
 +}
  EXPORT_SYMBOL_GPL(ide_device_add);
 diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
-index a4007d3..00c249c 100644
+index a4007d3..975c0ff 100644
 --- a/drivers/ide/ide-proc.c
 +++ b/drivers/ide/ide-proc.c
 @@ -1,6 +1,4 @@
@@ -405129,6 +408377,34 @@
  
  	if (!err && arg) {
  		ide_set_xfer_rate(drive, (u8) arg);
+@@ -735,7 +739,7 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
+ 
+ EXPORT_SYMBOL(ide_proc_unregister_driver);
+ 
+-static void create_proc_ide_drives(ide_hwif_t *hwif)
++void ide_proc_port_register_devices(ide_hwif_t *hwif)
+ {
+ 	int	d;
+ 	struct proc_dir_entry *ent;
+@@ -789,9 +793,6 @@ static ide_proc_entry_t hwif_entries[] = {
+ 
+ void ide_proc_register_port(ide_hwif_t *hwif)
+ {
+-	if (!hwif->present)
+-		return;
+-
+ 	if (!hwif->proc) {
+ 		hwif->proc = proc_mkdir(hwif->name, proc_ide_root);
+ 
+@@ -800,8 +801,6 @@ void ide_proc_register_port(ide_hwif_t *hwif)
+ 
+ 		ide_add_proc_entries(hwif->proc, hwif_entries, hwif);
+ 	}
+-
+-	create_proc_ide_drives(hwif);
+ }
+ 
+ #ifdef CONFIG_BLK_DEV_IDEPCI
 diff --git a/drivers/ide/ide-scan-pci.c b/drivers/ide/ide-scan-pci.c
 new file mode 100644
 index 0000000..93d2e41
@@ -405252,20 +408528,513 @@
 +
 +module_init(ide_scan_pcibus);
 diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
-index 7b9181b..5aef63a 100644
+index 7b9181b..bf40d8c 100644
 --- a/drivers/ide/ide-tape.c
 +++ b/drivers/ide/ide-tape.c
-@@ -1,7 +1,6 @@
+@@ -1,9 +1,8 @@
  /*
 - * linux/drivers/ide/ide-tape.c		Version 1.19	Nov, 2003
 - *
 - * Copyright (C) 1995 - 1999 Gadi Oxman <gadio at netvision.net.il>
++ * IDE ATAPI streaming tape driver.
+  *
+- * $Header$
 + * Copyright (C) 1995-1999  Gadi Oxman <gadio at netvision.net.il>
 + * Copyright (C) 2003-2005  Bartlomiej Zolnierkiewicz
   *
-  * $Header$
+  * This driver was constructed as a student project in the software laboratory
+  * of the faculty of electrical engineering in the Technion - Israel's
+@@ -11,415 +10,9 @@
+  *
+  * It is hereby placed under the terms of the GNU general public license.
+  * (See linux/COPYING).
+- */
+- 
+-/*
+- * IDE ATAPI streaming tape driver.
+- *
+- * This driver is a part of the Linux ide driver and works in co-operation
+- * with linux/drivers/block/ide.c.
+- *
+- * The driver, in co-operation with ide.c, basically traverses the 
+- * request-list for the block device interface. The character device
+- * interface, on the other hand, creates new requests, adds them
+- * to the request-list of the block device, and waits for their completion.
+- *
+- * Pipelined operation mode is now supported on both reads and writes.
+- *
+- * The block device major and minor numbers are determined from the
+- * tape's relative position in the ide interfaces, as explained in ide.c.
+- *
+- * The character device interface consists of the following devices:
+- *
+- * ht0		major 37, minor 0	first  IDE tape, rewind on close.
+- * ht1		major 37, minor 1	second IDE tape, rewind on close.
+- * ...
+- * nht0		major 37, minor 128	first  IDE tape, no rewind on close.
+- * nht1		major 37, minor 129	second IDE tape, no rewind on close.
+- * ...
+- *
+- * Run linux/scripts/MAKEDEV.ide to create the above entries.
+- *
+- * The general magnetic tape commands compatible interface, as defined by
+- * include/linux/mtio.h, is accessible through the character device.
+- *
+- * General ide driver configuration options, such as the interrupt-unmask
+- * flag, can be configured by issuing an ioctl to the block device interface,
+- * as any other ide device.
+- *
+- * Our own ide-tape ioctl's can be issued to either the block device or
+- * the character device interface.
+- *
+- * Maximal throughput with minimal bus load will usually be achieved in the
+- * following scenario:
+- *
+- *	1.	ide-tape is operating in the pipelined operation mode.
+- *	2.	No buffering is performed by the user backup program.
+- *
+- * Testing was done with a 2 GB CONNER CTMA 4000 IDE ATAPI Streaming Tape Drive.
+- * 
+- * Ver 0.1   Nov  1 95   Pre-working code :-)
+- * Ver 0.2   Nov 23 95   A short backup (few megabytes) and restore procedure
+- *                        was successful ! (Using tar cvf ... on the block
+- *                        device interface).
+- *                       A longer backup resulted in major swapping, bad
+- *                        overall Linux performance and eventually failed as
+- *                        we received non serial read-ahead requests from the
+- *                        buffer cache.
+- * Ver 0.3   Nov 28 95   Long backups are now possible, thanks to the
+- *                        character device interface. Linux's responsiveness
+- *                        and performance doesn't seem to be much affected
+- *                        from the background backup procedure.
+- *                       Some general mtio.h magnetic tape operations are
+- *                        now supported by our character device. As a result,
+- *                        popular tape utilities are starting to work with
+- *                        ide tapes :-)
+- *                       The following configurations were tested:
+- *                       	1. An IDE ATAPI TAPE shares the same interface
+- *                       	   and irq with an IDE ATAPI CDROM.
+- *                        	2. An IDE ATAPI TAPE shares the same interface
+- *                          	   and irq with a normal IDE disk.
+- *                        Both configurations seemed to work just fine !
+- *                        However, to be on the safe side, it is meanwhile
+- *                        recommended to give the IDE TAPE its own interface
+- *                        and irq.
+- *                       The one thing which needs to be done here is to
+- *                        add a "request postpone" feature to ide.c,
+- *                        so that we won't have to wait for the tape to finish
+- *                        performing a long media access (DSC) request (such
+- *                        as a rewind) before we can access the other device
+- *                        on the same interface. This effect doesn't disturb
+- *                        normal operation most of the time because read/write
+- *                        requests are relatively fast, and once we are
+- *                        performing one tape r/w request, a lot of requests
+- *                        from the other device can be queued and ide.c will
+- *			  service all of them after this single tape request.
+- * Ver 1.0   Dec 11 95   Integrated into Linux 1.3.46 development tree.
+- *                       On each read / write request, we now ask the drive
+- *                        if we can transfer a constant number of bytes
+- *                        (a parameter of the drive) only to its buffers,
+- *                        without causing actual media access. If we can't,
+- *                        we just wait until we can by polling the DSC bit.
+- *                        This ensures that while we are not transferring
+- *                        more bytes than the constant referred to above, the
+- *                        interrupt latency will not become too high and
+- *                        we won't cause an interrupt timeout, as happened
+- *                        occasionally in the previous version.
+- *                       While polling for DSC, the current request is
+- *                        postponed and ide.c is free to handle requests from
+- *                        the other device. This is handled transparently to
+- *                        ide.c. The hwgroup locking method which was used
+- *                        in the previous version was removed.
+- *                       Use of new general features which are provided by
+- *                        ide.c for use with atapi devices.
+- *                        (Programming done by Mark Lord)
+- *                       Few potential bug fixes (Again, suggested by Mark)
+- *                       Single character device data transfers are now
+- *                        not limited in size, as they were before.
+- *                       We are asking the tape about its recommended
+- *                        transfer unit and send a larger data transfer
+- *                        as several transfers of the above size.
+- *                        For best results, use an integral number of this
+- *                        basic unit (which is shown during driver
+- *                        initialization). I will soon add an ioctl to get
+- *                        this important parameter.
+- *                       Our data transfer buffer is allocated on startup,
+- *                        rather than before each data transfer. This should
+- *                        ensure that we will indeed have a data buffer.
+- * Ver 1.1   Dec 14 95   Fixed random problems which occurred when the tape
+- *                        shared an interface with another device.
+- *                        (poll_for_dsc was a complete mess).
+- *                       Removed some old (non-active) code which had
+- *                        to do with supporting buffer cache originated
+- *                        requests.
+- *                       The block device interface can now be opened, so
+- *                        that general ide driver features like the unmask
+- *                        interrupts flag can be selected with an ioctl.
+- *                        This is the only use of the block device interface.
+- *                       New fast pipelined operation mode (currently only on
+- *                        writes). When using the pipelined mode, the
+- *                        throughput can potentially reach the maximum
+- *                        tape supported throughput, regardless of the
+- *                        user backup program. On my tape drive, it sometimes
+- *                        boosted performance by a factor of 2. Pipelined
+- *                        mode is enabled by default, but since it has a few
+- *                        downfalls as well, you may want to disable it.
+- *                        A short explanation of the pipelined operation mode
+- *                        is available below.
+- * Ver 1.2   Jan  1 96   Eliminated pipelined mode race condition.
+- *                       Added pipeline read mode. As a result, restores
+- *                        are now as fast as backups.
+- *                       Optimized shared interface behavior. The new behavior
+- *                        typically results in better IDE bus efficiency and
+- *                        higher tape throughput.
+- *                       Pre-calculation of the expected read/write request
+- *                        service time, based on the tape's parameters. In
+- *                        the pipelined operation mode, this allows us to
+- *                        adjust our polling frequency to a much lower value,
+- *                        and thus to dramatically reduce our load on Linux,
+- *                        without any decrease in performance.
+- *                       Implemented additional mtio.h operations.
+- *                       The recommended user block size is returned by
+- *                        the MTIOCGET ioctl.
+- *                       Additional minor changes.
+- * Ver 1.3   Feb  9 96   Fixed pipelined read mode bug which prevented the
+- *                        use of some block sizes during a restore procedure.
+- *                       The character device interface will now present a
+- *                        continuous view of the media - any mix of block sizes
+- *                        during a backup/restore procedure is supported. The
+- *                        driver will buffer the requests internally and
+- *                        convert them to the tape's recommended transfer
+- *                        unit, making performance almost independent of the
+- *                        chosen user block size.
+- *                       Some improvements in error recovery.
+- *                       By cooperating with ide-dma.c, bus mastering DMA can
+- *                        now sometimes be used with IDE tape drives as well.
+- *                        Bus mastering DMA has the potential to dramatically
+- *                        reduce the CPU's overhead when accessing the device,
+- *                        and can be enabled by using hdparm -d1 on the tape's
+- *                        block device interface. For more info, read the
+- *                        comments in ide-dma.c.
+- * Ver 1.4   Mar 13 96   Fixed serialize support.
+- * Ver 1.5   Apr 12 96   Fixed shared interface operation, broken in 1.3.85.
+- *                       Fixed pipelined read mode inefficiency.
+- *                       Fixed nasty null dereferencing bug.
+- * Ver 1.6   Aug 16 96   Fixed FPU usage in the driver.
+- *                       Fixed end of media bug.
+- * Ver 1.7   Sep 10 96   Minor changes for the CONNER CTT8000-A model.
+- * Ver 1.8   Sep 26 96   Attempt to find a better balance between good
+- *                        interactive response and high system throughput.
+- * Ver 1.9   Nov  5 96   Automatically cross encountered filemarks rather
+- *                        than requiring an explicit FSF command.
+- *                       Abort pending requests at end of media.
+- *                       MTTELL was sometimes returning incorrect results.
+- *                       Return the real block size in the MTIOCGET ioctl.
+- *                       Some error recovery bug fixes.
+- * Ver 1.10  Nov  5 96   Major reorganization.
+- *                       Reduced CPU overhead a bit by eliminating internal
+- *                        bounce buffers.
+- *                       Added module support.
+- *                       Added multiple tape drives support.
+- *                       Added partition support.
+- *                       Rewrote DSC handling.
+- *                       Some portability fixes.
+- *                       Removed ide-tape.h.
+- *                       Additional minor changes.
+- * Ver 1.11  Dec  2 96   Bug fix in previous DSC timeout handling.
+- *                       Use ide_stall_queue() for DSC overlap.
+- *                       Use the maximum speed rather than the current speed
+- *                        to compute the request service time.
+- * Ver 1.12  Dec  7 97   Fix random memory overwriting and/or last block data
+- *                        corruption, which could occur if the total number
+- *                        of bytes written to the tape was not an integral
+- *                        number of tape blocks.
+- *                       Add support for INTERRUPT DRQ devices.
+- * Ver 1.13  Jan  2 98   Add "speed == 0" work-around for HP COLORADO 5GB
+- * Ver 1.14  Dec 30 98   Partial fixes for the Sony/AIWA tape drives.
+- *                       Replace cli()/sti() with hwgroup spinlocks.
+- * Ver 1.15  Mar 25 99   Fix SMP race condition by replacing hwgroup
+- *                        spinlock with private per-tape spinlock.
+- * Ver 1.16  Sep  1 99   Add OnStream tape support.
+- *                       Abort read pipeline on EOD.
+- *                       Wait for the tape to become ready in case it returns
+- *                        "in the process of becoming ready" on open().
+- *                       Fix zero padding of the last written block in
+- *                        case the tape block size is larger than PAGE_SIZE.
+- *                       Decrease the default disconnection time to tn.
+- * Ver 1.16e Oct  3 99   Minor fixes.
+- * Ver 1.16e1 Oct 13 99  Patches by Arnold Niessen,
+- *                          niessen at iae.nl / arnold.niessen at philips.com
+- *                   GO-1)  Undefined code in idetape_read_position
+- *				according to Gadi's email
+- *                   AJN-1) Minor fix asc == 11 should be asc == 0x11
+- *                               in idetape_issue_packet_command (did effect
+- *                               debugging output only)
+- *                   AJN-2) Added more debugging output, and
+- *                              added ide-tape: where missing. I would also
+- *				like to add tape->name where possible
+- *                   AJN-3) Added different debug_level's 
+- *                              via /proc/ide/hdc/settings
+- * 				"debug_level" determines amount of debugging output;
+- * 				can be changed using /proc/ide/hdx/settings
+- * 				0 : almost no debugging output
+- * 				1 : 0+output errors only
+- * 				2 : 1+output all sensekey/asc
+- * 				3 : 2+follow all chrdev related procedures
+- * 				4 : 3+follow all procedures
+- * 				5 : 4+include pc_stack rq_stack info
+- * 				6 : 5+USE_COUNT updates
+- *                   AJN-4) Fixed timeout for retension in idetape_queue_pc_tail
+- *				from 5 to 10 minutes
+- *                   AJN-5) Changed maximum number of blocks to skip when
+- *                              reading tapes with multiple consecutive write
+- *                              errors from 100 to 1000 in idetape_get_logical_blk
+- *                   Proposed changes to code:
+- *                   1) output "logical_blk_num" via /proc
+- *                   2) output "current_operation" via /proc
+- *                   3) Either solve or document the fact that `mt rewind' is
+- *                      required after reading from /dev/nhtx to be
+- *			able to rmmod the idetape module;
+- *			Also, sometimes an application finishes but the
+- *			device remains `busy' for some time. Same cause ?
+- *                   Proposed changes to release-notes:
+- *		     4) write a simple `quickstart' section in the
+- *                      release notes; I volunteer if you don't want to
+- * 		     5) include a pointer to video4linux in the doc
+- *                      to stimulate video applications
+- *                   6) release notes lines 331 and 362: explain what happens
+- *			if the application data rate is higher than 1100 KB/s; 
+- *			similar approach to lower-than-500 kB/s ?
+- *		     7) 6.6 Comparison; wouldn't it be better to allow different 
+- *			strategies for read and write ?
+- *			Wouldn't it be better to control the tape buffer
+- *			contents instead of the bandwidth ?
+- *		     8) line 536: replace will by would (if I understand
+- *			this section correctly, a hypothetical and unwanted situation
+- *			 is being described)
+- * Ver 1.16f Dec 15 99   Change place of the secondary OnStream header frames.
+- * Ver 1.17  Nov 2000 / Jan 2001  Marcel Mol, marcel at mesa.nl
+- *			- Add idetape_onstream_mode_sense_tape_parameter_page
+- *			  function to get tape capacity in frames: tape->capacity.
+- *			- Add support for DI-50 drives( or any DI- drive).
+- *			- 'workaround' for read error/blank block around block 3000.
+- *			- Implement Early warning for end of media for Onstream.
+- *			- Cosmetic code changes for readability.
+- *			- Idetape_position_tape should not use SKIP bit during
+- *			  Onstream read recovery.
+- *			- Add capacity, logical_blk_num and first/last_frame_position
+- *			  to /proc/ide/hd?/settings.
+- *			- Module use count was gone in the Linux 2.4 driver.
+- * Ver 1.17a Apr 2001 Willem Riede osst at riede.org
+- * 			- Get drive's actual block size from mode sense block descriptor
+- * 			- Limit size of pipeline
+- * Ver 1.17b Oct 2002   Alan Stern <stern at rowland.harvard.edu>
+- *			Changed IDETAPE_MIN_PIPELINE_STAGES to 1 and actually used
+- *			 it in the code!
+- *			Actually removed aborted stages in idetape_abort_pipeline
+- *			 instead of just changing the command code.
+- *			Made the transfer byte count for Request Sense equal to the
+- *			 actual length of the data transfer.
+- *			Changed handling of partial data transfers: they do not
+- *			 cause DMA errors.
+- *			Moved initiation of DMA transfers to the correct place.
+- *			Removed reference to unallocated memory.
+- *			Made __idetape_discard_read_pipeline return the number of
+- *			 sectors skipped, not the number of stages.
+- *			Replaced errant kfree() calls with __idetape_kfree_stage().
+- *			Fixed off-by-one error in testing the pipeline length.
+- *			Fixed handling of filemarks in the read pipeline.
+- *			Small code optimization for MTBSF and MTBSFM ioctls.
+- *			Don't try to unlock the door during device close if is
+- *			 already unlocked!
+- *			Cosmetic fixes to miscellaneous debugging output messages.
+- *			Set the minimum /proc/ide/hd?/settings values for "pipeline",
+- *			 "pipeline_min", and "pipeline_max" to 1.
+- *
+- * Here are some words from the first releases of hd.c, which are quoted
+- * in ide.c and apply here as well:
+- *
+- * | Special care is recommended.  Have Fun!
+- *
+- */
+-
+-/*
+- * An overview of the pipelined operation mode.
+- *
+- * In the pipelined write mode, we will usually just add requests to our
+- * pipeline and return immediately, before we even start to service them. The
+- * user program will then have enough time to prepare the next request while
+- * we are still busy servicing previous requests. In the pipelined read mode,
+- * the situation is similar - we add read-ahead requests into the pipeline,
+- * before the user even requested them.
+- *
+- * The pipeline can be viewed as a "safety net" which will be activated when
+- * the system load is high and prevents the user backup program from keeping up
+- * with the current tape speed. At this point, the pipeline will get
+- * shorter and shorter but the tape will still be streaming at the same speed.
+- * Assuming we have enough pipeline stages, the system load will hopefully
+- * decrease before the pipeline is completely empty, and the backup program
+- * will be able to "catch up" and refill the pipeline again.
+- * 
+- * When using the pipelined mode, it would be best to disable any type of
+- * buffering done by the user program, as ide-tape already provides all the
+- * benefits in the kernel, where it can be done in a more efficient way.
+- * As we will usually not block the user program on a request, the most
+- * efficient user code will then be a simple read-write-read-... cycle.
+- * Any additional logic will usually just slow down the backup process.
+- *
+- * Using the pipelined mode, I get a constant over 400 KBps throughput,
+- * which seems to be the maximum throughput supported by my tape.
+  *
+- * However, there are some downfalls:
+- *
+- *	1.	We use memory (for data buffers) in proportional to the number
+- *		of pipeline stages (each stage is about 26 KB with my tape).
+- *	2.	In the pipelined write mode, we cheat and postpone error codes
+- *		to the user task. In read mode, the actual tape position
+- *		will be a bit further than the last requested block.
+- *
+- * Concerning (1):
+- *
+- *	1.	We allocate stages dynamically only when we need them. When
+- *		we don't need them, we don't consume additional memory. In
+- *		case we can't allocate stages, we just manage without them
+- *		(at the expense of decreased throughput) so when Linux is
+- *		tight in memory, we will not pose additional difficulties.
+- *
+- *	2.	The maximum number of stages (which is, in fact, the maximum
+- *		amount of memory) which we allocate is limited by the compile
+- *		time parameter IDETAPE_MAX_PIPELINE_STAGES.
+- *
+- *	3.	The maximum number of stages is a controlled parameter - We
+- *		don't start from the user defined maximum number of stages
+- *		but from the lower IDETAPE_MIN_PIPELINE_STAGES (again, we
+- *		will not even allocate this amount of stages if the user
+- *		program can't handle the speed). We then implement a feedback
+- *		loop which checks if the pipeline is empty, and if it is, we
+- *		increase the maximum number of stages as necessary until we
+- *		reach the optimum value which just manages to keep the tape
+- *		busy with minimum allocated memory or until we reach
+- *		IDETAPE_MAX_PIPELINE_STAGES.
+- *
+- * Concerning (2):
+- *
+- *	In pipelined write mode, ide-tape can not return accurate error codes
+- *	to the user program since we usually just add the request to the
+- *      pipeline without waiting for it to be serviced. In case an error
+- *      occurs, I will report it on the next user request.
+- *
+- *	In the pipelined read mode, subsequent read requests or forward
+- *	filemark spacing will perform correctly, as we preserve all blocks
+- *	and filemarks which we encountered during our excess read-ahead.
+- * 
+- *	For accurate tape positioning and error reporting, disabling
+- *	pipelined mode might be the best option.
+- *
+- * You can enable/disable/tune the pipelined operation mode by adjusting
+- * the compile time parameters below.
+- */
+-
+-/*
+- *	Possible improvements.
+- *
+- *	1.	Support for the ATAPI overlap protocol.
+- *
+- *		In order to maximize bus throughput, we currently use the DSC
+- *		overlap method which enables ide.c to service requests from the
+- *		other device while the tape is busy executing a command. The
+- *		DSC overlap method involves polling the tape's status register
+- *		for the DSC bit, and servicing the other device while the tape
+- *		isn't ready.
+- *
+- *		In the current QIC development standard (December 1995),
+- *		it is recommended that new tape drives will *in addition* 
+- *		implement the ATAPI overlap protocol, which is used for the
+- *		same purpose - efficient use of the IDE bus, but is interrupt
+- *		driven and thus has much less CPU overhead.
+- *
+- *		ATAPI overlap is likely to be supported in most new ATAPI
+- *		devices, including new ATAPI cdroms, and thus provides us
+- *		a method by which we can achieve higher throughput when
+- *		sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
++ * For a historical changelog see
++ * Documentation/ide/ChangeLog.ide-tape.1995-2002
+  */
+ 
+ #define IDETAPE_VERSION "1.19"
+@@ -443,49 +36,13 @@
+ #include <linux/completion.h>
+ #include <linux/bitops.h>
+ #include <linux/mutex.h>
++#include <scsi/scsi.h>
+ 
+ #include <asm/byteorder.h>
+ #include <asm/irq.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+ #include <asm/unaligned.h>
+-
+-/*
+- * partition
+- */
+-typedef struct os_partition_s {
+-	__u8	partition_num;
+-	__u8	par_desc_ver;
+-	__u16	wrt_pass_cntr;
+-	__u32	first_frame_addr;
+-	__u32	last_frame_addr;
+-	__u32	eod_frame_addr;
+-} os_partition_t;
+-
+-/*
+- * DAT entry
+- */
+-typedef struct os_dat_entry_s {
+-	__u32	blk_sz;
+-	__u16	blk_cnt;
+-	__u8	flags;
+-	__u8	reserved;
+-} os_dat_entry_t;
+-
+-/*
+- * DAT
+- */
+-#define OS_DAT_FLAGS_DATA	(0xc)
+-#define OS_DAT_FLAGS_MARK	(0x1)
+-
+-typedef struct os_dat_s {
+-	__u8		dat_sz;
+-	__u8		reserved1;
+-	__u8		entry_cnt;
+-	__u8		reserved3;
+-	os_dat_entry_t	dat_list[16];
+-} os_dat_t;
+-
+ #include <linux/mtio.h>
+ 
+ /**************************** Tunable parameters *****************************/
+@@ -513,10 +70,7 @@ typedef struct os_dat_s {
+ /*
+  *	The following are used to debug the driver:
+  *
+- *	Setting IDETAPE_DEBUG_INFO to 1 will report device capabilities.
+  *	Setting IDETAPE_DEBUG_LOG to 1 will log driver flow control.
+- *	Setting IDETAPE_DEBUG_BUGS to 1 will enable self-sanity checks in
+- *	some places.
+  *
+  *	Setting them to 0 will restore normal operation mode:
   *
-@@ -615,16 +614,6 @@ typedef struct os_dat_s {
+@@ -528,9 +82,7 @@ typedef struct os_dat_s {
+  *	is verified to be stable enough. This will make it much more
+  *	esthetic.
+  */
+-#define IDETAPE_DEBUG_INFO		0
+ #define IDETAPE_DEBUG_LOG		0
+-#define IDETAPE_DEBUG_BUGS		1
+ 
+ /*
+  *	After each failed packet command we issue a request sense command
+@@ -615,16 +167,6 @@ typedef struct os_dat_s {
  /*************************** End of tunable parameters ***********************/
  
  /*
@@ -405282,7 +409051,478 @@
   *	Read/Write error simulation
   */
  #define SIMULATE_ERRORS			0
-@@ -1700,6 +1689,11 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
+@@ -682,65 +224,6 @@ typedef struct idetape_packet_command_s {
+ #define	PC_WRITING			5
+ 
+ /*
+- *	Capabilities and Mechanical Status Page
+- */
+-typedef struct {
+-	unsigned	page_code	:6;	/* Page code - Should be 0x2a */
+-	__u8		reserved0_6	:1;
+-	__u8		ps		:1;	/* parameters saveable */
+-	__u8		page_length;		/* Page Length - Should be 0x12 */
+-	__u8		reserved2, reserved3;
+-	unsigned	ro		:1;	/* Read Only Mode */
+-	unsigned	reserved4_1234	:4;
+-	unsigned	sprev		:1;	/* Supports SPACE in the reverse direction */
+-	unsigned	reserved4_67	:2;
+-	unsigned	reserved5_012	:3;
+-	unsigned	efmt		:1;	/* Supports ERASE command initiated formatting */
+-	unsigned	reserved5_4	:1;
+-	unsigned	qfa		:1;	/* Supports the QFA two partition formats */
+-	unsigned	reserved5_67	:2;
+-	unsigned	lock		:1;	/* Supports locking the volume */
+-	unsigned	locked		:1;	/* The volume is locked */
+-	unsigned	prevent		:1;	/* The device defaults in the prevent state after power up */	
+-	unsigned	eject		:1;	/* The device can eject the volume */
+-	__u8		disconnect	:1;	/* The device can break request > ctl */	
+-	__u8		reserved6_5	:1;
+-	unsigned	ecc		:1;	/* Supports error correction */
+-	unsigned	cmprs		:1;	/* Supports data compression */
+-	unsigned	reserved7_0	:1;
+-	unsigned	blk512		:1;	/* Supports 512 bytes block size */
+-	unsigned	blk1024		:1;	/* Supports 1024 bytes block size */
+-	unsigned	reserved7_3_6	:4;
+-	unsigned	blk32768	:1;	/* slowb - the device restricts the byte count for PIO */
+-						/* transfers for slow buffer memory ??? */
+-						/* Also 32768 block size in some cases */
+-	__u16		max_speed;		/* Maximum speed supported in KBps */
+-	__u8		reserved10, reserved11;
+-	__u16		ctl;			/* Continuous Transfer Limit in blocks */
+-	__u16		speed;			/* Current Speed, in KBps */
+-	__u16		buffer_size;		/* Buffer Size, in 512 bytes */
+-	__u8		reserved18, reserved19;
+-} idetape_capabilities_page_t;
+-
+-/*
+- *	Block Size Page
+- */
+-typedef struct {
+-	unsigned	page_code	:6;	/* Page code - Should be 0x30 */
+-	unsigned	reserved1_6	:1;
+-	unsigned	ps		:1;
+-	__u8		page_length;		/* Page Length - Should be 2 */
+-	__u8		reserved2;
+-	unsigned	play32		:1;
+-	unsigned	play32_5	:1;
+-	unsigned	reserved2_23	:2;
+-	unsigned	record32	:1;
+-	unsigned	record32_5	:1;
+-	unsigned	reserved2_6	:1;
+-	unsigned	one		:1;
+-} idetape_block_size_page_t;
+-
+-/*
+  *	A pipeline stage.
+  */
+ typedef struct idetape_stage_s {
+@@ -750,32 +233,6 @@ typedef struct idetape_stage_s {
+ } idetape_stage_t;
+ 
+ /*
+- *	REQUEST SENSE packet command result - Data Format.
+- */
+-typedef struct {
+-	unsigned	error_code	:7;	/* Current of deferred errors */
+-	unsigned	valid		:1;	/* The information field conforms to QIC-157C */
+-	__u8		reserved1	:8;	/* Segment Number - Reserved */
+-	unsigned	sense_key	:4;	/* Sense Key */
+-	unsigned	reserved2_4	:1;	/* Reserved */
+-	unsigned	ili		:1;	/* Incorrect Length Indicator */
+-	unsigned	eom		:1;	/* End Of Medium */
+-	unsigned	filemark 	:1;	/* Filemark */
+-	__u32		information __attribute__ ((packed));
+-	__u8		asl;			/* Additional sense length (n-7) */
+-	__u32		command_specific;	/* Additional command specific information */
+-	__u8		asc;			/* Additional Sense Code */
+-	__u8		ascq;			/* Additional Sense Code Qualifier */
+-	__u8		replaceable_unit_code;	/* Field Replaceable Unit Code */
+-	unsigned	sk_specific1 	:7;	/* Sense Key Specific */
+-	unsigned	sksv		:1;	/* Sense Key Specific information is valid */
+-	__u8		sk_specific2;		/* Sense Key Specific */
+-	__u8		sk_specific3;		/* Sense Key Specific */
+-	__u8		pad[2];			/* Padding to 20 bytes */
+-} idetape_request_sense_result_t;
+-
+-
+-/*
+  *	Most of our global data which we need to save even as we leave the
+  *	driver due to an interrupt or a timer event is stored in a variable
+  *	of type idetape_tape_t, defined below.
+@@ -865,8 +322,9 @@ typedef struct ide_tape_obj {
+ 	/* Usually 512 or 1024 bytes */
+ 	unsigned short tape_block_size;
+ 	int user_bs_factor;
++
+ 	/* Copy of the tape's Capabilities and Mechanical Page */
+-	idetape_capabilities_page_t capabilities;
++	u8 caps[20];
+ 
+ 	/*
+ 	 *	Active data transfer request parameters.
+@@ -929,9 +387,6 @@ typedef struct ide_tape_obj {
+ 	int avg_size;
+ 	int avg_speed;
+ 
+-	/* last sense information */
+-	idetape_request_sense_result_t sense;
+-
+ 	char vendor_id[10];
+ 	char product_id[18];
+ 	char firmware_revision[6];
+@@ -1063,27 +518,6 @@ static void ide_tape_put(struct ide_tape_obj *tape)
+ #define IDETAPE_MEDIUM_PRESENT		9
+ 
+ /*
+- *	Supported ATAPI tape drives packet commands
+- */
+-#define IDETAPE_TEST_UNIT_READY_CMD	0x00
+-#define IDETAPE_REWIND_CMD		0x01
+-#define IDETAPE_REQUEST_SENSE_CMD	0x03
+-#define IDETAPE_READ_CMD		0x08
+-#define IDETAPE_WRITE_CMD		0x0a
+-#define IDETAPE_WRITE_FILEMARK_CMD	0x10
+-#define IDETAPE_SPACE_CMD		0x11
+-#define IDETAPE_INQUIRY_CMD		0x12
+-#define IDETAPE_ERASE_CMD		0x19
+-#define IDETAPE_MODE_SENSE_CMD		0x1a
+-#define IDETAPE_MODE_SELECT_CMD		0x15
+-#define IDETAPE_LOAD_UNLOAD_CMD		0x1b
+-#define IDETAPE_PREVENT_CMD		0x1e
+-#define IDETAPE_LOCATE_CMD		0x2b
+-#define IDETAPE_READ_POSITION_CMD	0x34
+-#define IDETAPE_READ_BUFFER_CMD		0x3c
+-#define IDETAPE_SET_SPEED_CMD		0xbb
+-
+-/*
+  *	Some defines for the READ BUFFER command
+  */
+ #define IDETAPE_RETRIEVE_FAULTY_BLOCK	6
+@@ -1140,31 +574,6 @@ struct idetape_id_gcw {
+ };
+ 
+ /*
+- *	INQUIRY packet command - Data Format (From Table 6-8 of QIC-157C)
+- */
+-typedef struct {
+-	unsigned	device_type	:5;	/* Peripheral Device Type */
+-	unsigned	reserved0_765	:3;	/* Peripheral Qualifier - Reserved */
+-	unsigned	reserved1_6t0	:7;	/* Reserved */
+-	unsigned	rmb		:1;	/* Removable Medium Bit */
+-	unsigned	ansi_version	:3;	/* ANSI Version */
+-	unsigned	ecma_version	:3;	/* ECMA Version */
+-	unsigned	iso_version	:2;	/* ISO Version */
+-	unsigned	response_format :4;	/* Response Data Format */
+-	unsigned	reserved3_45	:2;	/* Reserved */
+-	unsigned	reserved3_6	:1;	/* TrmIOP - Reserved */
+-	unsigned	reserved3_7	:1;	/* AENC - Reserved */
+-	__u8		additional_length;	/* Additional Length (total_length-4) */
+-	__u8		rsv5, rsv6, rsv7;	/* Reserved */
+-	__u8		vendor_id[8];		/* Vendor Identification */
+-	__u8		product_id[16];		/* Product Identification */
+-	__u8		revision_level[4];	/* Revision Level */
+-	__u8		vendor_specific[20];	/* Vendor Specific - Optional */
+-	__u8		reserved56t95[40];	/* Reserved - Optional */
+-						/* Additional information may be returned */
+-} idetape_inquiry_result_t;
+-
+-/*
+  *	READ POSITION packet command - Data Format (From Table 6-57)
+  */
+ typedef struct {
+@@ -1182,100 +591,9 @@ typedef struct {
+ 	u32		bytes_in_buffer;	/* Bytes In Buffer (Optional) */
+ } idetape_read_position_result_t;
+ 
+-/*
+- *	Follows structures which are related to the SELECT SENSE / MODE SENSE
+- *	packet commands. Those packet commands are still not supported
+- *	by ide-tape.
+- */
++/* Structures related to the SELECT SENSE / MODE SENSE packet commands. */
+ #define IDETAPE_BLOCK_DESCRIPTOR	0
+ #define	IDETAPE_CAPABILITIES_PAGE	0x2a
+-#define IDETAPE_PARAMTR_PAGE		0x2b   /* Onstream DI-x0 only */
+-#define IDETAPE_BLOCK_SIZE_PAGE		0x30
+-#define IDETAPE_BUFFER_FILLING_PAGE	0x33
+-
+-/*
+- *	Mode Parameter Header for the MODE SENSE packet command
+- */
+-typedef struct {
+-	__u8	mode_data_length;	/* Length of the following data transfer */
+-	__u8	medium_type;		/* Medium Type */
+-	__u8	dsp;			/* Device Specific Parameter */
+-	__u8	bdl;			/* Block Descriptor Length */
+-#if 0
+-	/* data transfer page */
+-	__u8	page_code	:6;
+-	__u8	reserved0_6	:1;
+-	__u8	ps		:1;	/* parameters saveable */
+-	__u8	page_length;		/* page Length == 0x02 */
+-	__u8	reserved2;
+-	__u8	read32k		:1;	/* 32k blk size (data only) */
+-	__u8	read32k5	:1;	/* 32.5k blk size (data&AUX) */
+-	__u8	reserved3_23	:2;
+-	__u8	write32k	:1;	/* 32k blk size (data only) */
+-	__u8	write32k5	:1;	/* 32.5k blk size (data&AUX) */
+-	__u8	reserved3_6	:1;
+-	__u8	streaming	:1;	/* streaming mode enable */
+-#endif
+-} idetape_mode_parameter_header_t;
+-
+-/*
+- *	Mode Parameter Block Descriptor the MODE SENSE packet command
+- *
+- *	Support for block descriptors is optional.
+- */
+-typedef struct {
+-	__u8		density_code;		/* Medium density code */
+-	__u8		blocks[3];		/* Number of blocks */
+-	__u8		reserved4;		/* Reserved */
+-	__u8		length[3];		/* Block Length */
+-} idetape_parameter_block_descriptor_t;
+-
+-/*
+- *	The Data Compression Page, as returned by the MODE SENSE packet command.
+- */
+-typedef struct {
+-	unsigned	page_code	:6;	/* Page Code - Should be 0xf */
+-	unsigned	reserved0	:1;	/* Reserved */
+-	unsigned	ps		:1;
+-	__u8		page_length;		/* Page Length - Should be 14 */
+-	unsigned	reserved2	:6;	/* Reserved */
+-	unsigned	dcc		:1;	/* Data Compression Capable */
+-	unsigned	dce		:1;	/* Data Compression Enable */
+-	unsigned	reserved3	:5;	/* Reserved */
+-	unsigned	red		:2;	/* Report Exception on Decompression */
+-	unsigned	dde		:1;	/* Data Decompression Enable */
+-	__u32		ca;			/* Compression Algorithm */
+-	__u32		da;			/* Decompression Algorithm */
+-	__u8		reserved[4];		/* Reserved */
+-} idetape_data_compression_page_t;
+-
+-/*
+- *	The Medium Partition Page, as returned by the MODE SENSE packet command.
+- */
+-typedef struct {
+-	unsigned	page_code	:6;	/* Page Code - Should be 0x11 */
+-	unsigned	reserved1_6	:1;	/* Reserved */
+-	unsigned	ps		:1;
+-	__u8		page_length;		/* Page Length - Should be 6 */
+-	__u8		map;			/* Maximum Additional Partitions - Should be 0 */
+-	__u8		apd;			/* Additional Partitions Defined - Should be 0 */
+-	unsigned	reserved4_012	:3;	/* Reserved */
+-	unsigned	psum		:2;	/* Should be 0 */
+-	unsigned	idp		:1;	/* Should be 0 */
+-	unsigned	sdp		:1;	/* Should be 0 */
+-	unsigned	fdp		:1;	/* Fixed Data Partitions */
+-	__u8		mfr;			/* Medium Format Recognition */
+-	__u8		reserved[2];		/* Reserved */
+-} idetape_medium_partition_page_t;
+-
+-/*
+- *	Run time configurable parameters.
+- */
+-typedef struct {
+-	int	dsc_rw_frequency;
+-	int	dsc_media_access_frequency;
+-	int	nr_stages;
+-} idetape_config_t;
+ 
+ /*
+  *	The variables below are used for the character device interface.
+@@ -1320,14 +638,12 @@ static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigne
+ 	int count;
+ 
+ 	while (bcount) {
+-#if IDETAPE_DEBUG_BUGS
+ 		if (bh == NULL) {
+ 			printk(KERN_ERR "ide-tape: bh == NULL in "
+ 				"idetape_input_buffers\n");
+ 			idetape_discard_data(drive, bcount);
+ 			return;
+ 		}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 		count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), bcount);
+ 		HWIF(drive)->atapi_input_bytes(drive, bh->b_data + atomic_read(&bh->b_count), count);
+ 		bcount -= count;
+@@ -1347,13 +663,11 @@ static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsign
+ 	int count;
+ 
+ 	while (bcount) {
+-#if IDETAPE_DEBUG_BUGS
+ 		if (bh == NULL) {
+ 			printk(KERN_ERR "ide-tape: bh == NULL in "
+ 				"idetape_output_buffers\n");
+ 			return;
+ 		}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 		count = min((unsigned int)pc->b_count, (unsigned int)bcount);
+ 		HWIF(drive)->atapi_output_bytes(drive, pc->b_data, count);
+ 		bcount -= count;
+@@ -1378,13 +692,11 @@ static void idetape_update_buffers (idetape_pc_t *pc)
+ 	if (test_bit(PC_WRITING, &pc->flags))
+ 		return;
+ 	while (bcount) {
+-#if IDETAPE_DEBUG_BUGS
+ 		if (bh == NULL) {
+ 			printk(KERN_ERR "ide-tape: bh == NULL in "
+ 				"idetape_update_buffers\n");
+ 			return;
+ 		}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 		count = min((unsigned int)bh->b_size, (unsigned int)bcount);
+ 		atomic_set(&bh->b_count, count);
+ 		if (atomic_read(&bh->b_count) == bh->b_size)
+@@ -1457,36 +769,34 @@ static void idetape_init_pc (idetape_pc_t *pc)
+ }
+ 
+ /*
+- *	idetape_analyze_error is called on each failed packet command retry
+- *	to analyze the request sense. We currently do not utilize this
+- *	information.
++ * called on each failed packet command retry to analyze the request sense. We
++ * currently do not utilize this information.
+  */
+-static void idetape_analyze_error (ide_drive_t *drive, idetape_request_sense_result_t *result)
++static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
+ {
+ 	idetape_tape_t *tape = drive->driver_data;
+ 	idetape_pc_t *pc = tape->failed_pc;
+ 
+-	tape->sense     = *result;
+-	tape->sense_key = result->sense_key;
+-	tape->asc       = result->asc;
+-	tape->ascq      = result->ascq;
++	tape->sense_key = sense[2] & 0xF;
++	tape->asc       = sense[12];
++	tape->ascq      = sense[13];
+ #if IDETAPE_DEBUG_LOG
+ 	/*
+-	 *	Without debugging, we only log an error if we decided to
+-	 *	give up retrying.
++	 * Without debugging, we only log an error if we decided to give up
++	 * retrying.
+ 	 */
+ 	if (tape->debug_level >= 1)
+ 		printk(KERN_INFO "ide-tape: pc = %x, sense key = %x, "
+ 			"asc = %x, ascq = %x\n",
+-			pc->c[0], result->sense_key,
+-			result->asc, result->ascq);
++			pc->c[0], tape->sense_key,
++			tape->asc, tape->ascq);
+ #endif /* IDETAPE_DEBUG_LOG */
+ 
+-	/*
+-	 *	Correct pc->actually_transferred by asking the tape.
+-	 */
++	/* Correct pc->actually_transferred by asking the tape.	 */
+ 	if (test_bit(PC_DMA_ERROR, &pc->flags)) {
+-		pc->actually_transferred = pc->request_transfer - tape->tape_block_size * ntohl(get_unaligned(&result->information));
++		pc->actually_transferred = pc->request_transfer -
++			tape->tape_block_size *
++			be32_to_cpu(get_unaligned((u32 *)&sense[3]));
+ 		idetape_update_buffers(pc);
+ 	}
+ 
+@@ -1495,29 +805,29 @@ static void idetape_analyze_error (ide_drive_t *drive, idetape_request_sense_res
+ 	 * with sense key=5, asc=0x22, ascq=0, let it slide.  Some drives
+ 	 * (i.e. Seagate STT3401A Travan) don't support 0-length read/writes.
+ 	 */
+-	if ((pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD)
+-	    && pc->c[4] == 0 && pc->c[3] == 0 && pc->c[2] == 0) { /* length==0 */
+-		if (result->sense_key == 5) {
++	if ((pc->c[0] == READ_6 || pc->c[0] == WRITE_6)
++	    /* length == 0 */
++	    && pc->c[4] == 0 && pc->c[3] == 0 && pc->c[2] == 0) {
++		if (tape->sense_key == 5) {
+ 			/* don't report an error, everything's ok */
+ 			pc->error = 0;
+ 			/* don't retry read/write */
+ 			set_bit(PC_ABORT, &pc->flags);
+ 		}
+ 	}
+-	if (pc->c[0] == IDETAPE_READ_CMD && result->filemark) {
++	if (pc->c[0] == READ_6 && (sense[2] & 0x80)) {
+ 		pc->error = IDETAPE_ERROR_FILEMARK;
+ 		set_bit(PC_ABORT, &pc->flags);
+ 	}
+-	if (pc->c[0] == IDETAPE_WRITE_CMD) {
+-		if (result->eom ||
+-		    (result->sense_key == 0xd && result->asc == 0x0 &&
+-		     result->ascq == 0x2)) {
++	if (pc->c[0] == WRITE_6) {
++		if ((sense[2] & 0x40) || (tape->sense_key == 0xd
++		     && tape->asc == 0x0 && tape->ascq == 0x2)) {
+ 			pc->error = IDETAPE_ERROR_EOD;
+ 			set_bit(PC_ABORT, &pc->flags);
+ 		}
+ 	}
+-	if (pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD) {
+-		if (result->sense_key == 8) {
++	if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
++		if (tape->sense_key == 8) {
+ 			pc->error = IDETAPE_ERROR_EOD;
+ 			set_bit(PC_ABORT, &pc->flags);
+ 		}
+@@ -1527,10 +837,7 @@ static void idetape_analyze_error (ide_drive_t *drive, idetape_request_sense_res
+ 	}
+ }
+ 
+-/*
+- * idetape_active_next_stage will declare the next stage as "active".
+- */
+-static void idetape_active_next_stage (ide_drive_t *drive)
++static void idetape_activate_next_stage(ide_drive_t *drive)
+ {
+ 	idetape_tape_t *tape = drive->driver_data;
+ 	idetape_stage_t *stage = tape->next_stage;
+@@ -1540,12 +847,10 @@ static void idetape_active_next_stage (ide_drive_t *drive)
+ 	if (tape->debug_level >= 4)
+ 		printk(KERN_INFO "ide-tape: Reached idetape_active_next_stage\n");
+ #endif /* IDETAPE_DEBUG_LOG */
+-#if IDETAPE_DEBUG_BUGS
+ 	if (stage == NULL) {
+ 		printk(KERN_ERR "ide-tape: bug: Trying to activate a non existing stage\n");
+ 		return;
+ 	}
+-#endif /* IDETAPE_DEBUG_BUGS */	
+ 
+ 	rq->rq_disk = tape->disk;
+ 	rq->buffer = NULL;
+@@ -1620,28 +925,24 @@ static void idetape_remove_stage_head (ide_drive_t *drive)
+ 	if (tape->debug_level >= 4)
+ 		printk(KERN_INFO "ide-tape: Reached idetape_remove_stage_head\n");
+ #endif /* IDETAPE_DEBUG_LOG */
+-#if IDETAPE_DEBUG_BUGS
+ 	if (tape->first_stage == NULL) {
+ 		printk(KERN_ERR "ide-tape: bug: tape->first_stage is NULL\n");
+-		return;		
++		return;
+ 	}
+ 	if (tape->active_stage == tape->first_stage) {
+ 		printk(KERN_ERR "ide-tape: bug: Trying to free our active pipeline stage\n");
+ 		return;
+ 	}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 	stage = tape->first_stage;
+ 	tape->first_stage = stage->next;
+ 	idetape_kfree_stage(tape, stage);
+ 	tape->nr_stages--;
+ 	if (tape->first_stage == NULL) {
+ 		tape->last_stage = NULL;
+-#if IDETAPE_DEBUG_BUGS
+ 		if (tape->next_stage != NULL)
+ 			printk(KERN_ERR "ide-tape: bug: tape->next_stage != NULL\n");
+ 		if (tape->nr_stages)
+ 			printk(KERN_ERR "ide-tape: bug: nr_stages should be 0 now\n");
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 	}
+ }
+ 
+@@ -1700,6 +1001,11 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
  	if (error)
  		tape->failed_pc = NULL;
  
@@ -405294,7 +409534,34 @@
  	spin_lock_irqsave(&tape->spinlock, flags);
  
  	/* The request was a pipelined data transfer request */
-@@ -1818,9 +1812,8 @@ static ide_startstop_t idetape_retry_pc (ide_drive_t *drive)
+@@ -1722,7 +1028,7 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
+ 			}
+ 		}
+ 		if (tape->next_stage != NULL) {
+-			idetape_active_next_stage(drive);
++			idetape_activate_next_stage(drive);
+ 
+ 			/*
+ 			 * Insert the next request into the request queue.
+@@ -1754,7 +1060,7 @@ static ide_startstop_t idetape_request_sense_callback (ide_drive_t *drive)
+ 		printk(KERN_INFO "ide-tape: Reached idetape_request_sense_callback\n");
+ #endif /* IDETAPE_DEBUG_LOG */
+ 	if (!tape->pc->error) {
+-		idetape_analyze_error(drive, (idetape_request_sense_result_t *) tape->pc->buffer);
++		idetape_analyze_error(drive, tape->pc->buffer);
+ 		idetape_end_request(drive, 1, 0);
+ 	} else {
+ 		printk(KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n");
+@@ -1766,7 +1072,7 @@ static ide_startstop_t idetape_request_sense_callback (ide_drive_t *drive)
+ static void idetape_create_request_sense_cmd (idetape_pc_t *pc)
+ {
+ 	idetape_init_pc(pc);	
+-	pc->c[0] = IDETAPE_REQUEST_SENSE_CMD;
++	pc->c[0] = REQUEST_SENSE;
+ 	pc->c[4] = 20;
+ 	pc->request_transfer = 20;
+ 	pc->callback = &idetape_request_sense_callback;
+@@ -1818,9 +1124,8 @@ static ide_startstop_t idetape_retry_pc (ide_drive_t *drive)
  	idetape_tape_t *tape = drive->driver_data;
  	idetape_pc_t *pc;
  	struct request *rq;
@@ -405305,7 +409572,7 @@
  	pc = idetape_next_pc_storage(drive);
  	rq = idetape_next_rq_storage(drive);
  	idetape_create_request_sense_cmd(pc);
-@@ -1858,15 +1851,13 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
+@@ -1858,15 +1163,13 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
  {
  	ide_hwif_t *hwif = drive->hwif;
  	idetape_tape_t *tape = drive->driver_data;
@@ -405323,7 +409590,7 @@
  
  #if IDETAPE_DEBUG_LOG
  	if (tape->debug_level >= 4)
-@@ -1875,10 +1866,10 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
+@@ -1875,10 +1178,10 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
  #endif /* IDETAPE_DEBUG_LOG */	
  
  	/* Clear the interrupt */
@@ -405336,7 +409603,7 @@
  			/*
  			 * A DMA error is sometimes expected. For example,
  			 * if the tape is crossing a filemark during a
-@@ -1912,7 +1903,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
+@@ -1912,7 +1215,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
  	}
  
  	/* No more interrupts */
@@ -405345,7 +409612,13 @@
  #if IDETAPE_DEBUG_LOG
  		if (tape->debug_level >= 2)
  			printk(KERN_INFO "ide-tape: Packet command completed, %d bytes transferred\n", pc->actually_transferred);
-@@ -1927,12 +1918,13 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
+@@ -1922,23 +1225,23 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
+ 		local_irq_enable();
+ 
+ #if SIMULATE_ERRORS
+-		if ((pc->c[0] == IDETAPE_WRITE_CMD ||
+-		     pc->c[0] == IDETAPE_READ_CMD) &&
++		if ((pc->c[0] == WRITE_6 || pc->c[0] == READ_6) &&
  		    (++error_sim_count % 100) == 0) {
  			printk(KERN_INFO "ide-tape: %s: simulating error\n",
  				tape->name);
@@ -405356,14 +409629,21 @@
 -		if (status.b.check && pc->c[0] == IDETAPE_REQUEST_SENSE_CMD)
 -			status.b.check = 0;
 -		if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) {	/* Error detected */
-+		if ((stat & ERR_STAT) && pc->c[0] == IDETAPE_REQUEST_SENSE_CMD)
++		if ((stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE)
 +			stat &= ~ERR_STAT;
 +		if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) {
 +			/* Error detected */
  #if IDETAPE_DEBUG_LOG
  			if (tape->debug_level >= 1)
  				printk(KERN_INFO "ide-tape: %s: I/O error\n",
-@@ -1951,7 +1943,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
+ 					tape->name);
+ #endif /* IDETAPE_DEBUG_LOG */
+-			if (pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
++			if (pc->c[0] == REQUEST_SENSE) {
+ 				printk(KERN_ERR "ide-tape: I/O error in request sense command\n");
+ 				return ide_do_reset(drive);
+ 			}
+@@ -1951,7 +1254,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
  		}
  		pc->error = 0;
  		if (test_bit(PC_WAIT_FOR_DSC, &pc->flags) &&
@@ -405372,7 +409652,7 @@
  			/* Media access command */
  			tape->dsc_polling_start = jiffies;
  			tape->dsc_polling_frequency = IDETAPE_DSC_MA_FAST;
-@@ -1973,30 +1965,30 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
+@@ -1973,30 +1276,30 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
  		return ide_do_reset(drive);
  	}
  	/* Get the number of bytes to transfer on this interrupt. */
@@ -405412,7 +409692,7 @@
  				ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
  				return ide_started;
  			}
-@@ -2008,23 +2000,26 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
+@@ -2008,23 +1311,26 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
  	}
  	if (test_bit(PC_WRITING, &pc->flags)) {
  		if (pc->bh != NULL)
@@ -405446,7 +409726,7 @@
  #endif
  	/* And set the interrupt handler again */
  	ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
-@@ -2078,28 +2073,28 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
+@@ -2078,28 +1384,28 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
  	ide_hwif_t *hwif = drive->hwif;
  	idetape_tape_t *tape = drive->driver_data;
  	idetape_pc_t *pc = tape->pc;
@@ -405482,7 +409762,7 @@
  		printk(KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing "
  				"a packet command\n");
  		return ide_do_reset(drive);
-@@ -2120,8 +2115,8 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
+@@ -2120,18 +1426,16 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
  {
  	ide_hwif_t *hwif = drive->hwif;
  	idetape_tape_t *tape = drive->driver_data;
@@ -405490,9 +409770,31 @@
  	int dma_ok = 0;
 +	u16 bcount;
  
- #if IDETAPE_DEBUG_BUGS
- 	if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD &&
-@@ -2170,7 +2165,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
+-#if IDETAPE_DEBUG_BUGS
+-	if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD &&
+-	    pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
++	if (tape->pc->c[0] == REQUEST_SENSE &&
++	    pc->c[0] == REQUEST_SENSE) {
+ 		printk(KERN_ERR "ide-tape: possible ide-tape.c bug - "
+ 			"Two request sense in serial were issued\n");
+ 	}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 
+-	if (tape->failed_pc == NULL && pc->c[0] != IDETAPE_REQUEST_SENSE_CMD)
++	if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
+ 		tape->failed_pc = pc;
+ 	/* Set the current packet command */
+ 	tape->pc = pc;
+@@ -2144,7 +1448,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
+ 		 *	filemark, or end of the media, for example).
+ 		 */
+ 		if (!test_bit(PC_ABORT, &pc->flags)) {
+-			if (!(pc->c[0] == IDETAPE_TEST_UNIT_READY_CMD &&
++			if (!(pc->c[0] == TEST_UNIT_READY &&
+ 			      tape->sense_key == 2 && tape->asc == 4 &&
+ 			     (tape->ascq == 1 || tape->ascq == 8))) {
+ 				printk(KERN_ERR "ide-tape: %s: I/O error, "
+@@ -2170,7 +1474,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
  	pc->actually_transferred = 0;
  	pc->current_position = pc->buffer;
  	/* Request to transfer the entire buffer at once */
@@ -405501,7 +409803,7 @@
  
  	if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
  		printk(KERN_WARNING "ide-tape: DMA disabled, "
-@@ -2180,12 +2175,9 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
+@@ -2180,17 +1484,14 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
  	if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
  		dma_ok = !hwif->dma_setup(drive);
  
@@ -405517,7 +409819,23 @@
  	if (dma_ok)			/* Will begin DMA later */
  		set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
  	if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
-@@ -2295,11 +2287,11 @@ static ide_startstop_t idetape_media_access_finished (ide_drive_t *drive)
+-		ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
+-		hwif->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG);
++		ide_execute_command(drive, WIN_PACKETCMD, &idetape_transfer_pc,
++				    IDETAPE_WAIT_CMD, NULL);
+ 		return ide_started;
+ 	} else {
+ 		hwif->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG);
+@@ -2220,7 +1521,7 @@ static ide_startstop_t idetape_pc_callback (ide_drive_t *drive)
+ static void idetape_create_mode_sense_cmd (idetape_pc_t *pc, u8 page_code)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_MODE_SENSE_CMD;
++	pc->c[0] = MODE_SENSE;
+ 	if (page_code != IDETAPE_BLOCK_DESCRIPTOR)
+ 		pc->c[1] = 8;	/* DBD = 1 - Don't return block descriptors */
+ 	pc->c[2] = page_code;
+@@ -2295,13 +1596,13 @@ static ide_startstop_t idetape_media_access_finished (ide_drive_t *drive)
  {
  	idetape_tape_t *tape = drive->driver_data;
  	idetape_pc_t *pc = tape->pc;
@@ -405531,9 +409849,43 @@
 +	if (stat & SEEK_STAT) {
 +		if (stat & ERR_STAT) {
  			/* Error detected */
- 			if (pc->c[0] != IDETAPE_TEST_UNIT_READY_CMD)
+-			if (pc->c[0] != IDETAPE_TEST_UNIT_READY_CMD)
++			if (pc->c[0] != TEST_UNIT_READY)
  				printk(KERN_ERR "ide-tape: %s: I/O error, ",
-@@ -2417,7 +2409,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
+ 						tape->name);
+ 			/* Retry operation */
+@@ -2358,8 +1659,8 @@ static ide_startstop_t idetape_rw_callback (ide_drive_t *drive)
+ static void idetape_create_read_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct idetape_bh *bh)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_READ_CMD;
+-	put_unaligned(htonl(length), (unsigned int *) &pc->c[1]);
++	pc->c[0] = READ_6;
++	put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
+ 	pc->c[1] = 1;
+ 	pc->callback = &idetape_rw_callback;
+ 	pc->bh = bh;
+@@ -2376,7 +1677,7 @@ static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, idetape_pc_t *p
+ 	struct idetape_bh *p = bh;
+ 
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_READ_BUFFER_CMD;
++	pc->c[0] = READ_BUFFER;
+ 	pc->c[1] = IDETAPE_RETRIEVE_FAULTY_BLOCK;
+ 	pc->c[7] = size >> 8;
+ 	pc->c[8] = size & 0xff;
+@@ -2394,8 +1695,8 @@ static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, idetape_pc_t *p
+ static void idetape_create_write_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct idetape_bh *bh)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_WRITE_CMD;
+-	put_unaligned(htonl(length), (unsigned int *) &pc->c[1]);
++	pc->c[0] = WRITE_6;
++	put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
+ 	pc->c[1] = 1;
+ 	pc->callback = &idetape_rw_callback;
+ 	set_bit(PC_WRITING, &pc->flags);
+@@ -2417,15 +1718,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
  	idetape_tape_t *tape = drive->driver_data;
  	idetape_pc_t *pc = NULL;
  	struct request *postponed_rq = tape->postponed_rq;
@@ -405541,8 +409893,36 @@
 +	u8 stat;
  
  #if IDETAPE_DEBUG_LOG
- #if 0
-@@ -2465,7 +2457,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
+-#if 0
+-	if (tape->debug_level >= 5)
+-		printk(KERN_INFO "ide-tape:  %d, "
+-			"dev: %s, cmd: %ld, errors: %d\n",
+-			 rq->rq_disk->disk_name, rq->cmd[0], rq->errors);
+-#endif
+ 	if (tape->debug_level >= 2)
+ 		printk(KERN_INFO "ide-tape: sector: %ld, "
+ 			"nr_sectors: %ld, current_nr_sectors: %d\n",
+@@ -2446,10 +1741,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
+ 	 *	Retry a failed packet command
+ 	 */
+ 	if (tape->failed_pc != NULL &&
+-	    tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
++	    tape->pc->c[0] == REQUEST_SENSE) {
+ 		return idetape_issue_packet_command(drive, tape->failed_pc);
+ 	}
+-#if IDETAPE_DEBUG_BUGS
+ 	if (postponed_rq != NULL)
+ 		if (rq != postponed_rq) {
+ 			printk(KERN_ERR "ide-tape: ide-tape.c bug - "
+@@ -2457,7 +1751,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
+ 			idetape_end_request(drive, 0, 0);
+ 			return ide_stopped;
+ 		}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 
+ 	tape->postponed_rq = NULL;
+ 
+@@ -2465,7 +1758,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
  	 * If the tape is still busy, postpone our request and service
  	 * the other device meanwhile.
  	 */
@@ -405551,7 +409931,7 @@
  
  	if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2))
  		set_bit(IDETAPE_IGNORE_DSC, &tape->flags);
-@@ -2481,7 +2473,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
+@@ -2481,7 +1774,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
  		tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time);
  	calculate_speeds(drive);
  	if (!test_and_clear_bit(IDETAPE_IGNORE_DSC, &tape->flags) &&
@@ -405560,7 +409940,7 @@
  		if (postponed_rq == NULL) {
  			tape->dsc_polling_start = jiffies;
  			tape->dsc_polling_frequency = tape->best_dsc_rw_frequency;
-@@ -2502,9 +2494,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
+@@ -2502,9 +1795,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
  	}
  	if (rq->cmd[0] & REQ_IDETAPE_READ) {
  		tape->buffer_head++;
@@ -405570,7 +409950,7 @@
  		tape->postpone_cnt = 0;
  		pc = idetape_next_pc_storage(drive);
  		idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
-@@ -2512,9 +2501,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
+@@ -2512,9 +1802,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
  	}
  	if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
  		tape->buffer_head++;
@@ -405580,7 +409960,184 @@
  		tape->postpone_cnt = 0;
  		pc = idetape_next_pc_storage(drive);
  		idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
-@@ -3241,9 +3227,6 @@ static int idetape_add_chrdev_write_request (ide_drive_t *drive, int blocks)
+@@ -2650,13 +1937,11 @@ static int idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *
+ 	int ret = 0;
+ 
+ 	while (n) {
+-#if IDETAPE_DEBUG_BUGS
+ 		if (bh == NULL) {
+ 			printk(KERN_ERR "ide-tape: bh == NULL in "
+ 				"idetape_copy_stage_from_user\n");
+ 			return 1;
+ 		}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 		count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), (unsigned int)n);
+ 		if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, count))
+ 			ret = 1;
+@@ -2680,13 +1965,11 @@ static int idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, i
+ 	int ret = 0;
+ 
+ 	while (n) {
+-#if IDETAPE_DEBUG_BUGS
+ 		if (bh == NULL) {
+ 			printk(KERN_ERR "ide-tape: bh == NULL in "
+ 				"idetape_copy_stage_to_user\n");
+ 			return 1;
+ 		}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 		count = min(tape->b_count, n);
+ 		if  (copy_to_user(buf, tape->b_data, count))
+ 			ret = 1;
+@@ -2766,12 +2049,10 @@ static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq)
+ 	DECLARE_COMPLETION_ONSTACK(wait);
+ 	idetape_tape_t *tape = drive->driver_data;
+ 
+-#if IDETAPE_DEBUG_BUGS
+ 	if (rq == NULL || !blk_special_request(rq)) {
+ 		printk (KERN_ERR "ide-tape: bug: Trying to sleep on non-valid request\n");
+ 		return;
+ 	}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 	rq->end_io_data = &wait;
+ 	rq->end_io = blk_end_sync_rq;
+ 	spin_unlock_irq(&tape->spinlock);
+@@ -2831,7 +2112,7 @@ static ide_startstop_t idetape_read_position_callback (ide_drive_t *drive)
+ static void idetape_create_write_filemark_cmd (ide_drive_t *drive, idetape_pc_t *pc,int write_filemark)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_WRITE_FILEMARK_CMD;
++	pc->c[0] = WRITE_FILEMARKS;
+ 	pc->c[4] = write_filemark;
+ 	set_bit(PC_WAIT_FOR_DSC, &pc->flags);
+ 	pc->callback = &idetape_pc_callback;
+@@ -2840,7 +2121,7 @@ static void idetape_create_write_filemark_cmd (ide_drive_t *drive, idetape_pc_t
+ static void idetape_create_test_unit_ready_cmd(idetape_pc_t *pc)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_TEST_UNIT_READY_CMD;
++	pc->c[0] = TEST_UNIT_READY;
+ 	pc->callback = &idetape_pc_callback;
+ }
+ 
+@@ -2878,7 +2159,7 @@ static int __idetape_queue_pc_tail (ide_drive_t *drive, idetape_pc_t *pc)
+ static void idetape_create_load_unload_cmd (ide_drive_t *drive, idetape_pc_t *pc,int cmd)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_LOAD_UNLOAD_CMD;
++	pc->c[0] = START_STOP;
+ 	pc->c[4] = cmd;
+ 	set_bit(PC_WAIT_FOR_DSC, &pc->flags);
+ 	pc->callback = &idetape_pc_callback;
+@@ -2935,7 +2216,7 @@ static int idetape_flush_tape_buffers (ide_drive_t *drive)
+ static void idetape_create_read_position_cmd (idetape_pc_t *pc)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_READ_POSITION_CMD;
++	pc->c[0] = READ_POSITION;
+ 	pc->request_transfer = 20;
+ 	pc->callback = &idetape_read_position_callback;
+ }
+@@ -2961,9 +2242,9 @@ static int idetape_read_position (ide_drive_t *drive)
+ static void idetape_create_locate_cmd (ide_drive_t *drive, idetape_pc_t *pc, unsigned int block, u8 partition, int skip)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_LOCATE_CMD;
++	pc->c[0] = POSITION_TO_ELEMENT;
+ 	pc->c[1] = 2;
+-	put_unaligned(htonl(block), (unsigned int *) &pc->c[3]);
++	put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]);
+ 	pc->c[8] = partition;
+ 	set_bit(PC_WAIT_FOR_DSC, &pc->flags);
+ 	pc->callback = &idetape_pc_callback;
+@@ -2973,11 +2254,12 @@ static int idetape_create_prevent_cmd (ide_drive_t *drive, idetape_pc_t *pc, int
+ {
+ 	idetape_tape_t *tape = drive->driver_data;
+ 
+-	if (!tape->capabilities.lock)
++	/* device supports locking according to capabilities page */
++	if (!(tape->caps[6] & 0x01))
+ 		return 0;
+ 
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_PREVENT_CMD;
++	pc->c[0] = ALLOW_MEDIUM_REMOVAL;
+ 	pc->c[4] = prevent;
+ 	pc->callback = &idetape_pc_callback;
+ 	return 1;
+@@ -3086,12 +2368,10 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct
+ 	if (tape->debug_level >= 2)
+ 		printk(KERN_INFO "ide-tape: idetape_queue_rw_tail: cmd=%d\n",cmd);
+ #endif /* IDETAPE_DEBUG_LOG */
+-#if IDETAPE_DEBUG_BUGS
+ 	if (idetape_pipeline_active(tape)) {
+ 		printk(KERN_ERR "ide-tape: bug: the pipeline is active in idetape_queue_rw_tail\n");
+ 		return (0);
+ 	}
+-#endif /* IDETAPE_DEBUG_BUGS */	
+ 
+ 	idetape_init_rq(&rq, cmd);
+ 	rq.rq_disk = tape->disk;
+@@ -3122,7 +2402,7 @@ static void idetape_insert_pipeline_into_queue (ide_drive_t *drive)
+ 		return;
+ 	if (!idetape_pipeline_active(tape)) {
+ 		set_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags);
+-		idetape_active_next_stage(drive);
++		idetape_activate_next_stage(drive);
+ 		(void) ide_do_drive_cmd(drive, tape->active_data_request, ide_end);
+ 	}
+ }
+@@ -3130,7 +2410,7 @@ static void idetape_insert_pipeline_into_queue (ide_drive_t *drive)
+ static void idetape_create_inquiry_cmd (idetape_pc_t *pc)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_INQUIRY_CMD;
++	pc->c[0] = INQUIRY;
+ 	pc->c[4] = pc->request_transfer = 254;
+ 	pc->callback = &idetape_pc_callback;
+ }
+@@ -3138,28 +2418,15 @@ static void idetape_create_inquiry_cmd (idetape_pc_t *pc)
+ static void idetape_create_rewind_cmd (ide_drive_t *drive, idetape_pc_t *pc)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_REWIND_CMD;
++	pc->c[0] = REZERO_UNIT;
+ 	set_bit(PC_WAIT_FOR_DSC, &pc->flags);
+ 	pc->callback = &idetape_pc_callback;
+ }
+ 
+-#if 0
+-static void idetape_create_mode_select_cmd (idetape_pc_t *pc, int length)
+-{
+-	idetape_init_pc(pc);
+-	set_bit(PC_WRITING, &pc->flags);
+-	pc->c[0] = IDETAPE_MODE_SELECT_CMD;
+-	pc->c[1] = 0x10;
+-	put_unaligned(htons(length), (unsigned short *) &pc->c[3]);
+-	pc->request_transfer = 255;
+-	pc->callback = &idetape_pc_callback;
+-}
+-#endif
+-
+ static void idetape_create_erase_cmd (idetape_pc_t *pc)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_ERASE_CMD;
++	pc->c[0] = ERASE;
+ 	pc->c[1] = 1;
+ 	set_bit(PC_WAIT_FOR_DSC, &pc->flags);
+ 	pc->callback = &idetape_pc_callback;
+@@ -3168,8 +2435,8 @@ static void idetape_create_erase_cmd (idetape_pc_t *pc)
+ static void idetape_create_space_cmd (idetape_pc_t *pc,int count, u8 cmd)
+ {
+ 	idetape_init_pc(pc);
+-	pc->c[0] = IDETAPE_SPACE_CMD;
+-	put_unaligned(htonl(count), (unsigned int *) &pc->c[1]);
++	pc->c[0] = SPACE;
++	put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]);
+ 	pc->c[1] = cmd;
+ 	set_bit(PC_WAIT_FOR_DSC, &pc->flags);
+ 	pc->callback = &idetape_pc_callback;
+@@ -3241,9 +2508,6 @@ static int idetape_add_chrdev_write_request (ide_drive_t *drive, int blocks)
  	idetape_switch_buffers(tape, new_stage);
  	idetape_add_stage_tail(drive, new_stage);
  	tape->pipeline_head++;
@@ -405590,7 +410147,63 @@
  	calculate_speeds(drive);
  
  	/*
-@@ -3493,9 +3476,6 @@ static int idetape_add_chrdev_read_request (ide_drive_t *drive,int blocks)
+@@ -3292,8 +2556,7 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
+ 	idetape_tape_t *tape = drive->driver_data;
+ 	int blocks, min;
+ 	struct idetape_bh *bh;
+-	
+-#if IDETAPE_DEBUG_BUGS
++
+ 	if (tape->chrdev_direction != idetape_direction_write) {
+ 		printk(KERN_ERR "ide-tape: bug: Trying to empty write pipeline, but we are not writing.\n");
+ 		return;
+@@ -3302,7 +2565,6 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
+ 		printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n");
+ 		tape->merge_stage_size = tape->stage_size;
+ 	}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 	if (tape->merge_stage_size) {
+ 		blocks = tape->merge_stage_size / tape->tape_block_size;
+ 		if (tape->merge_stage_size % tape->tape_block_size) {
+@@ -3347,7 +2609,6 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
+ 	 *	 can be totally different on the next backup).
+ 	 */
+ 	tape->max_stages = tape->min_pipeline;
+-#if IDETAPE_DEBUG_BUGS
+ 	if (tape->first_stage != NULL ||
+ 	    tape->next_stage != NULL ||
+ 	    tape->last_stage != NULL ||
+@@ -3358,7 +2619,6 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive)
+ 			tape->first_stage, tape->next_stage,
+ 			tape->last_stage, tape->nr_stages);
+ 	}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ }
+ 
+ static void idetape_restart_speed_control (ide_drive_t *drive)
+@@ -3381,7 +2641,7 @@ static int idetape_initiate_read (ide_drive_t *drive, int max_stages)
+ 	idetape_stage_t *new_stage;
+ 	struct request rq;
+ 	int bytes_read;
+-	int blocks = tape->capabilities.ctl;
++	u16 blocks = *(u16 *)&tape->caps[12];
+ 
+ 	/* Initialize read operation */
+ 	if (tape->chrdev_direction != idetape_direction_read) {
+@@ -3389,12 +2649,10 @@ static int idetape_initiate_read (ide_drive_t *drive, int max_stages)
+ 			idetape_empty_write_pipeline(drive);
+ 			idetape_flush_tape_buffers(drive);
+ 		}
+-#if IDETAPE_DEBUG_BUGS
+ 		if (tape->merge_stage || tape->merge_stage_size) {
+ 			printk (KERN_ERR "ide-tape: merge_stage_size should be 0 now\n");
+ 			tape->merge_stage_size = 0;
+ 		}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 		if ((tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0)) == NULL)
+ 			return -ENOMEM;
+ 		tape->chrdev_direction = idetape_direction_read;
+@@ -3493,17 +2751,12 @@ static int idetape_add_chrdev_read_request (ide_drive_t *drive,int blocks)
  		idetape_remove_stage_head(drive);
  		spin_unlock_irqrestore(&tape->spinlock, flags);
  		tape->pipeline_head++;
@@ -405599,8 +410212,307 @@
 -#endif
  		calculate_speeds(drive);
  	}
- #if IDETAPE_DEBUG_BUGS
-@@ -4310,9 +4290,6 @@ static int idetape_identify_device (ide_drive_t *drive)
+-#if IDETAPE_DEBUG_BUGS
+ 	if (bytes_read > blocks * tape->tape_block_size) {
+ 		printk(KERN_ERR "ide-tape: bug: trying to return more bytes than requested\n");
+ 		bytes_read = blocks * tape->tape_block_size;
+ 	}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 	return (bytes_read);
+ }
+ 
+@@ -3587,16 +2840,21 @@ static int idetape_rewind_tape (ide_drive_t *drive)
+ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned long arg)
+ {
+ 	idetape_tape_t *tape = drive->driver_data;
+-	idetape_config_t config;
+ 	void __user *argp = (void __user *)arg;
+ 
++	struct idetape_config {
++		int dsc_rw_frequency;
++		int dsc_media_access_frequency;
++		int nr_stages;
++	} config;
++
+ #if IDETAPE_DEBUG_LOG	
+ 	if (tape->debug_level >= 4)
+ 		printk(KERN_INFO "ide-tape: Reached idetape_blkdev_ioctl\n");
+ #endif /* IDETAPE_DEBUG_LOG */
+ 	switch (cmd) {
+ 		case 0x0340:
+-			if (copy_from_user(&config, argp, sizeof (idetape_config_t)))
++			if (copy_from_user(&config, argp, sizeof(config)))
+ 				return -EFAULT;
+ 			tape->best_dsc_rw_frequency = config.dsc_rw_frequency;
+ 			tape->max_stages = config.nr_stages;
+@@ -3604,7 +2862,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned l
+ 		case 0x0350:
+ 			config.dsc_rw_frequency = (int) tape->best_dsc_rw_frequency;
+ 			config.nr_stages = tape->max_stages; 
+-			if (copy_to_user(argp, &config, sizeof (idetape_config_t)))
++			if (copy_to_user(argp, &config, sizeof(config)))
+ 				return -EFAULT;
+ 			break;
+ 		default:
+@@ -3628,11 +2886,12 @@ static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_c
+ 	idetape_pc_t pc;
+ 	unsigned long flags;
+ 	int retval,count=0;
++	int sprev = !!(tape->caps[4] & 0x20);
+ 
+ 	if (mt_count == 0)
+ 		return 0;
+ 	if (MTBSF == mt_op || MTBSFM == mt_op) {
+-		if (!tape->capabilities.sprev)
++		if (!sprev)
+ 			return -EIO;
+ 		mt_count = - mt_count;
+ 	}
+@@ -3686,7 +2945,7 @@ static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_c
+ 			return (idetape_queue_pc_tail(drive, &pc));
+ 		case MTFSFM:
+ 		case MTBSFM:
+-			if (!tape->capabilities.sprev)
++			if (!sprev)
+ 				return (-EIO);
+ 			retval = idetape_space_over_filemarks(drive, MTFSF, mt_count-count);
+ 			if (retval) return (retval);
+@@ -3723,6 +2982,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf,
+ 	ide_drive_t *drive = tape->drive;
+ 	ssize_t bytes_read,temp, actually_read = 0, rc;
+ 	ssize_t ret = 0;
++	u16 ctl = *(u16 *)&tape->caps[12];
+ 
+ #if IDETAPE_DEBUG_LOG
+ 	if (tape->debug_level >= 3)
+@@ -3748,7 +3008,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf,
+ 		count -= actually_read;
+ 	}
+ 	while (count >= tape->stage_size) {
+-		bytes_read = idetape_add_chrdev_read_request(drive, tape->capabilities.ctl);
++		bytes_read = idetape_add_chrdev_read_request(drive, ctl);
+ 		if (bytes_read <= 0)
+ 			goto finish;
+ 		if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, bytes_read))
+@@ -3758,7 +3018,7 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf,
+ 		actually_read += bytes_read;
+ 	}
+ 	if (count) {
+-		bytes_read = idetape_add_chrdev_read_request(drive, tape->capabilities.ctl);
++		bytes_read = idetape_add_chrdev_read_request(drive, ctl);
+ 		if (bytes_read <= 0)
+ 			goto finish;
+ 		temp = min((unsigned long)count, (unsigned long)bytes_read);
+@@ -3787,6 +3047,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
+ 	ide_drive_t *drive = tape->drive;
+ 	ssize_t actually_written = 0;
+ 	ssize_t ret = 0;
++	u16 ctl = *(u16 *)&tape->caps[12];
+ 
+ 	/* The drive is write protected. */
+ 	if (tape->write_prot)
+@@ -3802,13 +3063,11 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
+ 	if (tape->chrdev_direction != idetape_direction_write) {
+ 		if (tape->chrdev_direction == idetape_direction_read)
+ 			idetape_discard_read_pipeline(drive, 1);
+-#if IDETAPE_DEBUG_BUGS
+ 		if (tape->merge_stage || tape->merge_stage_size) {
+ 			printk(KERN_ERR "ide-tape: merge_stage_size "
+ 				"should be 0 now\n");
+ 			tape->merge_stage_size = 0;
+ 		}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 		if ((tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0)) == NULL)
+ 			return -ENOMEM;
+ 		tape->chrdev_direction = idetape_direction_write;
+@@ -3836,12 +3095,10 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
+ 	if (tape->restart_speed_control_req)
+ 		idetape_restart_speed_control(drive);
+ 	if (tape->merge_stage_size) {
+-#if IDETAPE_DEBUG_BUGS
+ 		if (tape->merge_stage_size >= tape->stage_size) {
+ 			printk(KERN_ERR "ide-tape: bug: merge buffer too big\n");
+ 			tape->merge_stage_size = 0;
+ 		}
+-#endif /* IDETAPE_DEBUG_BUGS */
+ 		actually_written = min((unsigned int)(tape->stage_size - tape->merge_stage_size), (unsigned int)count);
+ 		if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, actually_written))
+ 				ret = -EFAULT;
+@@ -3852,7 +3109,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
+ 		if (tape->merge_stage_size == tape->stage_size) {
+ 			ssize_t retval;
+ 			tape->merge_stage_size = 0;
+-			retval = idetape_add_chrdev_write_request(drive, tape->capabilities.ctl);
++			retval = idetape_add_chrdev_write_request(drive, ctl);
+ 			if (retval <= 0)
+ 				return (retval);
+ 		}
+@@ -3863,7 +3120,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
+ 			ret = -EFAULT;
+ 		buf += tape->stage_size;
+ 		count -= tape->stage_size;
+-		retval = idetape_add_chrdev_write_request(drive, tape->capabilities.ctl);
++		retval = idetape_add_chrdev_write_request(drive, ctl);
+ 		actually_written += tape->stage_size;
+ 		if (retval <= 0)
+ 			return (retval);
+@@ -3891,69 +3148,20 @@ static int idetape_write_filemark (ide_drive_t *drive)
+ }
+ 
+ /*
+- *	idetape_mtioctop is called from idetape_chrdev_ioctl when
+- *	the general mtio MTIOCTOP ioctl is requested.
+- *
+- *	We currently support the following mtio.h operations:
+- *
+- *	MTFSF	-	Space over mt_count filemarks in the positive direction.
+- *			The tape is positioned after the last spaced filemark.
+- *
+- *	MTFSFM	-	Same as MTFSF, but the tape is positioned before the
+- *			last filemark.
+- *
+- *	MTBSF	-	Steps background over mt_count filemarks, tape is
+- *			positioned before the last filemark.
++ * Called from idetape_chrdev_ioctl when the general mtio MTIOCTOP ioctl is
++ * requested.
+  *
+- *	MTBSFM	-	Like MTBSF, only tape is positioned after the last filemark.
++ * Note: MTBSF and MTBSFM are not supported when the tape doesn't support
++ * spacing over filemarks in the reverse direction. In this case, MTFSFM is also
++ * usually not supported (it is supported in the rare case in which we crossed
++ * the filemark during our read-ahead pipelined operation mode).
+  *
+- *	Note:
++ * The following commands are currently not supported:
+  *
+- *		MTBSF and MTBSFM are not supported when the tape doesn't
+- *		support spacing over filemarks in the reverse direction.
+- *		In this case, MTFSFM is also usually not supported (it is
+- *		supported in the rare case in which we crossed the filemark
+- *		during our read-ahead pipelined operation mode).
+- *		
+- *	MTWEOF	-	Writes mt_count filemarks. Tape is positioned after
+- *			the last written filemark.
+- *
+- *	MTREW	-	Rewinds tape.
+- *
+- *	MTLOAD	-	Loads the tape.
+- *
+- *	MTOFFL	-	Puts the tape drive "Offline": Rewinds the tape and
+- *	MTUNLOAD	prevents further access until the media is replaced.
+- *
+- *	MTNOP	-	Flushes tape buffers.
+- *
+- *	MTRETEN	-	Retension media. This typically consists of one end
+- *			to end pass on the media.
+- *
+- *	MTEOM	-	Moves to the end of recorded data.
+- *
+- *	MTERASE	-	Erases tape.
+- *
+- *	MTSETBLK - 	Sets the user block size to mt_count bytes. If
+- *			mt_count is 0, we will attempt to autodetect
+- *			the block size.
+- *
+- *	MTSEEK	-	Positions the tape in a specific block number, where
+- *			each block is assumed to contain which user_block_size
+- *			bytes.
+- *
+- *	MTSETPART - 	Switches to another tape partition.
+- *
+- *	MTLOCK - 	Locks the tape door.
+- *
+- *	MTUNLOCK - 	Unlocks the tape door.
+- *
+- *	The following commands are currently not supported:
+- *
+- *	MTFSS, MTBSS, MTWSM, MTSETDENSITY,
+- *	MTSETDRVBUFFER, MT_ST_BOOLEANS, MT_ST_WRITE_THRESHOLD.
++ * MTFSS, MTBSS, MTWSM, MTSETDENSITY, MTSETDRVBUFFER, MT_ST_BOOLEANS,
++ * MT_ST_WRITE_THRESHOLD.
+  */
+-static int idetape_mtioctop (ide_drive_t *drive,short mt_op,int mt_count)
++static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
+ {
+ 	idetape_tape_t *tape = drive->driver_data;
+ 	idetape_pc_t pc;
+@@ -4068,29 +3276,12 @@ static int idetape_mtioctop (ide_drive_t *drive,short mt_op,int mt_count)
+ }
+ 
+ /*
+- *	Our character device ioctls.
+- *
+- *	General mtio.h magnetic io commands are supported here, and not in
+- *	the corresponding block interface.
+- *
+- *	The following ioctls are supported:
+- *
+- *	MTIOCTOP -	Refer to idetape_mtioctop for detailed description.
+- *
+- *	MTIOCGET - 	The mt_dsreg field in the returned mtget structure
+- *			will be set to (user block size in bytes <<
+- *			MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK.
+- *
+- *			The mt_blkno is set to the current user block number.
+- *			The other mtget fields are not supported.
+- *
+- *	MTIOCPOS -	The current tape "block position" is returned. We
+- *			assume that each block contains user_block_size
+- *			bytes.
+- *
+- *	Our own ide-tape ioctls are supported on both interfaces.
++ * Our character device ioctls. General mtio.h magnetic io commands are
++ * supported here, and not in the corresponding block interface. Our own
++ * ide-tape ioctls are supported on both interfaces.
+  */
+-static int idetape_chrdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
++				unsigned int cmd, unsigned long arg)
+ {
+ 	struct ide_tape_obj *tape = ide_tape_f(file);
+ 	ide_drive_t *drive = tape->drive;
+@@ -4144,7 +3335,30 @@ static int idetape_chrdev_ioctl (struct inode *inode, struct file *file, unsigne
+ 	}
+ }
+ 
+-static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive);
++/*
++ * Do a mode sense page 0 with block descriptor and if it succeeds set the tape
++ * block size with the reported value.
++ */
++static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
++{
++	idetape_tape_t *tape = drive->driver_data;
++	idetape_pc_t pc;
++
++	idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR);
++	if (idetape_queue_pc_tail(drive, &pc)) {
++		printk(KERN_ERR "ide-tape: Can't get block descriptor\n");
++		if (tape->tape_block_size == 0) {
++			printk(KERN_WARNING "ide-tape: Cannot deal with zero "
++					    "block size, assuming 32k\n");
++			tape->tape_block_size = 32768;
++		}
++		return;
++	}
++	tape->tape_block_size = (pc.buffer[4 + 5] << 16) +
++				(pc.buffer[4 + 6] << 8)  +
++				 pc.buffer[4 + 7];
++	tape->drv_write_prot = (pc.buffer[2] & 0x80) >> 7;
++}
+ 
+ /*
+  *	Our character device open function.
+@@ -4198,7 +3412,7 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp)
+ 		clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
+ 
+ 	/* Read block size and write protect status from drive. */
+-	idetape_get_blocksize_from_block_descriptor(drive);
++	ide_tape_get_bsize_from_bdesc(drive);
+ 
+ 	/* Set write protect flag if device is opened as read-only. */
+ 	if ((filp->f_flags & O_ACCMODE) == O_RDONLY)
+@@ -4310,255 +3524,106 @@ static int idetape_identify_device (ide_drive_t *drive)
  {
  	struct idetape_id_gcw gcw;
  	struct hd_driveid *id = drive->id;
@@ -405610,10 +410522,42 @@
  
  	if (drive->id_read == 0)
  		return 1;
-@@ -4352,62 +4329,6 @@ static int idetape_identify_device (ide_drive_t *drive)
- 		case 1: printk("16 bytes\n");break;
- 		default: printk("Reserved\n");break;
- 	}
+ 
+ 	*((unsigned short *) &gcw) = id->config;
+ 
+-#if IDETAPE_DEBUG_INFO
+-	printk(KERN_INFO "ide-tape: Dumping ATAPI Identify Device tape parameters\n");
+-	printk(KERN_INFO "ide-tape: Protocol Type: ");
+-	switch (gcw.protocol) {
+-		case 0: case 1: printk("ATA\n");break;
+-		case 2:	printk("ATAPI\n");break;
+-		case 3: printk("Reserved (Unknown to ide-tape)\n");break;
+-	}
+-	printk(KERN_INFO "ide-tape: Device Type: %x - ",gcw.device_type);	
+-	switch (gcw.device_type) {
+-		case 0: printk("Direct-access Device\n");break;
+-		case 1: printk("Streaming Tape Device\n");break;
+-		case 2: case 3: case 4: printk("Reserved\n");break;
+-		case 5: printk("CD-ROM Device\n");break;
+-		case 6: printk("Reserved\n");
+-		case 7: printk("Optical memory Device\n");break;
+-		case 0x1f: printk("Unknown or no Device type\n");break;
+-		default: printk("Reserved\n");
+-	}
+-	printk(KERN_INFO "ide-tape: Removable: %s",gcw.removable ? "Yes\n":"No\n");	
+-	printk(KERN_INFO "ide-tape: Command Packet DRQ Type: ");
+-	switch (gcw.drq_type) {
+-		case 0: printk("Microprocessor DRQ\n");break;
+-		case 1: printk("Interrupt DRQ\n");break;
+-		case 2: printk("Accelerated DRQ\n");break;
+-		case 3: printk("Reserved\n");break;
+-	}
+-	printk(KERN_INFO "ide-tape: Command Packet Size: ");
+-	switch (gcw.packet_size) {
+-		case 0: printk("12 bytes\n");break;
+-		case 1: printk("16 bytes\n");break;
+-		default: printk("Reserved\n");break;
+-	}
 -	printk(KERN_INFO "ide-tape: Model: %.40s\n",id->model);
 -	printk(KERN_INFO "ide-tape: Firmware Revision: %.8s\n",id->fw_rev);
 -	printk(KERN_INFO "ide-tape: Serial Number: %.20s\n",id->serial_no);
@@ -405670,10 +410614,233 @@
 -		
 -	} else
 -		printk(KERN_INFO "ide-tape: According to the device, fields 64-70 are not valid.\n");
- #endif /* IDETAPE_DEBUG_INFO */
- 
+-#endif /* IDETAPE_DEBUG_INFO */
+-
  	/* Check that we can support this device */
-@@ -4610,19 +4531,11 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
+ 
+-	if (gcw.protocol !=2 )
+-		printk(KERN_ERR "ide-tape: Protocol is not ATAPI\n");
++	if (gcw.protocol != 2)
++		printk(KERN_ERR "ide-tape: Protocol (0x%02x) is not ATAPI\n",
++				gcw.protocol);
+ 	else if (gcw.device_type != 1)
+-		printk(KERN_ERR "ide-tape: Device type is not set to tape\n");
++		printk(KERN_ERR "ide-tape: Device type (0x%02x) is not set "
++				"to tape\n", gcw.device_type);
+ 	else if (!gcw.removable)
+ 		printk(KERN_ERR "ide-tape: The removable flag is not set\n");
+ 	else if (gcw.packet_size != 0) {
+-		printk(KERN_ERR "ide-tape: Packet size is not 12 bytes long\n");
+-		if (gcw.packet_size == 1)
+-			printk(KERN_ERR "ide-tape: Sorry, padding to 16 bytes is still not supported\n");
++		printk(KERN_ERR "ide-tape: Packet size (0x%02x) is not 12 "
++				"bytes long\n", gcw.packet_size);
+ 	} else
+ 		return 1;
+ 	return 0;
+ }
+ 
+-/*
+- * Use INQUIRY to get the firmware revision
+- */
+-static void idetape_get_inquiry_results (ide_drive_t *drive)
++static void idetape_get_inquiry_results(ide_drive_t *drive)
+ {
+ 	char *r;
+ 	idetape_tape_t *tape = drive->driver_data;
+ 	idetape_pc_t pc;
+-	idetape_inquiry_result_t *inquiry;
+-	
++
+ 	idetape_create_inquiry_cmd(&pc);
+ 	if (idetape_queue_pc_tail(drive, &pc)) {
+-		printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", tape->name);
++		printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
++				tape->name);
+ 		return;
+ 	}
+-	inquiry = (idetape_inquiry_result_t *) pc.buffer;
+-	memcpy(tape->vendor_id, inquiry->vendor_id, 8);
+-	memcpy(tape->product_id, inquiry->product_id, 16);
+-	memcpy(tape->firmware_revision, inquiry->revision_level, 4);
++	memcpy(tape->vendor_id, &pc.buffer[8], 8);
++	memcpy(tape->product_id, &pc.buffer[16], 16);
++	memcpy(tape->firmware_revision, &pc.buffer[32], 4);
++
+ 	ide_fixstring(tape->vendor_id, 10, 0);
+ 	ide_fixstring(tape->product_id, 18, 0);
+ 	ide_fixstring(tape->firmware_revision, 6, 0);
+ 	r = tape->firmware_revision;
+ 	if (*(r + 1) == '.')
+-		tape->firmware_revision_num = (*r - '0') * 100 + (*(r + 2) - '0') * 10 + *(r + 3) - '0';
+-	printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n", drive->name, tape->name, tape->vendor_id, tape->product_id, tape->firmware_revision);
++		tape->firmware_revision_num = (*r - '0') * 100 +
++			(*(r + 2) - '0') * 10 +	*(r + 3) - '0';
++	printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n",
++			drive->name, tape->name, tape->vendor_id,
++			tape->product_id, tape->firmware_revision);
+ }
+ 
+ /*
+- *	idetape_get_mode_sense_results asks the tape about its various
+- *	parameters. In particular, we will adjust our data transfer buffer
+- *	size to the recommended value as returned by the tape.
++ * Ask the tape about its various parameters. In particular, we will adjust our
++ * data transfer buffer	size to the recommended value as returned by the tape.
+  */
+ static void idetape_get_mode_sense_results (ide_drive_t *drive)
+ {
+ 	idetape_tape_t *tape = drive->driver_data;
+ 	idetape_pc_t pc;
+-	idetape_mode_parameter_header_t *header;
+-	idetape_capabilities_page_t *capabilities;
+-	
++	u8 *caps;
++	u8 speed, max_speed;
++
+ 	idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE);
+ 	if (idetape_queue_pc_tail(drive, &pc)) {
+-		printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming some default values\n");
++		printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming"
++				" some default values\n");
+ 		tape->tape_block_size = 512;
+-		tape->capabilities.ctl = 52;
+-		tape->capabilities.speed = 450;
+-		tape->capabilities.buffer_size = 6 * 52;
++		put_unaligned(52,   (u16 *)&tape->caps[12]);
++		put_unaligned(540,  (u16 *)&tape->caps[14]);
++		put_unaligned(6*52, (u16 *)&tape->caps[16]);
+ 		return;
+ 	}
+-	header = (idetape_mode_parameter_header_t *) pc.buffer;
+-	capabilities = (idetape_capabilities_page_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t) + header->bdl);
++	caps = pc.buffer + 4 + pc.buffer[3];
+ 
+-	capabilities->max_speed = ntohs(capabilities->max_speed);
+-	capabilities->ctl = ntohs(capabilities->ctl);
+-	capabilities->speed = ntohs(capabilities->speed);
+-	capabilities->buffer_size = ntohs(capabilities->buffer_size);
++	/* convert to host order and save for later use */
++	speed = be16_to_cpu(*(u16 *)&caps[14]);
++	max_speed = be16_to_cpu(*(u16 *)&caps[8]);
+ 
+-	if (!capabilities->speed) {
+-		printk(KERN_INFO "ide-tape: %s: overriding capabilities->speed (assuming 650KB/sec)\n", drive->name);
+-		capabilities->speed = 650;
++	put_unaligned(max_speed, (u16 *)&caps[8]);
++	put_unaligned(be16_to_cpu(*(u16 *)&caps[12]), (u16 *)&caps[12]);
++	put_unaligned(speed, (u16 *)&caps[14]);
++	put_unaligned(be16_to_cpu(*(u16 *)&caps[16]), (u16 *)&caps[16]);
++
++	if (!speed) {
++		printk(KERN_INFO "ide-tape: %s: invalid tape speed "
++				"(assuming 650KB/sec)\n", drive->name);
++		put_unaligned(650, (u16 *)&caps[14]);
+ 	}
+-	if (!capabilities->max_speed) {
+-		printk(KERN_INFO "ide-tape: %s: overriding capabilities->max_speed (assuming 650KB/sec)\n", drive->name);
+-		capabilities->max_speed = 650;
++	if (!max_speed) {
++		printk(KERN_INFO "ide-tape: %s: invalid max_speed "
++				"(assuming 650KB/sec)\n", drive->name);
++		put_unaligned(650, (u16 *)&caps[8]);
+ 	}
+ 
+-	tape->capabilities = *capabilities;		/* Save us a copy */
+-	if (capabilities->blk512)
++	memcpy(&tape->caps, caps, 20);
++	if (caps[7] & 0x02)
+ 		tape->tape_block_size = 512;
+-	else if (capabilities->blk1024)
++	else if (caps[7] & 0x04)
+ 		tape->tape_block_size = 1024;
+-
+-#if IDETAPE_DEBUG_INFO
+-	printk(KERN_INFO "ide-tape: Dumping the results of the MODE SENSE packet command\n");
+-	printk(KERN_INFO "ide-tape: Mode Parameter Header:\n");
+-	printk(KERN_INFO "ide-tape: Mode Data Length - %d\n",header->mode_data_length);
+-	printk(KERN_INFO "ide-tape: Medium Type - %d\n",header->medium_type);
+-	printk(KERN_INFO "ide-tape: Device Specific Parameter - %d\n",header->dsp);
+-	printk(KERN_INFO "ide-tape: Block Descriptor Length - %d\n",header->bdl);
+-	
+-	printk(KERN_INFO "ide-tape: Capabilities and Mechanical Status Page:\n");
+-	printk(KERN_INFO "ide-tape: Page code - %d\n",capabilities->page_code);
+-	printk(KERN_INFO "ide-tape: Page length - %d\n",capabilities->page_length);
+-	printk(KERN_INFO "ide-tape: Read only - %s\n",capabilities->ro ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports reverse space - %s\n",capabilities->sprev ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports erase initiated formatting - %s\n",capabilities->efmt ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports QFA two Partition format - %s\n",capabilities->qfa ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports locking the medium - %s\n",capabilities->lock ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: The volume is currently locked - %s\n",capabilities->locked ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: The device defaults in the prevent state - %s\n",capabilities->prevent ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports ejecting the medium - %s\n",capabilities->eject ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports error correction - %s\n",capabilities->ecc ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports data compression - %s\n",capabilities->cmprs ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports 512 bytes block size - %s\n",capabilities->blk512 ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports 1024 bytes block size - %s\n",capabilities->blk1024 ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Supports 32768 bytes block size / Restricted byte count for PIO transfers - %s\n",capabilities->blk32768 ? "Yes":"No");
+-	printk(KERN_INFO "ide-tape: Maximum supported speed in KBps - %d\n",capabilities->max_speed);
+-	printk(KERN_INFO "ide-tape: Continuous transfer limits in blocks - %d\n",capabilities->ctl);
+-	printk(KERN_INFO "ide-tape: Current speed in KBps - %d\n",capabilities->speed);	
+-	printk(KERN_INFO "ide-tape: Buffer size - %d\n",capabilities->buffer_size*512);
+-#endif /* IDETAPE_DEBUG_INFO */
+-}
+-
+-/*
+- *	ide_get_blocksize_from_block_descriptor does a mode sense page 0 with block descriptor
+- *	and if it succeeds sets the tape block size with the reported value
+- */
+-static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive)
+-{
+-
+-	idetape_tape_t *tape = drive->driver_data;
+-	idetape_pc_t pc;
+-	idetape_mode_parameter_header_t *header;
+-	idetape_parameter_block_descriptor_t *block_descrp;
+-	
+-	idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR);
+-	if (idetape_queue_pc_tail(drive, &pc)) {
+-		printk(KERN_ERR "ide-tape: Can't get block descriptor\n");
+-		if (tape->tape_block_size == 0) {
+-			printk(KERN_WARNING "ide-tape: Cannot deal with zero block size, assume 32k\n");
+-			tape->tape_block_size =  32768;
+-		}
+-		return;
+-	}
+-	header = (idetape_mode_parameter_header_t *) pc.buffer;
+-	block_descrp = (idetape_parameter_block_descriptor_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t));
+-	tape->tape_block_size =( block_descrp->length[0]<<16) + (block_descrp->length[1]<<8) + block_descrp->length[2];
+-	tape->drv_write_prot = (header->dsp & 0x80) >> 7;
+-
+-#if IDETAPE_DEBUG_INFO
+-	printk(KERN_INFO "ide-tape: Adjusted block size - %d\n", tape->tape_block_size);
+-#endif /* IDETAPE_DEBUG_INFO */
+ }
+ 
+ #ifdef CONFIG_IDE_PROC_FS
+@@ -4569,13 +3634,15 @@ static void idetape_add_settings (ide_drive_t *drive)
+ /*
+  *			drive	setting name		read/write	data type	min			max			mul_factor			div_factor	data pointer				set function
+  */
+-	ide_add_setting(drive,	"buffer",		SETTING_READ,	TYPE_SHORT,	0,			0xffff,			1,				2,		&tape->capabilities.buffer_size,	NULL);
++	ide_add_setting(drive, "buffer", SETTING_READ, TYPE_SHORT, 0, 0xffff,
++			1, 2, (u16 *)&tape->caps[16], NULL);
+ 	ide_add_setting(drive,	"pipeline_min",		SETTING_RW,	TYPE_INT,	1,			0xffff,			tape->stage_size / 1024,	1,		&tape->min_pipeline,			NULL);
+ 	ide_add_setting(drive,	"pipeline",		SETTING_RW,	TYPE_INT,	1,			0xffff,			tape->stage_size / 1024,	1,		&tape->max_stages,			NULL);
+ 	ide_add_setting(drive,	"pipeline_max",		SETTING_RW,	TYPE_INT,	1,			0xffff,			tape->stage_size / 1024,	1,		&tape->max_pipeline,			NULL);
+ 	ide_add_setting(drive,	"pipeline_used",	SETTING_READ,	TYPE_INT,	0,			0xffff,			tape->stage_size / 1024,	1,		&tape->nr_stages,			NULL);
+ 	ide_add_setting(drive,	"pipeline_pending",	SETTING_READ,	TYPE_INT,	0,			0xffff,			tape->stage_size / 1024,	1,		&tape->nr_pending_stages,		NULL);
+-	ide_add_setting(drive,	"speed",		SETTING_READ,	TYPE_SHORT,	0,			0xffff,			1,				1,		&tape->capabilities.speed,		NULL);
++	ide_add_setting(drive, "speed", SETTING_READ, TYPE_SHORT, 0, 0xffff,
++			1, 1, (u16 *)&tape->caps[14], NULL);
+ 	ide_add_setting(drive,	"stage",		SETTING_READ,	TYPE_INT,	0,			0xffff,			1,				1024,		&tape->stage_size,			NULL);
+ 	ide_add_setting(drive,	"tdsc",			SETTING_RW,	TYPE_INT,	IDETAPE_DSC_RW_MIN,	IDETAPE_DSC_RW_MAX,	1000,				HZ,		&tape->best_dsc_rw_frequency,		NULL);
+ 	ide_add_setting(drive,	"dsc_overlap",		SETTING_RW,	TYPE_BYTE,	0,			1,			1,				1,		&drive->dsc_overlap,			NULL);
+@@ -4607,22 +3674,15 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
+ 	struct idetape_id_gcw gcw;
+ 	int stage_size;
+ 	struct sysinfo si;
++	u16 *ctl = (u16 *)&tape->caps[12];
  
  	spin_lock_init(&tape->spinlock);
  	drive->dsc_overlap = 1;
@@ -405697,7 +410864,59 @@
  	/* Seagate Travan drives do not support DSC overlap. */
  	if (strstr(drive->id->model, "Seagate STT3401"))
  		drive->dsc_overlap = 0;
-@@ -4724,10 +4637,8 @@ static void ide_tape_release(struct kref *kref)
+@@ -4642,13 +3702,13 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
+ 	
+ 	idetape_get_inquiry_results(drive);
+ 	idetape_get_mode_sense_results(drive);
+-	idetape_get_blocksize_from_block_descriptor(drive);
++	ide_tape_get_bsize_from_bdesc(drive);
+ 	tape->user_bs_factor = 1;
+-	tape->stage_size = tape->capabilities.ctl * tape->tape_block_size;
++	tape->stage_size = *ctl * tape->tape_block_size;
+ 	while (tape->stage_size > 0xffff) {
+ 		printk(KERN_NOTICE "ide-tape: decreasing stage size\n");
+-		tape->capabilities.ctl /= 2;
+-		tape->stage_size = tape->capabilities.ctl * tape->tape_block_size;
++		*ctl /= 2;
++		tape->stage_size = *ctl * tape->tape_block_size;
+ 	}
+ 	stage_size = tape->stage_size;
+ 	tape->pages_per_stage = stage_size / PAGE_SIZE;
+@@ -4657,11 +3717,8 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
+ 		tape->excess_bh_size = PAGE_SIZE - stage_size % PAGE_SIZE;
+ 	}
+ 
+-	/*
+-	 *	Select the "best" DSC read/write polling frequency
+-	 *	and pipeline size.
+-	 */
+-	speed = max(tape->capabilities.speed, tape->capabilities.max_speed);
++	/* Select the "best" DSC read/write polling freq and pipeline size. */
++	speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]);
+ 
+ 	tape->max_stages = speed * 1000 * 10 / tape->stage_size;
+ 
+@@ -4678,7 +3735,7 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
+ 		tape->max_stages = tape->min_pipeline = tape->max_pipeline = 1;
+ 
+ 	t1 = (tape->stage_size * HZ) / (speed * 1000);
+-	tmid = (tape->capabilities.buffer_size * 32 * HZ) / (speed * 125);
++	tmid = (*(u16 *)&tape->caps[16] * 32 * HZ) / (speed * 125);
+ 	tn = (IDETAPE_FIFO_THRESHOLD * tape->stage_size * HZ) / (speed * 1000);
+ 
+ 	if (tape->max_stages)
+@@ -4693,8 +3750,8 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
+ 	tape->best_dsc_rw_frequency = max_t(unsigned long, min_t(unsigned long, t, IDETAPE_DSC_RW_MAX), IDETAPE_DSC_RW_MIN);
+ 	printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, "
+ 		"%dkB pipeline, %lums tDSC%s\n",
+-		drive->name, tape->name, tape->capabilities.speed,
+-		(tape->capabilities.buffer_size * 512) / tape->stage_size,
++		drive->name, tape->name, *(u16 *)&tape->caps[14],
++		(*(u16 *)&tape->caps[16] * 512) / tape->stage_size,
+ 		tape->stage_size / 1024,
+ 		tape->max_stages * tape->stage_size / 1024,
+ 		tape->best_dsc_rw_frequency * 1000 / HZ,
+@@ -4724,10 +3781,8 @@ static void ide_tape_release(struct kref *kref)
  
  	drive->dsc_overlap = 0;
  	drive->driver_data = NULL;
@@ -405710,7 +410929,7 @@
  	idetape_devs[tape->minor] = NULL;
  	g->private_data = NULL;
  	put_disk(g);
-@@ -4884,10 +4795,10 @@ static int ide_tape_probe(ide_drive_t *drive)
+@@ -4884,10 +3939,10 @@ static int ide_tape_probe(ide_drive_t *drive)
  
  	idetape_setup(drive, tape, minor);
  
@@ -405726,7 +410945,7 @@
  	g->fops = &idetape_block_ops;
  	ide_register_region(g);
 diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
-index 2b60f1b..16a9a58 100644
+index 2b60f1b..4e1da1c 100644
 --- a/drivers/ide/ide-taskfile.c
 +++ b/drivers/ide/ide-taskfile.c
 @@ -1,11 +1,9 @@
@@ -406372,7 +411591,7 @@
  
  	if (copy_to_user(buf, req_task, tasksize)) {
  		err = -EFAULT;
-@@ -658,40 +744,24 @@ abort:
+@@ -658,40 +744,25 @@ abort:
  
  //	printk("IDE Taskfile ioctl ended. rc = %i\n", err);
  
@@ -406410,6 +411629,7 @@
 +	u8 args[4], xfer_rate = 0;
  	ide_task_t tfargs;
 +	struct ide_taskfile *tf = &tfargs.tf;
++	struct hd_driveid *id = drive->id;
  
  	if (NULL == (void *) arg) {
  		struct request rq;
@@ -406420,7 +411640,7 @@
  		return ide_do_drive_cmd(drive, &rq, ide_wait);
  	}
  
-@@ -699,27 +769,40 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
+@@ -699,27 +770,46 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
  		return -EFAULT;
  
  	memset(&tfargs, 0, sizeof(ide_task_t));
@@ -406456,11 +411676,19 @@
 +		if (buf == NULL)
  			return -ENOMEM;
  	}
+-	if (set_transfer(drive, &tfargs)) {
 +
- 	if (set_transfer(drive, &tfargs)) {
++	if (tf->command == WIN_SETFEATURES &&
++	    tf->feature == SETFEATURES_XFER &&
++	    tf->nsect >= XFER_SW_DMA_0 &&
++	    (id->dma_ultra || id->dma_mword || id->dma_1word)) {
  		xfer_rate = args[1];
- 		if (ide_ata66_check(drive, &tfargs))
+-		if (ide_ata66_check(drive, &tfargs))
++		if (tf->nsect > XFER_UDMA_2 && !eighty_ninty_three(drive)) {
++			printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
++					    "be set\n", drive->name);
  			goto abort;
++		}
  	}
  
 -	err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
@@ -406472,7 +411700,7 @@
  
  	if (!err && xfer_rate) {
  		/* active-retuning-calls future */
-@@ -727,142 +810,38 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
+@@ -727,142 +817,38 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
  		ide_driveid_update(drive);
  	}
  abort:
@@ -406515,7 +411743,7 @@
 -		err = -EFAULT;
 -	return err;
 -}
--
+ 
 -/*
 - * NOTICE: This is additions from IBM to provide a discrete interface,
 - * for selective taskregister access operations.  Nice JOB Klaus!!!
@@ -406526,7 +411754,11 @@
 -	ide_hwif_t *hwif	= HWIF(drive);
 -	task_struct_t *taskfile	= (task_struct_t *) task->tfRegister;
 -	hob_struct_t *hobfile	= (hob_struct_t *) task->hobRegister;
--
++	memset(&task, 0, sizeof(task));
++	memcpy(&task.tf_array[7], &args[1], 6);
++	task.tf.command = args[0];
++	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ 
 -	if (task->data_phase == TASKFILE_MULTI_IN ||
 -	    task->data_phase == TASKFILE_MULTI_OUT) {
 -		if (!drive->mult_count) {
@@ -406534,7 +411766,7 @@
 -			return ide_stopped;
 -		}
 -	}
- 
+-
 -	/*
 -	 * (ks) Check taskfile in flags.
 -	 * If set, then execute as it is defined.
@@ -406592,10 +411824,7 @@
 -	 */
 -	hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG);
 -	switch(task->data_phase) {
-+	memset(&task, 0, sizeof(task));
-+	memcpy(&task.tf_array[7], &args[1], 6);
-+	task.tf.command = args[0];
-+	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
++	err = ide_no_data_taskfile(drive, &task);
  
 -   	        case TASKFILE_OUT_DMAQ:
 -		case TASKFILE_OUT_DMA:
@@ -406603,7 +411832,8 @@
 -		case TASKFILE_IN_DMA:
 -			if (!drive->using_dma)
 -				break;
-+	err = ide_no_data_taskfile(drive, &task);
++	args[0] = task.tf.command;
++	memcpy(&args[1], &task.tf_array[7], 6);
  
 -			if (!hwif->dma_setup(drive)) {
 -				hwif->dma_exec_cmd(drive, taskfile->command);
@@ -406611,9 +411841,7 @@
 -				return ide_started;
 -			}
 -			break;
-+	args[0] = task.tf.command;
-+	memcpy(&args[1], &task.tf_array[7], 6);
- 
+-
 -	        default:
 - 			if (task->handler == NULL)
 -				return ide_stopped;
@@ -406647,7 +411875,7 @@
   */
  
 diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
-index 54943da..ab9ca2b 100644
+index 54943da..ac61360 100644
 --- a/drivers/ide/ide.c
 +++ b/drivers/ide/ide.c
 @@ -1,7 +1,6 @@
@@ -406800,7 +412028,7 @@
  	hwif->dma_command		= tmp_hwif->dma_command;
  	hwif->dma_vendor1		= tmp_hwif->dma_vendor1;
  	hwif->dma_status		= tmp_hwif->dma_status;
-@@ -483,6 +461,41 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
+@@ -483,9 +461,46 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
  	hwif->hwif_data			= tmp_hwif->hwif_data;
  }
  
@@ -406842,7 +412070,21 @@
  /**
   *	ide_unregister		-	free an IDE interface
   *	@index: index of interface (will change soon to a pointer)
-@@ -550,43 +563,8 @@ void ide_unregister(unsigned int index)
++ *	@init_default: init default hwif flag
++ *	@restore: restore hwif flag
+  *
+  *	Perform the final unregister of an IDE interface. At the moment
+  *	we don't refcount interfaces so this will also get split up.
+@@ -505,7 +520,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
+  *	This is raving bonkers.
+  */
+ 
+-void ide_unregister(unsigned int index)
++void ide_unregister(unsigned int index, int init_default, int restore)
+ {
+ 	ide_drive_t *drive;
+ 	ide_hwif_t *hwif, *g;
+@@ -550,43 +565,8 @@ void ide_unregister(unsigned int index)
  	if (irq_count == 1)
  		free_irq(hwif->irq, hwgroup);
  
@@ -406853,8 +412095,7 @@
 -	 * allocated for weird IDE interface chipsets.
 -	 */
 -	ide_hwif_release_regions(hwif);
-+	ide_remove_port_from_hwgroup(hwif);
- 
+-
 -	/*
 -	 * Remove us from the hwgroup, and free
 -	 * the hwgroup if we were the only member
@@ -406881,13 +412122,14 @@
 -		}
 -		BUG_ON(hwgroup->hwif == hwif);
 -	}
--
++	ide_remove_port_from_hwgroup(hwif);
+ 
 -	/* More messed up locking ... */
 -	spin_unlock_irq(&ide_lock);
  	device_unregister(&hwif->gendev);
  	wait_for_completion(&hwif->gendev_rel_comp);
  
-@@ -602,7 +580,6 @@ void ide_unregister(unsigned int index)
+@@ -602,7 +582,6 @@ void ide_unregister(unsigned int index)
  		(void) ide_release_dma(hwif);
  
  		hwif->dma_base = 0;
@@ -406895,7 +412137,7 @@
  		hwif->dma_command = 0;
  		hwif->dma_vendor1 = 0;
  		hwif->dma_status = 0;
-@@ -613,11 +590,18 @@ void ide_unregister(unsigned int index)
+@@ -613,14 +592,24 @@ void ide_unregister(unsigned int index)
  		hwif->extra_ports = 0;
  	}
  
@@ -406911,11 +412153,19 @@
  
  	/* restore hwif data to pristine status */
 -	init_hwif_data(hwif, index);
+-	init_hwif_default(hwif, index);
 +	ide_init_port_data(hwif, index);
- 	init_hwif_default(hwif, index);
++
++	if (init_default)
++		init_hwif_default(hwif, index);
+ 
+-	ide_hwif_restore(hwif, &tmp_hwif);
++	if (restore)
++		ide_hwif_restore(hwif, &tmp_hwif);
  
- 	ide_hwif_restore(hwif, &tmp_hwif);
-@@ -683,24 +667,34 @@ void ide_setup_ports (	hw_regs_t *hw,
+ abort:
+ 	spin_unlock_irq(&ide_lock);
+@@ -683,70 +672,86 @@ void ide_setup_ports (	hw_regs_t *hw,
   */
  }
  
@@ -406930,6 +412180,31 @@
 +}
 +EXPORT_SYMBOL_GPL(ide_init_port_hw);
 +
++ide_hwif_t *ide_deprecated_find_port(unsigned long base)
++{
++	ide_hwif_t *hwif;
++	int i;
++
++	for (i = 0; i < MAX_HWIFS; i++) {
++		hwif = &ide_hwifs[i];
++		if (hwif->io_ports[IDE_DATA_OFFSET] == base)
++			goto found;
++	}
++
++	for (i = 0; i < MAX_HWIFS; i++) {
++		hwif = &ide_hwifs[i];
++		if (hwif->hold)
++			continue;
++		if (!hwif->present && hwif->mate == NULL)
++			goto found;
++	}
++
++	hwif = NULL;
++found:
++	return hwif;
++}
++EXPORT_SYMBOL_GPL(ide_deprecated_find_port);
++
  /**
   *	ide_register_hw		-	register IDE interface
   *	@hw: hardware registers
@@ -406954,27 +412229,37 @@
 +	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
  
  	do {
- 		for (index = 0; index < MAX_HWIFS; ++index) {
-@@ -712,8 +706,7 @@ int ide_register_hw(hw_regs_t *hw, void (*fixup)(ide_hwif_t *),
- 			hwif = &ide_hwifs[index];
- 			if (hwif->hold)
- 				continue;
+-		for (index = 0; index < MAX_HWIFS; ++index) {
+-			hwif = &ide_hwifs[index];
+-			if (hwif->io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
+-				goto found;
+-		}
+-		for (index = 0; index < MAX_HWIFS; ++index) {
+-			hwif = &ide_hwifs[index];
+-			if (hwif->hold)
+-				continue;
 -			if ((!hwif->present && !hwif->mate && !initializing) ||
 -			    (!hwif->io_ports[IDE_DATA_OFFSET] && initializing))
-+			if (!hwif->present && hwif->mate == NULL)
- 				goto found;
- 		}
+-				goto found;
+-		}
++		hwif = ide_deprecated_find_port(hw->io_ports[IDE_DATA_OFFSET]);
++		index = hwif->index;
++		if (hwif)
++			goto found;
  		for (index = 0; index < MAX_HWIFS; index++)
-@@ -724,29 +717,23 @@ found:
+-			ide_unregister(index);
++			ide_unregister(index, 1, 1);
+ 	} while (retry--);
+ 	return -1;
+ found:
  	if (hwif->present)
- 		ide_unregister(index);
- 	else if (!hwif->hold) {
+-		ide_unregister(index);
+-	else if (!hwif->hold) {
 -		init_hwif_data(hwif, index);
-+		ide_init_port_data(hwif, index);
- 		init_hwif_default(hwif, index);
- 	}
- 	if (hwif->present)
- 		return -1;
+-		init_hwif_default(hwif, index);
+-	}
+-	if (hwif->present)
+-		return -1;
 -	memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
 -	hwif->irq = hw->irq;
 -	hwif->noprobe = 0;
@@ -406982,6 +412267,9 @@
 -	hwif->chipset = hw->chipset;
 -	hwif->gendev.parent = hw->dev;
 -	hwif->ack_intr = hw->ack_intr;
++		ide_unregister(index, 0, 1);
++	else if (!hwif->hold)
++		ide_init_port_data(hwif, index);
  
 -	if (initializing == 0) {
 -		u8 idx[4] = { index, 0xff, 0xff, 0xff };
@@ -406992,7 +412280,7 @@
 -	}
 +	idx[0] = index;
 +
-+	ide_device_add(idx);
++	ide_device_add(idx, NULL);
  
  	if (hwifp)
  		*hwifp = hwif;
@@ -407002,7 +412290,18 @@
  }
  
  EXPORT_SYMBOL(ide_register_hw);
-@@ -839,7 +826,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
+@@ -804,10 +809,6 @@ int set_io_32bit(ide_drive_t *drive, int arg)
+ 		return -EBUSY;
+ 
+ 	drive->io_32bit = arg;
+-#ifdef CONFIG_BLK_DEV_DTC2278
+-	if (HWIF(drive)->chipset == ide_dtc2278)
+-		HWIF(drive)->drives[!drive->select.b.unit].io_32bit = arg;
+-#endif /* CONFIG_BLK_DEV_DTC2278 */
+ 
+ 	spin_unlock_irq(&ide_lock);
+ 
+@@ -839,7 +840,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
  	if (!drive->id || !(drive->id->capability & 1))
  		goto out;
  
@@ -407011,7 +412310,7 @@
  		goto out;
  
  	err = -EBUSY;
-@@ -854,8 +841,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
+@@ -854,8 +855,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
  	err = 0;
  
  	if (arg) {
@@ -407021,7 +412320,7 @@
  			err = -EIO;
  	} else
  		ide_dma_off(drive);
-@@ -888,7 +874,10 @@ int set_pio_mode(ide_drive_t *drive, int arg)
+@@ -888,7 +888,10 @@ int set_pio_mode(ide_drive_t *drive, int arg)
  
  	if (drive->special.b.set_tune)
  		return -EBUSY;
@@ -407032,7 +412331,7 @@
  	drive->tune_req = (u8) arg;
  	drive->special.b.set_tune = 1;
  	(void) ide_do_drive_cmd(drive, &rq, ide_wait);
-@@ -920,7 +909,7 @@ static int set_unmaskirq(ide_drive_t *drive, int arg)
+@@ -920,7 +923,7 @@ static int set_unmaskirq(ide_drive_t *drive, int arg)
  
  int system_bus_clock (void)
  {
@@ -407041,7 +412340,20 @@
  }
  
  EXPORT_SYMBOL(system_bus_clock);
-@@ -1070,7 +1059,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
+@@ -1032,11 +1035,8 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
+ 		case HDIO_GET_NICE:
+ 			return put_user(drive->dsc_overlap	<<	IDE_NICE_DSC_OVERLAP	|
+ 					drive->atapi_overlap	<<	IDE_NICE_ATAPI_OVERLAP	|
+-					drive->nice0		<< 	IDE_NICE_0		|
+-					drive->nice1		<<	IDE_NICE_1		|
+-					drive->nice2		<<	IDE_NICE_2,
++					drive->nice1 << IDE_NICE_1,
+ 					(long __user *) arg);
+-
+ #ifdef CONFIG_IDE_TASK_IOCTL
+ 		case HDIO_DRIVE_TASKFILE:
+ 		        if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+@@ -1070,14 +1070,14 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
  			ide_init_hwif_ports(&hw, (unsigned long) args[0],
  					    (unsigned long) args[1], NULL);
  			hw.irq = args[2];
@@ -407050,7 +412362,15 @@
  				return -EIO;
  			return 0;
  		}
-@@ -1231,26 +1220,12 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
+ 	        case HDIO_UNREGISTER_HWIF:
+ 			if (!capable(CAP_SYS_RAWIO)) return -EACCES;
+ 			/* (arg > MAX_HWIFS) checked in function */
+-			ide_unregister(arg);
++			ide_unregister(arg, 1, 1);
+ 			return 0;
+ 		case HDIO_SET_NICE:
+ 			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+@@ -1231,26 +1231,12 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
  	return 0;	/* zero = nothing matched */
  }
  
@@ -407078,7 +412398,7 @@
  
  static int __initdata is_chipset_set[MAX_HWIFS];
  
-@@ -1327,7 +1302,7 @@ static int __init ide_setup(char *s)
+@@ -1327,7 +1313,7 @@ static int __init ide_setup(char *s)
  	if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
  		const char *hd_words[] = {
  			"none", "noprobe", "nowerr", "cdrom", "nodma",
@@ -407087,7 +412407,7 @@
  			"noflush", "remap", "remap63", "scsi", NULL };
  		unit = s[2] - 'a';
  		hw   = unit / MAX_DRIVES;
-@@ -1363,10 +1338,6 @@ static int __init ide_setup(char *s)
+@@ -1363,10 +1349,6 @@ static int __init ide_setup(char *s)
  			case -7: /* "noautotune" */
  				drive->autotune = IDE_TUNE_NOAUTO;
  				goto obsolete_option;
@@ -407098,7 +412418,7 @@
  			case -11: /* noflush */
  				drive->noflush = 1;
  				goto done;
-@@ -1466,11 +1437,8 @@ static int __init ide_setup(char *s)
+@@ -1466,11 +1448,8 @@ static int __init ide_setup(char *s)
  #endif
  #ifdef CONFIG_BLK_DEV_CMD640
  			case -14: /* "cmd640_vlb" */
@@ -407110,7 +412430,7 @@
  #endif
  #ifdef CONFIG_BLK_DEV_HT6560B
  			case -13: /* "ht6560b" */
-@@ -1560,79 +1528,6 @@ done:
+@@ -1560,79 +1539,6 @@ done:
  	return 1;
  }
  
@@ -407190,7 +412510,7 @@
  EXPORT_SYMBOL(ide_lock);
  
  static int ide_bus_match(struct device *dev, struct device_driver *drv)
-@@ -1769,6 +1664,10 @@ static int __init ide_init(void)
+@@ -1769,6 +1675,10 @@ static int __init ide_init(void)
  	printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
  	system_bus_speed = ide_system_bus_speed();
  
@@ -407201,7 +412521,7 @@
  	ret = bus_register(&ide_bus_type);
  	if (ret < 0) {
  		printk(KERN_WARNING "IDE: bus_register error: %d\n", ret);
-@@ -1779,30 +1678,6 @@ static int __init ide_init(void)
+@@ -1779,30 +1689,6 @@ static int __init ide_init(void)
  
  	proc_ide_create();
  
@@ -407232,17 +412552,19 @@
  	return 0;
  }
  
-@@ -1838,10 +1713,6 @@ void __exit cleanup_module (void)
- 	for (index = 0; index < MAX_HWIFS; ++index)
- 		ide_unregister(index);
+@@ -1836,11 +1722,7 @@ void __exit cleanup_module (void)
+ 	int index;
  
+ 	for (index = 0; index < MAX_HWIFS; ++index)
+-		ide_unregister(index);
+-
 -#ifdef CONFIG_BLK_DEV_IDEPNP
 -	pnpide_exit();
 -#endif
--
++		ide_unregister(index, 0, 0);
+ 
  	proc_ide_destroy();
  
- 	bus_unregister(&ide_bus_type);
 diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile
 index 4098223..7043ec7 100644
 --- a/drivers/ide/legacy/Makefile
@@ -407278,7 +412600,7 @@
  
  EXTRA_CFLAGS	:= -Idrivers/ide
 diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
-index 38c3a6d..e3ea209 100644
+index 38c3a6d..d4d1a6b 100644
 --- a/drivers/ide/legacy/ali14xx.c
 +++ b/drivers/ide/legacy/ali14xx.c
 @@ -1,6 +1,4 @@
@@ -407288,7 +412610,48 @@
   *  Copyright (C) 1996  Linus Torvalds & author (see below)
   */
  
-@@ -231,8 +229,7 @@ int probe_ali14xx = 0;
+@@ -193,9 +191,14 @@ static int __init initRegisters (void) {
+ 	return t;
+ }
+ 
++static const struct ide_port_info ali14xx_port_info = {
++	.chipset		= ide_ali14xx,
++	.host_flags		= IDE_HFLAG_NO_DMA | IDE_HFLAG_NO_AUTOTUNE,
++	.pio_mask		= ATA_PIO4,
++};
++
+ static int __init ali14xx_probe(void)
+ {
+-	ide_hwif_t *hwif, *mate;
+ 	static u8 idx[4] = { 0, 1, 0xff, 0xff };
+ 
+ 	printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
+@@ -207,21 +210,10 @@ static int __init ali14xx_probe(void)
+ 		return 1;
+ 	}
+ 
+-	hwif = &ide_hwifs[0];
+-	mate = &ide_hwifs[1];
+-
+-	hwif->chipset = ide_ali14xx;
+-	hwif->pio_mask = ATA_PIO4;
+-	hwif->set_pio_mode = &ali14xx_set_pio_mode;
+-	hwif->mate = mate;
+-
+-	mate->chipset = ide_ali14xx;
+-	mate->pio_mask = ATA_PIO4;
+-	mate->set_pio_mode = &ali14xx_set_pio_mode;
+-	mate->mate = hwif;
+-	mate->channel = 1;
++	ide_hwifs[0].set_pio_mode = &ali14xx_set_pio_mode;
++	ide_hwifs[1].set_pio_mode = &ali14xx_set_pio_mode;
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, &ali14xx_port_info);
+ 
+ 	return 0;
+ }
+@@ -231,8 +223,7 @@ int probe_ali14xx = 0;
  module_param_named(probe, probe_ali14xx, bool, 0);
  MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets");
  
@@ -407298,7 +412661,7 @@
  {
  	if (probe_ali14xx == 0)
  		goto out;
-@@ -248,9 +245,7 @@ out:
+@@ -248,9 +239,7 @@ out:
  	return -ENODEV;
  }
  
@@ -407309,7 +412672,7 @@
  MODULE_AUTHOR("see local file");
  MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets");
 diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
-index 4a0be25..dd3d198 100644
+index 4a0be25..8bdb79d 100644
 --- a/drivers/ide/legacy/buddha.c
 +++ b/drivers/ide/legacy/buddha.c
 @@ -1,5 +1,5 @@
@@ -407395,7 +412758,7 @@
 +			}
  		}
 +
-+		ide_device_add(idx);
++		ide_device_add(idx, NULL);
  	}
 +
 +	return 0;
@@ -407403,7 +412766,7 @@
 +
 +module_init(buddha_init);
 diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c
-index 24a845d..611c970 100644
+index 24a845d..73396f7 100644
 --- a/drivers/ide/legacy/dtc2278.c
 +++ b/drivers/ide/legacy/dtc2278.c
 @@ -1,6 +1,4 @@
@@ -407413,7 +412776,59 @@
   *  Copyright (C) 1996  Linus Torvalds & author (see below)
   */
  
-@@ -150,8 +148,7 @@ int probe_dtc2278 = 0;
+@@ -86,14 +84,20 @@ static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
+ 		/* Actually we do - there is a data sheet available for the
+ 		   Winbond but does anyone actually care */
+ 	}
+-
+-	/*
+-	 * 32bit I/O has to be enabled for *both* drives at the same time.
+-	 */
+-	drive->io_32bit = 1;
+-	HWIF(drive)->drives[!drive->select.b.unit].io_32bit = 1;
+ }
+ 
++static const struct ide_port_info dtc2278_port_info __initdata = {
++	.chipset		= ide_dtc2278,
++	.host_flags		= IDE_HFLAG_SERIALIZE |
++				  IDE_HFLAG_NO_UNMASK_IRQS |
++				  IDE_HFLAG_IO_32BIT |
++				  /* disallow ->io_32bit changes */
++				  IDE_HFLAG_NO_IO_32BIT |
++				  IDE_HFLAG_NO_DMA |
++				  IDE_HFLAG_NO_AUTOTUNE,
++	.pio_mask		= ATA_PIO4,
++};
++
+ static int __init dtc2278_probe(void)
+ {
+ 	unsigned long flags;
+@@ -124,23 +128,9 @@ static int __init dtc2278_probe(void)
+ #endif
+ 	local_irq_restore(flags);
+ 
+-	hwif->serialized = 1;
+-	hwif->chipset = ide_dtc2278;
+-	hwif->pio_mask = ATA_PIO4;
+ 	hwif->set_pio_mode = &dtc2278_set_pio_mode;
+-	hwif->drives[0].no_unmask = 1;
+-	hwif->drives[1].no_unmask = 1;
+-	hwif->mate = mate;
+-
+-	mate->serialized = 1;
+-	mate->chipset = ide_dtc2278;
+-	mate->pio_mask = ATA_PIO4;
+-	mate->drives[0].no_unmask = 1;
+-	mate->drives[1].no_unmask = 1;
+-	mate->mate = hwif;
+-	mate->channel = 1;
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, &dtc2278_port_info);
+ 
+ 	return 0;
+ }
+@@ -150,8 +140,7 @@ int probe_dtc2278 = 0;
  module_param_named(probe, probe_dtc2278, bool, 0);
  MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets");
  
@@ -407423,7 +412838,7 @@
  {
  	if (probe_dtc2278 == 0)
  		return -ENODEV;
-@@ -163,9 +160,7 @@ int __init dtc2278_init(void)
+@@ -163,9 +152,7 @@ int __init dtc2278_init(void)
  	return 0;
  }
  
@@ -407434,7 +412849,7 @@
  MODULE_AUTHOR("See Local File");
  MODULE_DESCRIPTION("support of DTC-2278 VLB IDE chipsets");
 diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
-index 7d7936f..c9bd6bf 100644
+index 7d7936f..85b69a8 100644
 --- a/drivers/ide/legacy/falconide.c
 +++ b/drivers/ide/legacy/falconide.c
 @@ -1,5 +1,5 @@
@@ -407474,7 +412889,7 @@
 +		ide_init_port_data(hwif, index);
 +		ide_init_port_hw(hwif, &hw);
 +
-+		ide_device_add(idx);
++		ide_device_add(idx, NULL);
 +	}
      }
 +
@@ -407483,7 +412898,7 @@
 +
 +module_init(falconide_init);
 diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
-index 53331ee..f67c51a 100644
+index 53331ee..fc29ce7 100644
 --- a/drivers/ide/legacy/gayle.c
 +++ b/drivers/ide/legacy/gayle.c
 @@ -1,5 +1,5 @@
@@ -407564,14 +412979,14 @@
  	    release_mem_region(res_start, res_n);
      }
 +
-+    ide_device_add(idx);
++    ide_device_add(idx, NULL);
 +
 +    return 0;
  }
 +
 +module_init(gayle_init);
 diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
-index a4245d1..57bc15c 100644
+index a4245d1..02d12c7 100644
 --- a/drivers/ide/legacy/ht6560b.c
 +++ b/drivers/ide/legacy/ht6560b.c
 @@ -1,6 +1,4 @@
@@ -407581,16 +412996,86 @@
   *  Copyright (C) 1995-2000  Linus Torvalds & author (see below)
   */
  
-@@ -307,8 +305,7 @@ int probe_ht6560b = 0;
+@@ -302,17 +300,36 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
+ #endif
+ }
+ 
++static void __init ht6560b_port_init_devs(ide_hwif_t *hwif)
++{
++	/* Setting default configurations for drives. */
++	int t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT;
++
++	if (hwif->channel)
++		t |= (HT_SECONDARY_IF << 8);
++
++	hwif->drives[0].drive_data = t;
++	hwif->drives[1].drive_data = t;
++}
++
+ int probe_ht6560b = 0;
+ 
  module_param_named(probe, probe_ht6560b, bool, 0);
  MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
  
 -/* Can be called directly from ide.c. */
 -int __init ht6560b_init(void)
++static const struct ide_port_info ht6560b_port_info __initdata = {
++	.chipset		= ide_ht6560b,
++	.host_flags		= IDE_HFLAG_SERIALIZE | /* is this needed? */
++				  IDE_HFLAG_NO_DMA |
++				  IDE_HFLAG_NO_AUTOTUNE |
++				  IDE_HFLAG_ABUSE_PREFETCH,
++	.pio_mask		= ATA_PIO5,
++};
++
 +static int __init ht6560b_init(void)
  {
  	ide_hwif_t *hwif, *mate;
  	static u8 idx[4] = { 0, 1, 0xff, 0xff };
+-	int t;
+ 
+ 	if (probe_ht6560b == 0)
+ 		return -ENODEV;
+@@ -331,36 +348,16 @@ int __init ht6560b_init(void)
+ 		goto release_region;
+ 	}
+ 
+-	hwif->chipset = ide_ht6560b;
+ 	hwif->selectproc = &ht6560b_selectproc;
+-	hwif->host_flags = IDE_HFLAG_ABUSE_PREFETCH;
+-	hwif->pio_mask = ATA_PIO5;
+ 	hwif->set_pio_mode = &ht6560b_set_pio_mode;
+-	hwif->serialized = 1;	/* is this needed? */
+-	hwif->mate = mate;
+ 
+-	mate->chipset = ide_ht6560b;
+ 	mate->selectproc = &ht6560b_selectproc;
+-	mate->host_flags = IDE_HFLAG_ABUSE_PREFETCH;
+-	mate->pio_mask = ATA_PIO5;
+ 	mate->set_pio_mode = &ht6560b_set_pio_mode;
+-	mate->serialized = 1;	/* is this needed? */
+-	mate->mate = hwif;
+-	mate->channel = 1;
+ 
+-	/*
+-	 * Setting default configurations for drives
+-	 */
+-	t = (HT_CONFIG_DEFAULT << 8);
+-	t |= HT_TIMING_DEFAULT;
+-	hwif->drives[0].drive_data = t;
+-	hwif->drives[1].drive_data = t;
+-
+-	t |= (HT_SECONDARY_IF << 8);
+-	mate->drives[0].drive_data = t;
+-	mate->drives[1].drive_data = t;
++	hwif->port_init_devs = ht6560b_port_init_devs;
++	mate->port_init_devs = ht6560b_port_init_devs;
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, &ht6560b_port_info);
+ 
+ 	return 0;
+ 
 @@ -369,9 +366,7 @@ release_region:
  	return -ENODEV;
  }
@@ -407602,7 +413087,7 @@
  MODULE_AUTHOR("See Local File");
  MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
 diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
-index 03715c0..3bd2967 100644
+index 03715c0..15ccf69 100644
 --- a/drivers/ide/legacy/ide-cs.c
 +++ b/drivers/ide/legacy/ide-cs.c
 @@ -2,8 +2,6 @@
@@ -407614,17 +413099,56 @@
      The contents of this file are subject to the Mozilla Public
      License Version 1.1 (the "License"); you may not use this file
      except in compliance with the License. You may obtain a copy of
-@@ -153,7 +151,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq
+@@ -147,13 +145,36 @@ static void ide_detach(struct pcmcia_device *link)
+ 
+ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
+ {
++    ide_hwif_t *hwif;
+     hw_regs_t hw;
++    int i;
++    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
++
+     memset(&hw, 0, sizeof(hw));
+-    ide_init_hwif_ports(&hw, io, ctl, NULL);
++    ide_std_init_ports(&hw, io, ctl);
      hw.irq = irq;
      hw.chipset = ide_pci;
      hw.dev = &handle->dev;
 -    return ide_register_hw(&hw, &ide_undecoded_slave, 0, NULL);
-+    return ide_register_hw(&hw, &ide_undecoded_slave, NULL);
++
++    hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
++    if (hwif == NULL)
++	return -1;
++
++    i = hwif->index;
++
++    if (hwif->present)
++	ide_unregister(i, 0, 0);
++    else if (!hwif->hold)
++	ide_init_port_data(hwif, i);
++
++    ide_init_port_hw(hwif, &hw);
++    hwif->quirkproc = &ide_undecoded_slave;
++
++    idx[0] = i;
++
++    ide_device_add(idx, NULL);
++
++    return hwif->present ? i : -1;
  }
  
  /*======================================================================
+@@ -339,7 +360,7 @@ void ide_release(struct pcmcia_device *link)
+     if (info->ndev) {
+ 	/* FIXME: if this fails we need to queue the cleanup somehow
+ 	   -- need to investigate the required PCMCIA magic */
+-	ide_unregister(info->hd);
++	ide_unregister(info->hd, 0, 0);
+     }
+     info->ndev = 0;
+ 
 diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
-index 7bb79f5..7c3231a 100644
+index 7bb79f5..26c82ce 100644
 --- a/drivers/ide/legacy/ide_platform.c
 +++ b/drivers/ide/legacy/ide_platform.c
 @@ -21,56 +21,39 @@
@@ -407696,7 +413220,7 @@
  
  	pdata = pdev->dev.platform_data;
  
-@@ -95,26 +78,33 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
+@@ -95,30 +78,37 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
  	}
  
  	if (mmio) {
@@ -407739,6 +413263,11 @@
  
  	idx[0] = hwif->index;
  
+-	ide_device_add(idx);
++	ide_device_add(idx, NULL);
+ 
+ 	platform_set_drvdata(pdev, hwif);
+ 
 @@ -132,14 +122,7 @@ static int __devexit plat_ide_remove(struct platform_device *pdev)
  {
  	ide_hwif_t *hwif = pdev->dev.driver_data;
@@ -407751,12 +413280,12 @@
 -		hwif_prop.index = 0;
 -		hwif_prop.hwif = NULL;
 -	}
-+	ide_unregister(hwif->index);
++	ide_unregister(hwif->index, 0, 0);
  
  	return 0;
  }
 diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
-index 5c6aa77..c54d07f 100644
+index 5c6aa77..06df8df 100644
 --- a/drivers/ide/legacy/macide.c
 +++ b/drivers/ide/legacy/macide.c
 @@ -1,5 +1,5 @@
@@ -407786,7 +413315,7 @@
  
  	switch (macintosh_config->ide_type) {
  	case MAC_IDE_QUADRA:
-@@ -93,48 +95,50 @@ void __init macide_init(void)
+@@ -93,48 +95,40 @@ void __init macide_init(void)
  				0, 0, macide_ack_intr,
  //				quadra_ide_iops,
  				IRQ_NUBUS_F);
@@ -407807,14 +413336,27 @@
 -		index = ide_register_hw(&hw, NULL, 1, &hwif);
 -		if (index == -1) break;
 -		if (macintosh_config->ident == MAC_MODEL_PB190) {
-+		break;
-+	default:
+-
+-			/* Fix breakage in ide-disk.c: drive capacity	*/
+-			/* is not initialized for drives without a 	*/
+-			/* hardware ID, and we can't get that without	*/
+-			/* probing the drive which freezes a 190.	*/
+-
+-			ide_drive_t *drive = &ide_hwifs[index].drives[0];
+-			drive->capacity64 = drive->cyl*drive->head*drive->sect;
+-
+-		}
+ 		break;
+-
+ 	default:
+-	    return;
 +		return -ENODEV;
-+	}
-+
+ 	}
+ 
+-        if (index != -1) {
 +	printk(KERN_INFO "ide: Macintosh %s IDE controller\n",
 +			 mac_ide_name[macintosh_config->ide_type - 1]);
- 
++
 +	hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]);
 +	if (hwif) {
 +		u8 index = hwif->index;
@@ -407823,25 +413365,6 @@
 +		ide_init_port_data(hwif, index);
 +		ide_init_port_hw(hwif, &hw);
 +
-+		if (macintosh_config->ide_type == MAC_IDE_BABOON &&
-+		    macintosh_config->ident == MAC_MODEL_PB190) {
- 			/* Fix breakage in ide-disk.c: drive capacity	*/
- 			/* is not initialized for drives without a 	*/
- 			/* hardware ID, and we can't get that without	*/
- 			/* probing the drive which freezes a 190.	*/
--
--			ide_drive_t *drive = &ide_hwifs[index].drives[0];
-+			ide_drive_t *drive = &hwif->drives[0];
- 			drive->capacity64 = drive->cyl*drive->head*drive->sect;
--
- 		}
--		break;
--
--	default:
--	    return;
--	}
- 
--        if (index != -1) {
  		hwif->mmio = 1;
 -		if (macintosh_config->ide_type == MAC_IDE_QUADRA)
 -			printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index);
@@ -407852,7 +413375,7 @@
 -		else
 -			printk(KERN_INFO "ide%d: Unknown Macintosh IDE interface\n", index);
 +
-+		ide_device_add(idx);
++		ide_device_add(idx, NULL);
  	}
 +
 +	return 0;
@@ -407860,7 +413383,7 @@
 +
 +module_init(macide_init);
 diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
-index 6ea46a6..a9c6b06 100644
+index 6ea46a6..2f0b34d 100644
 --- a/drivers/ide/legacy/q40ide.c
 +++ b/drivers/ide/legacy/q40ide.c
 @@ -1,5 +1,5 @@
@@ -407909,14 +413432,14 @@
 +	}
      }
 +
-+    ide_device_add(idx);
++    ide_device_add(idx, NULL);
 +
 +    return 0;
  }
  
 +module_init(q40ide_init);
 diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
-index 912e738..37534bb 100644
+index 912e738..bba29df 100644
 --- a/drivers/ide/legacy/qd65xx.c
 +++ b/drivers/ide/legacy/qd65xx.c
 @@ -1,6 +1,4 @@
@@ -407926,7 +413449,129 @@
   *  Copyright (C) 1996-2001  Linus Torvalds & author (see below)
   */
  
-@@ -478,8 +476,7 @@ int probe_qd65xx = 0;
+@@ -307,18 +305,33 @@ static int __init qd_testreg(int port)
+  * called to setup an ata channel : adjusts attributes & links for tuning
+  */
+ 
+-static void __init qd_setup(ide_hwif_t *hwif, int base, int config,
+-			    unsigned int data0, unsigned int data1)
++static void __init qd_setup(ide_hwif_t *hwif, int base, int config)
+ {
+-	hwif->chipset = ide_qd65xx;
+-	hwif->channel = hwif->index;
+ 	hwif->select_data = base;
+ 	hwif->config_data = config;
+-	hwif->drives[0].drive_data = data0;
+-	hwif->drives[1].drive_data = data1;
+-	hwif->drives[0].io_32bit =
+-	hwif->drives[1].io_32bit = 1;
+-	hwif->pio_mask = ATA_PIO4;
++}
++
++static void __init qd6500_port_init_devs(ide_hwif_t *hwif)
++{
++	u8 base = hwif->select_data, config = QD_CONFIG(hwif);
++
++	hwif->drives[0].drive_data = QD6500_DEF_DATA;
++	hwif->drives[1].drive_data = QD6500_DEF_DATA;
++}
++
++static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
++{
++	u16 t1, t2;
++	u8 base = hwif->select_data, config = QD_CONFIG(hwif);
++
++	if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
++		t1 = QD6580_DEF_DATA;
++		t2 = QD6580_DEF_DATA2;
++	} else
++		t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA;
++
++	hwif->drives[0].drive_data = t1;
++	hwif->drives[1].drive_data = t2;
+ }
+ 
+ /*
+@@ -358,6 +371,14 @@ static void __exit qd_unsetup(ide_hwif_t *hwif)
+ }
+ */
+ 
++static const struct ide_port_info qd65xx_port_info __initdata = {
++	.chipset		= ide_qd65xx,
++	.host_flags		= IDE_HFLAG_IO_32BIT |
++				  IDE_HFLAG_NO_DMA |
++				  IDE_HFLAG_NO_AUTOTUNE,
++	.pio_mask		= ATA_PIO4,
++};
++
+ /*
+  * qd_probe:
+  *
+@@ -395,13 +416,14 @@ static int __init qd_probe(int base)
+ 			return 1;
+ 		}
+ 
+-		qd_setup(hwif, base, config, QD6500_DEF_DATA, QD6500_DEF_DATA);
++		qd_setup(hwif, base, config);
+ 
++		hwif->port_init_devs = qd6500_port_init_devs;
+ 		hwif->set_pio_mode = &qd6500_set_pio_mode;
+ 
+-		idx[0] = unit;
++		idx[unit] = unit;
+ 
+-		ide_device_add(idx);
++		ide_device_add(idx, &qd65xx_port_info);
+ 
+ 		return 1;
+ 	}
+@@ -428,14 +450,15 @@ static int __init qd_probe(int base)
+ 			hwif = &ide_hwifs[unit];
+ 			printk(KERN_INFO "%s: qd6580: single IDE board\n",
+ 					 hwif->name);
+-			qd_setup(hwif, base, config | (control << 8),
+-				 QD6580_DEF_DATA, QD6580_DEF_DATA2);
+ 
++			qd_setup(hwif, base, config | (control << 8));
++
++			hwif->port_init_devs = qd6580_port_init_devs;
+ 			hwif->set_pio_mode = &qd6580_set_pio_mode;
+ 
+-			idx[0] = unit;
++			idx[unit] = unit;
+ 
+-			ide_device_add(idx);
++			ide_device_add(idx, &qd65xx_port_info);
+ 
+ 			outb(QD_DEF_CONTR, QD_CONTROL_PORT);
+ 
+@@ -449,20 +472,20 @@ static int __init qd_probe(int base)
+ 			printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n",
+ 					hwif->name, mate->name);
+ 
+-			qd_setup(hwif, base, config | (control << 8),
+-				 QD6580_DEF_DATA, QD6580_DEF_DATA);
++			qd_setup(hwif, base, config | (control << 8));
+ 
++			hwif->port_init_devs = qd6580_port_init_devs;
+ 			hwif->set_pio_mode = &qd6580_set_pio_mode;
+ 
+-			qd_setup(mate, base, config | (control << 8),
+-				 QD6580_DEF_DATA2, QD6580_DEF_DATA2);
++			qd_setup(mate, base, config | (control << 8));
+ 
++			mate->port_init_devs = qd6580_port_init_devs;
+ 			mate->set_pio_mode = &qd6580_set_pio_mode;
+ 
+ 			idx[0] = 0;
+ 			idx[1] = 1;
+ 
+-			ide_device_add(idx);
++			ide_device_add(idx, &qd65xx_port_info);
+ 
+ 			outb(QD_DEF_CONTR, QD_CONTROL_PORT);
+ 
+@@ -478,8 +501,7 @@ int probe_qd65xx = 0;
  module_param_named(probe, probe_qd65xx, bool, 0);
  MODULE_PARM_DESC(probe, "probe for QD65xx chipsets");
  
@@ -407936,7 +413581,7 @@
  {
  	if (probe_qd65xx == 0)
  		return -ENODEV;
-@@ -492,9 +489,7 @@ int __init qd65xx_init(void)
+@@ -492,9 +514,7 @@ int __init qd65xx_init(void)
  	return 0;
  }
  
@@ -407958,7 +413603,7 @@
   */
  
 diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
-index 79577b9..26f38ce 100644
+index 79577b9..5696ba0 100644
 --- a/drivers/ide/legacy/umc8672.c
 +++ b/drivers/ide/legacy/umc8672.c
 @@ -1,6 +1,4 @@
@@ -407968,7 +413613,48 @@
   *  Copyright (C) 1995-1996  Linus Torvalds & author (see below)
   */
  
-@@ -169,8 +167,7 @@ int probe_umc8672 = 0;
+@@ -122,9 +120,14 @@ static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
+ 	spin_unlock_irqrestore(&ide_lock, flags);
+ }
+ 
++static const struct ide_port_info umc8672_port_info __initdata = {
++	.chipset		= ide_umc8672,
++	.host_flags		= IDE_HFLAG_NO_DMA | IDE_HFLAG_NO_AUTOTUNE,
++	.pio_mask		= ATA_PIO4,
++};
++
+ static int __init umc8672_probe(void)
+ {
+-	ide_hwif_t *hwif, *mate;
+ 	unsigned long flags;
+ 	static u8 idx[4] = { 0, 1, 0xff, 0xff };
+ 
+@@ -145,21 +148,10 @@ static int __init umc8672_probe(void)
+ 	umc_set_speeds (current_speeds);
+ 	local_irq_restore(flags);
+ 
+-	hwif = &ide_hwifs[0];
+-	mate = &ide_hwifs[1];
+-
+-	hwif->chipset = ide_umc8672;
+-	hwif->pio_mask = ATA_PIO4;
+-	hwif->set_pio_mode = &umc_set_pio_mode;
+-	hwif->mate = mate;
+-
+-	mate->chipset = ide_umc8672;
+-	mate->pio_mask = ATA_PIO4;
+-	mate->set_pio_mode = &umc_set_pio_mode;
+-	mate->mate = hwif;
+-	mate->channel = 1;
++	ide_hwifs[0].set_pio_mode = &umc_set_pio_mode;
++	ide_hwifs[1].set_pio_mode = &umc_set_pio_mode;
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, &umc8672_port_info);
+ 
+ 	return 0;
+ }
+@@ -169,8 +161,7 @@ int probe_umc8672 = 0;
  module_param_named(probe, probe_umc8672, bool, 0);
  MODULE_PARM_DESC(probe, "probe for UMC8672 chipset");
  
@@ -407978,7 +413664,7 @@
  {
  	if (probe_umc8672 == 0)
  		goto out;
-@@ -181,9 +178,7 @@ out:
+@@ -181,9 +172,7 @@ out:
  	return -ENODEV;;
  }
  
@@ -407989,7 +413675,7 @@
  MODULE_AUTHOR("Wolfram Podien");
  MODULE_DESCRIPTION("Support for UMC 8672 IDE chipset");
 diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
-index a4ce3ba..cd42b30 100644
+index a4ce3ba..0f4bf5d 100644
 --- a/drivers/ide/mips/au1xxx-ide.c
 +++ b/drivers/ide/mips/au1xxx-ide.c
 @@ -1,6 +1,4 @@
@@ -408113,7 +413799,25 @@
  						PRD_ENTRIES * PRD_BYTES,        /* 1 Page */
  						&hwif->dmatable_dma, GFP_KERNEL);
  	
-@@ -610,9 +565,6 @@ static int au_ide_probe(struct device *dev)
+@@ -593,6 +548,17 @@ static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
+ 	*ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET);
+ }
+ 
++static const struct ide_port_info au1xxx_port_info = {
++	.host_flags		= IDE_HFLAG_POST_SET_MODE |
++				  IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
++				  IDE_HFLAG_NO_IO_32BIT |
++				  IDE_HFLAG_UNMASK_IRQS,
++	.pio_mask		= ATA_PIO4,
++#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
++	.mwdma_mask		= ATA_MWDMA2,
++#endif
++};
++
+ static int au_ide_probe(struct device *dev)
+ {
+ 	struct platform_device *pdev = to_platform_device(dev);
+@@ -610,9 +576,6 @@ static int au_ide_probe(struct device *dev)
  #endif
  
  	memset(&auide_hwif, 0, sizeof(_auide_hwif));
@@ -408123,7 +413827,7 @@
  	ahwif->irq = platform_get_irq(pdev, 0);
  
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-@@ -643,12 +595,16 @@ static int au_ide_probe(struct device *dev)
+@@ -643,28 +606,16 @@ static int au_ide_probe(struct device *dev)
  	/* FIXME:  This might possibly break PCMCIA IDE devices */
  
  	hwif                            = &ide_hwifs[pdev->id];
@@ -408136,22 +413840,28 @@
 +	hw.irq = ahwif->irq;
 +	hw.dev = dev;
 +	hw.chipset = ide_au1xxx;
-+
-+	ide_init_port_hw(hwif, &hw);
-+
-+	hwif->dev = dev;
  
- 	hwif->ultra_mask                = 0x0;  /* Disable Ultra DMA */
- #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-@@ -662,7 +618,6 @@ static int au_ide_probe(struct device *dev)
- 	hwif->pio_mask = ATA_PIO4;
- 	hwif->host_flags = IDE_HFLAG_POST_SET_MODE;
+-	hwif->ultra_mask                = 0x0;  /* Disable Ultra DMA */
+-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+-	hwif->mwdma_mask                = 0x07; /* Multimode-2 DMA  */
+-	hwif->swdma_mask                = 0x00;
+-#else
+-	hwif->mwdma_mask                = 0x0;
+-	hwif->swdma_mask                = 0x0;
+-#endif
+-
+-	hwif->pio_mask = ATA_PIO4;
+-	hwif->host_flags = IDE_HFLAG_POST_SET_MODE;
++	ide_init_port_hw(hwif, &hw);
  
 -	hwif->noprobe = 0;
- 	hwif->drives[0].unmask          = 1;
- 	hwif->drives[1].unmask          = 1;
+-	hwif->drives[0].unmask          = 1;
+-	hwif->drives[1].unmask          = 1;
++	hwif->dev = dev;
  
-@@ -684,29 +639,25 @@ static int au_ide_probe(struct device *dev)
+ 	/* hold should be on in all cases */
+ 	hwif->hold                      = 1;
+@@ -684,32 +635,21 @@ static int au_ide_probe(struct device *dev)
  	hwif->set_dma_mode		= &auide_set_dma_mode;
  
  #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
@@ -408171,30 +413881,41 @@
  	hwif->dma_lost_irq		= &auide_dma_lost_irq;
 -	hwif->ide_dma_on                = &auide_dma_on;
 -#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
-+#endif
- 	hwif->channel                   = 0;
+-	hwif->channel                   = 0;
 -	hwif->hold                      = 1;
++#endif
  	hwif->select_data               = 0;    /* no chipset-specific code */
  	hwif->config_data               = 0;    /* no chipset-specific code */
  
- 	hwif->drives[0].autotune        = 1;    /* 1=autotune, 2=noautotune, 0=default */
- 	hwif->drives[1].autotune	= 1;
+-	hwif->drives[0].autotune        = 1;    /* 1=autotune, 2=noautotune, 0=default */
+-	hwif->drives[1].autotune	= 1;
 -#endif
-+
- 	hwif->drives[0].no_io_32bit	= 1;
- 	hwif->drives[1].no_io_32bit	= 1;
+-	hwif->drives[0].no_io_32bit	= 1;
+-	hwif->drives[1].no_io_32bit	= 1;
+-
+ 	auide_hwif.hwif                 = hwif;
+ 	hwif->hwif_data                 = &auide_hwif;
+ 
+@@ -720,7 +660,7 @@ static int au_ide_probe(struct device *dev)
+ 
+ 	idx[0] = hwif->index;
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, &au1xxx_port_info);
+ 
+ 	dev_set_drvdata(dev, hwif);
  
-@@ -737,7 +688,7 @@ static int au_ide_remove(struct device *dev)
+@@ -737,7 +677,7 @@ static int au_ide_remove(struct device *dev)
  	ide_hwif_t *hwif = dev_get_drvdata(dev);
  	_auide_hwif *ahwif = &auide_hwif;
  
 -	ide_unregister(hwif - ide_hwifs);
-+	ide_unregister(hwif->index);
++	ide_unregister(hwif->index, 0, 0);
  
  	iounmap((void *)ahwif->regbase);
  
 diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
-index 521edd4..8b3959d 100644
+index 521edd4..956259f 100644
 --- a/drivers/ide/mips/swarm.c
 +++ b/drivers/ide/mips/swarm.c
 @@ -117,6 +117,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
@@ -408205,6 +413926,15 @@
  	hwif->noprobe = 0;
  
  	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
+@@ -128,7 +129,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
+ 
+ 	idx[0] = hwif->index;
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, NULL);
+ 
+ 	dev_set_drvdata(dev, hwif);
+ 
 diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
 index 95d1ea8..9480325 100644
 --- a/drivers/ide/pci/Makefile
@@ -408219,7 +413949,7 @@
 +
  EXTRA_CFLAGS	:= -Idrivers/ide
 diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
-index 4426850..824df78 100644
+index 4426850..cfb3265 100644
 --- a/drivers/ide/pci/aec62xx.c
 +++ b/drivers/ide/pci/aec62xx.c
 @@ -1,6 +1,4 @@
@@ -408229,7 +413959,15 @@
   * Copyright (C) 1999-2002	Andre Hedrick <andre at linux-ide.org>
   * Copyright (C) 2007		MontaVista Software, Inc. <source at mvista.com>
   *
-@@ -90,7 +88,7 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
+@@ -9,7 +7,6 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+@@ -90,7 +87,7 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
  static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -408238,7 +413976,7 @@
  	u16 d_conf		= 0;
  	u8 ultra = 0, ultra_conf = 0;
  	u8 tmp0 = 0, tmp1 = 0, tmp2 = 0;
-@@ -116,7 +114,7 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
+@@ -116,7 +113,7 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
  static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -408247,8 +413985,20 @@
  	u8 unit		= (drive->select.b.unit & 0x01);
  	u8 tmp1 = 0, tmp2 = 0;
  	u8 ultra = 0, drive_conf = 0, ultra_conf = 0;
-@@ -170,7 +168,7 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch
+@@ -168,29 +165,28 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch
+ 	return dev->irq;
+ }
  
++static u8 __devinit atp86x_cable_detect(ide_hwif_t *hwif)
++{
++	struct pci_dev *dev = to_pci_dev(hwif->dev);
++	u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01;
++
++	pci_read_config_byte(dev, 0x49, &ata66);
++
++	return (ata66 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
++}
++
  static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
  {
 -	struct pci_dev *dev	= hwif->pci_dev;
@@ -408256,16 +414006,29 @@
  
  	hwif->set_pio_mode = &aec_set_pio_mode;
  
-@@ -188,7 +186,7 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
- 	if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
- 		u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01;
+ 	if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
+ 		hwif->set_dma_mode = &aec6210_set_mode;
+-	else
++	else {
+ 		hwif->set_dma_mode = &aec6260_set_mode;
  
+-	if (hwif->dma_base == 0)
+-		return;
+-
+-	if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
+-		return;
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
+-		u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01;
+-
 -		pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
-+		pci_read_config_byte(dev, 0x49, &ata66);
- 
- 		hwif->cbl = (ata66 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
+-
+-		hwif->cbl = (ata66 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
++		hwif->cable_detect = atp86x_cable_detect;
  	}
-@@ -202,6 +200,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
+ }
+ 
+@@ -202,6 +198,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
  		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
  		.host_flags	= IDE_HFLAG_SERIALIZE |
  				  IDE_HFLAG_NO_ATAPI_DMA |
@@ -408274,7 +414037,7 @@
  				  IDE_HFLAG_OFF_BOARD,
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
-@@ -211,6 +211,7 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
+@@ -211,6 +209,7 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
  		.init_chipset	= init_chipset_aec62xx,
  		.init_hwif	= init_hwif_aec62xx,
  		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA |
@@ -408282,7 +414045,7 @@
  				  IDE_HFLAG_OFF_BOARD,
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
-@@ -220,7 +221,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
+@@ -220,7 +219,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
  		.init_chipset	= init_chipset_aec62xx,
  		.init_hwif	= init_hwif_aec62xx,
  		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
@@ -408292,7 +414055,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA4,
-@@ -228,7 +230,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
+@@ -228,7 +228,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
  		.name		= "AEC6280",
  		.init_chipset	= init_chipset_aec62xx,
  		.init_hwif	= init_hwif_aec62xx,
@@ -408303,7 +414066,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA5,
-@@ -237,7 +241,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
+@@ -237,7 +239,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
  		.init_chipset	= init_chipset_aec62xx,
  		.init_hwif	= init_hwif_aec62xx,
  		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
@@ -408315,7 +414078,7 @@
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA5,
 diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
-index ce29393..130cc6e 100644
+index ce29393..b3b6f51 100644
 --- a/drivers/ide/pci/alim15x3.c
 +++ b/drivers/ide/pci/alim15x3.c
 @@ -1,6 +1,4 @@
@@ -408325,7 +414088,15 @@
   *  Copyright (C) 1998-2000 Michel Aubry, Maintainer
   *  Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
   *  Copyright (C) 1999-2000 CJ, cjtsai at ali.com.tw, Maintainer
-@@ -293,7 +291,7 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
+@@ -33,7 +31,6 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+@@ -293,7 +290,7 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
  static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
  {
  	ide_hwif_t *hwif = HWIF(drive);
@@ -408334,7 +414105,7 @@
  	int s_time, a_time, c_time;
  	u8 s_clc, a_clc, r_clc;
  	unsigned long flags;
-@@ -396,15 +394,12 @@ static u8 ali_udma_filter(ide_drive_t *drive)
+@@ -396,15 +393,12 @@ static u8 ali_udma_filter(ide_drive_t *drive)
  static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -408351,7 +414122,7 @@
  	if (speed == XFER_UDMA_6)
  		speed1 = 0x47;
  
-@@ -628,7 +623,7 @@ static int ali_cable_override(struct pci_dev *pdev)
+@@ -628,7 +622,7 @@ static int ali_cable_override(struct pci_dev *pdev)
  
  static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif)
  {
@@ -408360,7 +414131,23 @@
  	unsigned long flags;
  	u8 cbl = ATA_CBL_PATA40, tmpbyte;
  
-@@ -691,12 +686,13 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
+@@ -671,13 +665,12 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
+ 	hwif->set_dma_mode = &ali_set_dma_mode;
+ 	hwif->udma_filter = &ali_udma_filter;
+ 
++	hwif->cable_detect = ata66_ali15x3;
++
+ 	if (hwif->dma_base == 0)
+ 		return;
+ 
+ 	hwif->dma_setup = &ali15x3_dma_setup;
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = ata66_ali15x3(hwif);
+ }
+ 
+ /**
+@@ -691,12 +684,13 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
  
  static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
  {
@@ -408375,7 +414162,7 @@
  		hwif->irq = hwif->channel ? 15 : 14;
  
  	if (isa_dev) {
-@@ -748,7 +744,7 @@ static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
+@@ -748,7 +742,7 @@ static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
  		return;
  	if (!hwif->channel)
  		outb(inb(dmabase + 2) & 0x60, dmabase + 2);
@@ -408384,7 +414171,7 @@
  }
  
  static const struct ide_port_info ali15x3_chipset __devinitdata = {
-@@ -778,7 +774,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
+@@ -778,7 +772,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
  	};
  
  	struct ide_port_info d = ali15x3_chipset;
@@ -408393,7 +414180,7 @@
  
  	if (pci_dev_present(ati_rs100))
  		printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
-@@ -801,6 +797,9 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
+@@ -801,6 +795,9 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
  			d.udma_mask = ATA_UDMA6;
  	}
  
@@ -408403,7 +414190,7 @@
  #if defined(CONFIG_SPARC64)
  	d.init_hwif = init_hwif_common_ali15x3;
  #endif /* CONFIG_SPARC64 */
-@@ -810,7 +809,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
+@@ -810,7 +807,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
  
  static const struct pci_device_id alim15x3_pci_tbl[] = {
  	{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), 0 },
@@ -408413,7 +414200,7 @@
  };
  MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl);
 diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
-index 8d4125e..8c52bc9 100644
+index 8d4125e..2ef890c 100644
 --- a/drivers/ide/pci/amd74xx.c
 +++ b/drivers/ide/pci/amd74xx.c
 @@ -1,6 +1,4 @@
@@ -408423,7 +414210,16 @@
   * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
   * IDE driver for Linux.
   *
-@@ -28,81 +26,46 @@
+@@ -19,90 +17,52 @@
+ 
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/ide.h>
+-#include <asm/io.h>
  
  #include "ide-timing.h"
  
@@ -408525,7 +414321,7 @@
  	case ATA_UDMA2: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
  	case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break;
  	case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break;
-@@ -110,7 +73,7 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi
+@@ -110,7 +70,7 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi
  	default: return;
  	}
  
@@ -408534,7 +414330,7 @@
  }
  
  /*
-@@ -120,12 +83,15 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi
+@@ -120,12 +80,15 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi
  
  static void amd_set_drive(ide_drive_t *drive, const u8 speed)
  {
@@ -408552,7 +414348,7 @@
  
  	ide_timing_compute(drive, speed, &t, T, UT);
  
-@@ -137,7 +103,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed)
+@@ -137,7 +100,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed)
  	if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1;
  	if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15;
  
@@ -408561,7 +414357,7 @@
  }
  
  /*
-@@ -149,67 +115,68 @@ static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -149,67 +112,68 @@ static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio)
  	amd_set_drive(drive, XFER_PIO_0 + pio);
  }
  
@@ -408674,7 +414470,7 @@
  
  /*
   * Determine the system bus clock.
-@@ -225,25 +192,19 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
+@@ -225,53 +189,44 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
  
  	if (amd_clock < 20000 || amd_clock > 50000) {
  		printk(KERN_WARNING "%s: User given PCI clock speed impossible (%d), using 33 MHz instead.\n",
@@ -408694,6 +414490,14 @@
  	return dev->irq;
  }
  
++static u8 __devinit amd_cable_detect(ide_hwif_t *hwif)
++{
++	if ((amd_80w >> hwif->channel) & 1)
++		return ATA_CBL_PATA80;
++	else
++		return ATA_CBL_PATA40;
++}
++
  static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
  {
 +	struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -408704,18 +414508,23 @@
  
  	hwif->set_pio_mode = &amd_set_pio_mode;
  	hwif->set_dma_mode = &amd_set_drive;
-@@ -251,10 +212,6 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
- 	if (!hwif->dma_base)
- 		return;
  
+-	if (!hwif->dma_base)
+-		return;
+-
 -	hwif->ultra_mask = amd_config->udma_mask;
 -	if (amd_config->flags & AMD_BAD_SWDMA)
 -		hwif->swdma_mask = 0x00;
 -
- 	if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
- 		if ((amd_80w >> hwif->channel) & 1)
- 			hwif->cbl = ATA_CBL_PATA80;
-@@ -266,12 +223,13 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
+-		if ((amd_80w >> hwif->channel) & 1)
+-			hwif->cbl = ATA_CBL_PATA80;
+-		else
+-			hwif->cbl = ATA_CBL_PATA40;
+-	}
++	hwif->cable_detect = amd_cable_detect;
+ }
+ 
  #define IDE_HFLAGS_AMD \
  	(IDE_HFLAG_PIO_NO_BLACKLIST | \
  	 IDE_HFLAG_PIO_NO_DOWNGRADE | \
@@ -408730,7 +414539,7 @@
  	{								\
  		.name		= name_str,				\
  		.init_chipset	= init_chipset_amd74xx,			\
-@@ -279,11 +237,12 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
+@@ -279,11 +234,12 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
  		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},	\
  		.host_flags	= IDE_HFLAGS_AMD,			\
  		.pio_mask	= ATA_PIO5,				\
@@ -408745,7 +414554,7 @@
  	{								\
  		.name		= name_str,				\
  		.init_chipset	= init_chipset_amd74xx,			\
-@@ -293,45 +252,62 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
+@@ -293,45 +249,62 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
  		.pio_mask	= ATA_PIO5,				\
  		.swdma_mask	= ATA_SWDMA2,				\
  		.mwdma_mask	= ATA_MWDMA2,				\
@@ -408840,7 +414649,7 @@
  
  static const struct pci_device_id amd74xx_pci_tbl[] = {
 diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
-index ef8e016..b56274a 100644
+index ef8e016..7e037c8 100644
 --- a/drivers/ide/pci/atiixp.c
 +++ b/drivers/ide/pci/atiixp.c
 @@ -1,6 +1,4 @@
@@ -408850,7 +414659,23 @@
   *  Copyright (C) 2003 ATI Inc. <hyu at ati.com>
   *  Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz
   */
-@@ -43,47 +41,8 @@ static atiixp_ide_timing mdma_timing[] = {
+@@ -8,15 +6,11 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/ioport.h>
+ #include <linux/pci.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+-#include <linux/delay.h>
+ #include <linux/init.h>
+ 
+-#include <asm/io.h>
+-
+ #define ATIIXP_IDE_PIO_TIMING		0x40
+ #define ATIIXP_IDE_MDMA_TIMING		0x44
+ #define ATIIXP_IDE_PIO_CONTROL		0x48
+@@ -43,47 +37,8 @@ static atiixp_ide_timing mdma_timing[] = {
  	{ 0x02, 0x00 },
  };
  
@@ -408898,7 +414723,7 @@
  /**
   *	atiixp_set_pio_mode	-	set host controller for PIO mode
   *	@drive: drive
-@@ -94,7 +53,7 @@ static void atiixp_dma_host_off(ide_drive_t *drive)
+@@ -94,7 +49,7 @@ static void atiixp_dma_host_off(ide_drive_t *drive)
  
  static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
  {
@@ -408907,7 +414732,7 @@
  	unsigned long flags;
  	int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
  	u32 pio_timing_data;
-@@ -127,34 +86,38 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -127,37 +82,54 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
  
  static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
  {
@@ -408960,30 +414785,51 @@
  	spin_unlock_irqrestore(&atiixp_lock, flags);
  }
  
-@@ -168,9 +131,8 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
++static u8 __devinit atiixp_cable_detect(ide_hwif_t *hwif)
++{
++	struct pci_dev *pdev = to_pci_dev(hwif->dev);
++	u8 udma_mode = 0, ch = hwif->channel;
++
++	pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode);
++
++	if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40)
++		return ATA_CBL_PATA80;
++	else
++		return ATA_CBL_PATA40;
++}
++
+ /**
+  *	init_hwif_atiixp		-	fill in the hwif for the ATIIXP
+  *	@hwif: IDE interface
+@@ -168,25 +140,10 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
  
  static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
  {
 -	u8 udma_mode = 0;
 -	u8 ch = hwif->channel;
 -	struct pci_dev *pdev = hwif->pci_dev;
-+	struct pci_dev *pdev = to_pci_dev(hwif->dev);
-+	u8 udma_mode = 0, ch = hwif->channel;
- 
+-
  	hwif->set_pio_mode = &atiixp_set_pio_mode;
  	hwif->set_dma_mode = &atiixp_set_dma_mode;
-@@ -184,9 +146,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
- 		hwif->cbl = ATA_CBL_PATA80;
- 	else
- 		hwif->cbl = ATA_CBL_PATA40;
+ 
+-	if (!hwif->dma_base)
+-		return;
+-
+-	pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode);
+-
+-	if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40)
+-		hwif->cbl = ATA_CBL_PATA80;
+-	else
+-		hwif->cbl = ATA_CBL_PATA40;
 -
 -	hwif->dma_host_on = &atiixp_dma_host_on;
 -	hwif->dma_host_off = &atiixp_dma_host_off;
++	hwif->cable_detect = atiixp_cable_detect;
  }
  
  static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
 diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
-index 4aa4810..7240c20 100644
+index 4aa4810..bd24dad 100644
 --- a/drivers/ide/pci/cmd640.c
 +++ b/drivers/ide/pci/cmd640.c
 @@ -1,6 +1,4 @@
@@ -408993,9 +414839,33 @@
   *  Copyright (C) 1995-1996  Linus Torvalds & authors (see below)
   */
  
-@@ -706,9 +704,9 @@ static int pci_conf2(void)
+@@ -105,10 +103,6 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+@@ -705,10 +699,22 @@ static int pci_conf2(void)
+ 	return 0;
  }
  
++static const struct ide_port_info cmd640_port_info __initdata = {
++	.chipset		= ide_cmd640,
++	.host_flags		= IDE_HFLAG_SERIALIZE |
++				  IDE_HFLAG_NO_DMA |
++				  IDE_HFLAG_NO_AUTOTUNE |
++				  IDE_HFLAG_ABUSE_PREFETCH |
++				  IDE_HFLAG_ABUSE_FAST_DEVSEL,
++#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
++	.pio_mask		= ATA_PIO5,
++#endif
++};
++
  /*
 - * Probe for a cmd640 chipset, and initialize it if found.  Called from ide.c
 + * Probe for a cmd640 chipset, and initialize it if found.
@@ -409005,7 +414875,7 @@
  {
  #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
  	int second_port_toggled = 0;
-@@ -717,6 +715,7 @@ int __init ide_probe_for_cmd640x (void)
+@@ -717,6 +723,7 @@ int __init ide_probe_for_cmd640x (void)
  	const char *bus_type, *port2;
  	unsigned int index;
  	u8 b, cfr;
@@ -409013,7 +414883,15 @@
  
  	if (cmd640_vlb && probe_for_cmd640_vlb()) {
  		bus_type = "VLB";
-@@ -769,6 +768,8 @@ int __init ide_probe_for_cmd640x (void)
+@@ -761,14 +768,12 @@ int __init ide_probe_for_cmd640x (void)
+ 	setup_device_ptrs ();
+ 	printk("%s: buggy cmd640%c interface on %s, config=0x%02x\n",
+ 	       cmd_hwif0->name, 'a' + cmd640_chip_version - 1, bus_type, cfr);
+-	cmd_hwif0->chipset = ide_cmd640;
+ #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
+-	cmd_hwif0->host_flags = IDE_HFLAG_ABUSE_PREFETCH |
+-				IDE_HFLAG_ABUSE_FAST_DEVSEL;
+-	cmd_hwif0->pio_mask = ATA_PIO5;
  	cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode;
  #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
  
@@ -409022,21 +414900,37 @@
  	/*
  	 * Ensure compatibility by always using the slowest timings
  	 * for access to the drive's command register block,
-@@ -826,6 +827,8 @@ int __init ide_probe_for_cmd640x (void)
- 		cmd_hwif1->pio_mask = ATA_PIO5;
+@@ -814,21 +819,14 @@ int __init ide_probe_for_cmd640x (void)
+ 	 * Initialize data for secondary cmd640 port, if enabled
+ 	 */
+ 	if (second_port_cmd640) {
+-		cmd_hwif0->serialized = 1;
+-		cmd_hwif1->serialized = 1;
+-		cmd_hwif1->chipset = ide_cmd640;
+-		cmd_hwif0->mate = cmd_hwif1;
+-		cmd_hwif1->mate = cmd_hwif0;
+-		cmd_hwif1->channel = 1;
+ #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
+-		cmd_hwif1->host_flags = IDE_HFLAG_ABUSE_PREFETCH |
+-					IDE_HFLAG_ABUSE_FAST_DEVSEL;
+-		cmd_hwif1->pio_mask = ATA_PIO5;
  		cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode;
  #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 +
 +		idx[1] = cmd_hwif1->index;
  	}
  	printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name,
- 		cmd_hwif0->serialized ? "" : "not ", port2);
-@@ -872,6 +875,13 @@ int __init ide_probe_for_cmd640x (void)
+-		cmd_hwif0->serialized ? "" : "not ", port2);
++			 second_port_cmd640 ? "" : "not ", port2);
+ 
+ 	/*
+ 	 * Establish initial timings/prefetch for all drives.
+@@ -872,6 +870,13 @@ int __init ide_probe_for_cmd640x (void)
  #ifdef CMD640_DUMP_REGS
  	cmd640_dump_regs();
  #endif
 +
-+	ide_device_add(idx);
++	ide_device_add(idx, &cmd640_port_info);
 +
  	return 1;
  }
@@ -409046,7 +414940,7 @@
 +
 +module_init(cmd640x_init);
 diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
-index bc55333..04aa9e5 100644
+index bc55333..edabe62 100644
 --- a/drivers/ide/pci/cmd64x.c
 +++ b/drivers/ide/pci/cmd64x.c
 @@ -1,6 +1,4 @@
@@ -409056,7 +414950,14 @@
   * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
   *           Due to massive hardware bugs, UltraDMA is only supported
   *           on the 646U2 and not on the 646U.
-@@ -22,8 +20,6 @@
+@@ -15,15 +13,12 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
  
  #include <asm/io.h>
  
@@ -409065,7 +414966,7 @@
  #define CMD_DEBUG 0
  
  #if CMD_DEBUG
-@@ -37,11 +33,6 @@
+@@ -37,11 +32,6 @@
   */
  #define CFR		0x50
  #define   CFR_INTR_CH0		0x04
@@ -409077,7 +414978,7 @@
  
  #define	CMDTIM		0x52
  #define	ARTTIM0		0x53
-@@ -60,108 +51,13 @@
+@@ -60,108 +50,13 @@
  #define MRDMODE		0x71
  #define   MRDMODE_INTR_CH0	0x04
  #define   MRDMODE_INTR_CH1	0x08
@@ -409186,7 +415087,7 @@
  static u8 quantize_timing(int timing, int quant)
  {
  	return (timing + quant - 1) / quant;
-@@ -173,7 +69,7 @@ static u8 quantize_timing(int timing, int quant)
+@@ -173,7 +68,7 @@ static u8 quantize_timing(int timing, int quant)
   */
  static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time)
  {
@@ -409195,7 +415096,7 @@
  	int clock_time		= 1000 / system_bus_clock();
  	u8  cycle_count, active_count, recovery_count, drwtim;
  	static const u8 recovery_values[] =
-@@ -220,7 +116,7 @@ static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_
+@@ -220,7 +115,7 @@ static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_
  static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -409204,7 +415105,7 @@
  	unsigned int cycle_time;
  	u8 setup_count, arttim = 0;
  
-@@ -285,7 +181,7 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -285,7 +180,7 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
  static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -409213,7 +415114,7 @@
  	u8 unit			= drive->dn & 0x01;
  	u8 regU = 0, pciU	= hwif->channel ? UDIDETCR1 : UDIDETCR0;
  
-@@ -322,8 +218,6 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -322,8 +217,6 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
  	case XFER_MW_DMA_0:
  		program_cycle_times(drive, 480, 215);
  		break;
@@ -409222,7 +415123,7 @@
  	}
  
  	if (speed >= XFER_SW_DMA_0)
-@@ -333,14 +227,15 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -333,14 +226,15 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
  static int cmd648_ide_dma_end (ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -409240,7 +415141,7 @@
  
  	return err;
  }
-@@ -348,7 +243,7 @@ static int cmd648_ide_dma_end (ide_drive_t *drive)
+@@ -348,7 +242,7 @@ static int cmd648_ide_dma_end (ide_drive_t *drive)
  static int cmd64x_ide_dma_end (ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -409249,7 +415150,7 @@
  	int irq_reg		= hwif->channel ? ARTTIM23 : CFR;
  	u8  irq_mask		= hwif->channel ? ARTTIM23_INTR_CH1 :
  						  CFR_INTR_CH0;
-@@ -365,10 +260,11 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive)
+@@ -365,10 +259,11 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive)
  static int cmd648_ide_dma_test_irq (ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -409262,7 +415163,7 @@
  
  #ifdef DEBUG
  	printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n",
-@@ -387,7 +283,7 @@ static int cmd648_ide_dma_test_irq (ide_drive_t *drive)
+@@ -387,7 +282,7 @@ static int cmd648_ide_dma_test_irq (ide_drive_t *drive)
  static int cmd64x_ide_dma_test_irq (ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -409271,7 +415172,7 @@
  	int irq_reg		= hwif->channel ? ARTTIM23 : CFR;
  	u8  irq_mask		= hwif->channel ? ARTTIM23_INTR_CH1 :
  						  CFR_INTR_CH0;
-@@ -472,22 +368,12 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
+@@ -472,22 +367,12 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
  	mrdmode &= ~0x30;
  	(void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02));
  
@@ -409295,7 +415196,7 @@
  	u8 bmidecsr = 0, mask	= hwif->channel ? 0x02 : 0x01;
  
  	switch (dev->device) {
-@@ -502,7 +388,7 @@ static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif)
+@@ -502,11 +387,13 @@ static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif)
  
  static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
  {
@@ -409304,7 +415205,23 @@
  
  	hwif->set_pio_mode = &cmd64x_set_pio_mode;
  	hwif->set_dma_mode = &cmd64x_set_dma_mode;
-@@ -555,7 +441,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
+ 
++	hwif->cable_detect = ata66_cmd64x;
++
+ 	if (!hwif->dma_base)
+ 		return;
+ 
+@@ -525,9 +412,6 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
+ 	if (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 5)
+ 		hwif->ultra_mask = 0x00;
+ 
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = ata66_cmd64x(hwif);
+-
+ 	switch (dev->device) {
+ 	case PCI_DEVICE_ID_CMD_648:
+ 	case PCI_DEVICE_ID_CMD_649:
+@@ -555,7 +439,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
  		.init_chipset	= init_chipset_cmd64x,
  		.init_hwif	= init_hwif_cmd64x,
  		.enablebits	= {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
@@ -409316,10 +415233,33 @@
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= 0x00, /* no udma */
 diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
-index 0466462..eb68a9a 100644
+index 0466462..0be1a82 100644
 --- a/drivers/ide/pci/cs5520.c
 +++ b/drivers/ide/pci/cs5520.c
-@@ -69,9 +69,8 @@ static struct pio_clocks cs5520_pio_clocks[]={
+@@ -35,22 +35,12 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+-
+-#include <linux/interrupt.h>
+ #include <linux/init.h>
+ #include <linux/pci.h>
+ #include <linux/ide.h>
+ #include <linux/dma-mapping.h>
+ 
+-#include <asm/io.h>
+-#include <asm/irq.h>
+-
+ struct pio_clocks
+ {
+ 	int address;
+@@ -69,9 +59,8 @@ static struct pio_clocks cs5520_pio_clocks[]={
  static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
  {
  	ide_hwif_t *hwif = HWIF(drive);
@@ -409330,7 +415270,7 @@
  
  	/* FIXME: if DMA = 1 do we need to set the DMA bit here ? */
  
-@@ -91,11 +90,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -91,11 +80,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
  	pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1),
  		(cs5520_pio_clocks[pio].recovery << 4) |
  		(cs5520_pio_clocks[pio].assert));
@@ -409342,7 +415282,7 @@
  }
  
  static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
-@@ -109,13 +103,14 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -109,13 +93,14 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
   *	We wrap the DMA activate to set the vdma flag. This is needed
   *	so that the IDE DMA layer issues PIO not DMA commands over the
   *	DMA channel
@@ -409362,7 +415302,7 @@
  }
  
  static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
-@@ -126,7 +121,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
+@@ -126,7 +111,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
  	if (hwif->dma_base == 0)
  		return;
  
@@ -409371,7 +415311,7 @@
  }
  
  #define DECLARE_CS_DEV(name_str)				\
-@@ -137,6 +132,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
+@@ -137,6 +122,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
  				  IDE_HFLAG_CS5520 |		\
  				  IDE_HFLAG_VDMA |		\
  				  IDE_HFLAG_NO_ATAPI_DMA |	\
@@ -409379,7 +415319,7 @@
  				  IDE_HFLAG_BOOTABLE,		\
  		.pio_mask	= ATA_PIO4,			\
  	}
-@@ -160,8 +156,14 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
+@@ -160,8 +146,14 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
  	ide_setup_pci_noise(dev, d);
  
  	/* We must not grab the entire device, it has 'ISA' space in its
@@ -409396,8 +415336,17 @@
  		printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
  		return -ENODEV;
  	}
+@@ -178,7 +170,7 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
+ 
+ 	ide_pci_setup_ports(dev, d, 14, &idx[0]);
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, d);
+ 
+ 	return 0;
+ }
 diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
-index 5476903..765aac3 100644
+index 5476903..941a134 100644
 --- a/drivers/ide/pci/cs5530.c
 +++ b/drivers/ide/pci/cs5530.c
 @@ -1,6 +1,4 @@
@@ -409407,7 +415356,27 @@
   * Copyright (C) 2000			Andre Hedrick <andre at linux-ide.org>
   * Copyright (C) 2000			Mark Lord <mlord at pobox.com>
   * Copyright (C) 2007			Bartlomiej Zolnierkiewicz
-@@ -116,8 +114,6 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
+@@ -17,18 +15,12 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+-#include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/ide.h>
++
+ #include <asm/io.h>
+-#include <asm/irq.h>
+ 
+ /*
+  * Here are the standard PIO mode 0-4 timings for each "format".
+@@ -116,8 +108,6 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
  		case XFER_MW_DMA_0:	timings = 0x00077771; break;
  		case XFER_MW_DMA_1:	timings = 0x00012121; break;
  		case XFER_MW_DMA_2:	timings = 0x00002020; break;
@@ -409417,7 +415386,7 @@
  	basereg = CS5530_BASEREG(drive->hwif);
  	reg = inl(basereg + 4);			/* get drive0 config register */
 diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
-index ddcbeba..66433aa 100644
+index ddcbeba..d7b5ea9 100644
 --- a/drivers/ide/pci/cs5535.c
 +++ b/drivers/ide/pci/cs5535.c
 @@ -1,6 +1,4 @@
@@ -409427,20 +415396,26 @@
   * Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
   * Copyright (C)      2007 Bartlomiej Zolnierkiewicz
   *
-@@ -177,20 +175,22 @@ static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
-  */
- static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
+@@ -157,8 +155,9 @@ static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio)
+ 	cs5535_set_speed(drive, XFER_PIO_0 + pio);
+ }
+ 
+-static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
++static u8 __devinit cs5535_cable_detect(ide_hwif_t *hwif)
  {
 +	struct pci_dev *dev = to_pci_dev(hwif->dev);
-+
+ 	u8 bit;
+ 
+ 	/* if a 80 wire cable was detected */
+@@ -180,17 +179,14 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
  	hwif->set_pio_mode = &cs5535_set_pio_mode;
  	hwif->set_dma_mode = &cs5535_set_dma_mode;
  
- 	if (hwif->dma_base == 0)
- 		return;
- 
+-	if (hwif->dma_base == 0)
+-		return;
+-
 -	hwif->cbl = cs5535_cable_detect(hwif->pci_dev);
-+	hwif->cbl = cs5535_cable_detect(dev);
++	hwif->cable_detect = cs5535_cable_detect;
  }
  
  static const struct ide_port_info cs5535_chipset __devinitdata = {
@@ -409453,7 +415428,7 @@
  	.mwdma_mask	= ATA_MWDMA2,
  	.udma_mask	= ATA_UDMA4,
 diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
-index 1cd4e9c..50100ac 100644
+index 1cd4e9c..724cbac 100644
 --- a/drivers/ide/pci/cy82c693.c
 +++ b/drivers/ide/pci/cy82c693.c
 @@ -1,6 +1,4 @@
@@ -409463,7 +415438,15 @@
   *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs at altavista.net), Maintainer
   *  Copyright (C) 1998-2002 Andre Hedrick <andre at linux-ide.org>, Integrator
   *
-@@ -176,17 +174,12 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
+@@ -47,7 +45,6 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+ 
+@@ -176,17 +173,12 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
   * set DMA mode a specific channel for CY82C693
   */
  
@@ -409485,7 +415468,7 @@
  
  #if CY82C693_DEBUG_LOGS
  	/* for debug let's show the previous values */
-@@ -199,7 +192,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
+@@ -199,7 +191,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
  		(data&0x3), ((data>>2)&1));
  #endif /* CY82C693_DEBUG_LOGS */
  
@@ -409494,7 +415477,7 @@
  
  	outb(index, CY82_INDEX_PORT);
  	outb(data, CY82_DATA_PORT);
-@@ -207,7 +200,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
+@@ -207,7 +199,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
  #if CY82C693_DEBUG_INFO
  	printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
  		drive->name, HWIF(drive)->channel, drive->select.b.unit,
@@ -409503,7 +415486,7 @@
  #endif /* CY82C693_DEBUG_INFO */
  
  	/* 
-@@ -230,43 +223,10 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
+@@ -230,43 +222,10 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
  #endif /* CY82C693_DEBUG_INFO */
  }
  
@@ -409548,7 +415531,7 @@
  	pio_clocks_t pclk;
  	unsigned int addrCtrl;
  
-@@ -429,18 +389,15 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
+@@ -429,18 +388,15 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
  static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
  {
  	hwif->set_pio_mode = &cy82c693_set_pio_mode;
@@ -409570,7 +415553,7 @@
  		primary = hwif;
  	else {
  		hwif->mate = primary;
-@@ -454,11 +411,11 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = {
+@@ -454,11 +410,11 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = {
  	.init_iops	= init_iops_cy82c693,
  	.init_hwif	= init_hwif_cy82c693,
  	.chipset	= ide_cy82c693,
@@ -409586,7 +415569,7 @@
  
  static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
-index 8382908..27e47fc 100644
+index 8382908..3f9cd64 100644
 --- a/drivers/ide/pci/delkin_cb.c
 +++ b/drivers/ide/pci/delkin_cb.c
 @@ -1,6 +1,4 @@
@@ -409596,25 +415579,92 @@
   *  Created 20 Oct 2004 by Mark Lord
   *
   *  Basic support for Delkin/ASKA/Workbit Cardbus CompactFlash adapter
-@@ -80,14 +78,14 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
+@@ -18,15 +16,14 @@
+  *  License.  See the file COPYING in the main directory of this archive for
+  *  more details.
+  */
+-#include <linux/autoconf.h>
++
+ #include <linux/types.h>
+ #include <linux/module.h>
+-#include <linux/mm.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+ #include <linux/pci.h>
++
+ #include <asm/io.h>
+ 
+ /*
+@@ -54,6 +51,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
+ 	ide_hwif_t *hwif = NULL;
+ 	ide_drive_t *drive;
+ 	int i, rc;
++	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ 
+ 	rc = pci_enable_device(dev);
+ 	if (rc) {
+@@ -80,20 +78,40 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
  	hw.irq = dev->irq;
  	hw.chipset = ide_pci;		/* this enables IRQ sharing */
  
 -	rc = ide_register_hw(&hw, &ide_undecoded_slave, 0, &hwif);
-+	rc = ide_register_hw(&hw, &ide_undecoded_slave, &hwif);
- 	if (rc < 0) {
- 		printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
- 		pci_disable_device(dev);
- 		return -ENODEV;
- 	}
+-	if (rc < 0) {
+-		printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
+-		pci_disable_device(dev);
+-		return -ENODEV;
+-	}
++	hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]);
++	if (hwif == NULL)
++		goto out_disable;
++
++	i = hwif->index;
++
++	if (hwif->present)
++		ide_unregister(i, 0, 0);
++	else if (!hwif->hold)
++		ide_init_port_data(hwif, i);
++
++	ide_init_port_hw(hwif, &hw);
++	hwif->quirkproc = &ide_undecoded_slave;
++
++	idx[0] = i;
++
++	ide_device_add(idx, NULL);
++
++	if (!hwif->present)
++		goto out_disable;
++
  	pci_set_drvdata(dev, hwif);
 -	hwif->pci_dev = dev;
 +	hwif->dev = &dev->dev;
  	drive = &hwif->drives[0];
  	if (drive->present) {
  		drive->io_32bit = 1;
+ 		drive->unmask   = 1;
+ 	}
+ 	return 0;
++
++out_disable:
++	printk(KERN_ERR "delkin_cb: no IDE devices found\n");
++	pci_disable_device(dev);
++	return -ENODEV;
+ }
+ 
+ static void
+@@ -102,7 +120,8 @@ delkin_cb_remove (struct pci_dev *dev)
+ 	ide_hwif_t *hwif = pci_get_drvdata(dev);
+ 
+ 	if (hwif)
+-		ide_unregister(hwif->index);
++		ide_unregister(hwif->index, 0, 0);
++
+ 	pci_disable_device(dev);
+ }
+ 
 diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
-index 0688569..59ebe84 100644
+index 0688569..9262a91 100644
 --- a/drivers/ide/pci/generic.c
 +++ b/drivers/ide/pci/generic.c
 @@ -1,6 +1,4 @@
@@ -409624,7 +415674,26 @@
   *  Copyright (C) 2001-2002	Andre Hedrick <andre at linux-ide.org>
   *  Portions (C) Copyright 2002  Red Hat Inc <alan at redhat.com>
   *
-@@ -104,7 +102,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
+@@ -24,18 +22,11 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/pci.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+ 
+-#include <asm/io.h>
+-
+ static int ide_generic_all;		/* Set to claim all devices */
+ 
+ /*
+@@ -104,7 +95,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
  
  	{	/* 14 */
  		.name		= "Revolution",
@@ -409635,7 +415704,7 @@
  		.swdma_mask	= ATA_SWDMA2,
  		.mwdma_mask	= ATA_MWDMA2,
 diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
-index ae6307f..25dbb81 100644
+index ae6307f..9f01da4 100644
 --- a/drivers/ide/pci/hpt34x.c
 +++ b/drivers/ide/pci/hpt34x.c
 @@ -1,7 +1,6 @@
@@ -409647,7 +415716,25 @@
   * May be copied or modified under the terms of the GNU General Public License
   *
   *
-@@ -45,7 +44,7 @@
+@@ -27,25 +26,18 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+ #include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/ide.h>
+ 
+-#include <asm/io.h>
+-#include <asm/irq.h>
+-
+ #define HPT343_DEBUG_DRIVE_INFO		0
  
  static void hpt34x_set_mode(ide_drive_t *drive, const u8 speed)
  {
@@ -409656,7 +415743,7 @@
  	u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
  	u8			hi_speed, lo_speed;
  
-@@ -129,14 +128,19 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
+@@ -129,14 +121,19 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
  	hwif->set_dma_mode = &hpt34x_set_mode;
  }
  
@@ -409678,7 +415765,7 @@
  		.pio_mask	= ATA_PIO5,
  	},
  	{ /* 1 */
-@@ -144,9 +148,7 @@ static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
+@@ -144,9 +141,7 @@ static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
  		.init_chipset	= init_chipset_hpt34x,
  		.init_hwif	= init_hwif_hpt34x,
  		.extra		= 16,
@@ -409690,7 +415777,7 @@
  #ifdef CONFIG_HPT34X_AUTODMA
  		.swdma_mask	= ATA_SWDMA2,
 diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
-index 9fce25b..5623cad 100644
+index 9fce25b..d0f7bb8 100644
 --- a/drivers/ide/pci/hpt366.c
 +++ b/drivers/ide/pci/hpt366.c
 @@ -1,6 +1,4 @@
@@ -409709,7 +415796,28 @@
   *   separate the UltraDMA and MWDMA masks there to avoid changing PIO timings
   *   when setting an UltraDMA mode
   * - fix hpt3xx_tune_drive() to set the PIO mode requested, not always select
-@@ -458,6 +456,13 @@ enum ata_clock {
+@@ -123,12 +121,8 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+ #include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+-
+ #include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+@@ -136,7 +130,6 @@
+ 
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+-#include <asm/irq.h>
+ 
+ /* various tuning parameters */
+ #define HPT_RESET_STATE_ENGINE
+@@ -458,6 +451,13 @@ enum ata_clock {
  	NUM_ATA_CLOCKS
  };
  
@@ -409723,7 +415831,7 @@
  /*
   *	Hold all the HighPoint chip information in one place.
   */
-@@ -468,7 +473,8 @@ struct hpt_info {
+@@ -468,7 +468,8 @@ struct hpt_info {
  	u8 udma_mask;		/* Allowed UltraDMA modes mask. */
  	u8 dpll_clk;		/* DPLL clock in MHz */
  	u8 pci_clk;		/* PCI  clock in MHz */
@@ -409733,7 +415841,7 @@
  };
  
  /* Supported HighPoint chips */
-@@ -486,20 +492,30 @@ enum {
+@@ -486,20 +487,30 @@ enum {
  	HPT371N
  };
  
@@ -409776,7 +415884,7 @@
  };
  
  static const struct hpt_info hpt36x __devinitdata = {
-@@ -507,7 +523,7 @@ static const struct hpt_info hpt36x __devinitdata = {
+@@ -507,7 +518,7 @@ static const struct hpt_info hpt36x __devinitdata = {
  	.chip_type	= HPT36x,
  	.udma_mask	= HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2,
  	.dpll_clk	= 0,	/* no DPLL */
@@ -409785,7 +415893,7 @@
  };
  
  static const struct hpt_info hpt370 __devinitdata = {
-@@ -515,7 +531,7 @@ static const struct hpt_info hpt370 __devinitdata = {
+@@ -515,7 +526,7 @@ static const struct hpt_info hpt370 __devinitdata = {
  	.chip_type	= HPT370,
  	.udma_mask	= HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
  	.dpll_clk	= 48,
@@ -409794,7 +415902,7 @@
  };
  
  static const struct hpt_info hpt370a __devinitdata = {
-@@ -523,7 +539,7 @@ static const struct hpt_info hpt370a __devinitdata = {
+@@ -523,7 +534,7 @@ static const struct hpt_info hpt370a __devinitdata = {
  	.chip_type	= HPT370A,
  	.udma_mask	= HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
  	.dpll_clk	= 48,
@@ -409803,7 +415911,7 @@
  };
  
  static const struct hpt_info hpt374 __devinitdata = {
-@@ -531,7 +547,7 @@ static const struct hpt_info hpt374 __devinitdata = {
+@@ -531,7 +542,7 @@ static const struct hpt_info hpt374 __devinitdata = {
  	.chip_type	= HPT374,
  	.udma_mask	= ATA_UDMA5,
  	.dpll_clk	= 48,
@@ -409812,7 +415920,7 @@
  };
  
  static const struct hpt_info hpt372 __devinitdata = {
-@@ -539,7 +555,7 @@ static const struct hpt_info hpt372 __devinitdata = {
+@@ -539,7 +550,7 @@ static const struct hpt_info hpt372 __devinitdata = {
  	.chip_type	= HPT372,
  	.udma_mask	= HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
  	.dpll_clk	= 55,
@@ -409821,7 +415929,7 @@
  };
  
  static const struct hpt_info hpt372a __devinitdata = {
-@@ -547,7 +563,7 @@ static const struct hpt_info hpt372a __devinitdata = {
+@@ -547,7 +558,7 @@ static const struct hpt_info hpt372a __devinitdata = {
  	.chip_type	= HPT372A,
  	.udma_mask	= HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
  	.dpll_clk	= 66,
@@ -409830,7 +415938,7 @@
  };
  
  static const struct hpt_info hpt302 __devinitdata = {
-@@ -555,7 +571,7 @@ static const struct hpt_info hpt302 __devinitdata = {
+@@ -555,7 +566,7 @@ static const struct hpt_info hpt302 __devinitdata = {
  	.chip_type	= HPT302,
  	.udma_mask	= HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
  	.dpll_clk	= 66,
@@ -409839,7 +415947,7 @@
  };
  
  static const struct hpt_info hpt371 __devinitdata = {
-@@ -563,7 +579,7 @@ static const struct hpt_info hpt371 __devinitdata = {
+@@ -563,7 +574,7 @@ static const struct hpt_info hpt371 __devinitdata = {
  	.chip_type	= HPT371,
  	.udma_mask	= HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
  	.dpll_clk	= 66,
@@ -409848,7 +415956,7 @@
  };
  
  static const struct hpt_info hpt372n __devinitdata = {
-@@ -571,7 +587,7 @@ static const struct hpt_info hpt372n __devinitdata = {
+@@ -571,7 +582,7 @@ static const struct hpt_info hpt372n __devinitdata = {
  	.chip_type	= HPT372N,
  	.udma_mask	= HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
  	.dpll_clk	= 77,
@@ -409857,7 +415965,7 @@
  };
  
  static const struct hpt_info hpt302n __devinitdata = {
-@@ -579,7 +595,7 @@ static const struct hpt_info hpt302n __devinitdata = {
+@@ -579,7 +590,7 @@ static const struct hpt_info hpt302n __devinitdata = {
  	.chip_type	= HPT302N,
  	.udma_mask	= HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
  	.dpll_clk	= 77,
@@ -409866,7 +415974,7 @@
  };
  
  static const struct hpt_info hpt371n __devinitdata = {
-@@ -587,7 +603,7 @@ static const struct hpt_info hpt371n __devinitdata = {
+@@ -587,7 +598,7 @@ static const struct hpt_info hpt371n __devinitdata = {
  	.chip_type	= HPT371N,
  	.udma_mask	= HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
  	.dpll_clk	= 77,
@@ -409875,7 +415983,7 @@
  };
  
  static int check_in_drive_list(ide_drive_t *drive, const char **list)
-@@ -608,7 +624,8 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
+@@ -608,7 +619,8 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
  static u8 hpt3xx_udma_filter(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -409885,7 +415993,7 @@
  	u8 mask 		= hwif->ultra_mask;
  
  	switch (info->chip_type) {
-@@ -647,7 +664,8 @@ static u8 hpt3xx_udma_filter(ide_drive_t *drive)
+@@ -647,7 +659,8 @@ static u8 hpt3xx_udma_filter(ide_drive_t *drive)
  static u8 hpt3xx_mdma_filter(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -409895,7 +416003,7 @@
  
  	switch (info->chip_type) {
  	case HPT372 :
-@@ -675,100 +693,56 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
+@@ -675,100 +688,56 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
  	for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++)
  		if (xfer_speeds[i] == speed)
  			break;
@@ -410015,7 +416123,7 @@
  	struct hpt_info *info	= pci_get_drvdata(dev);
  
  	if (drive->quirk_list) {
-@@ -800,7 +774,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
+@@ -800,7 +769,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
   */
  static void hpt366_dma_lost_irq(ide_drive_t *drive)
  {
@@ -410024,7 +416132,7 @@
  	u8 mcr1 = 0, mcr3 = 0, scr1 = 0;
  
  	pci_read_config_byte(dev, 0x50, &mcr1);
-@@ -816,18 +790,20 @@ static void hpt366_dma_lost_irq(ide_drive_t *drive)
+@@ -816,18 +785,20 @@ static void hpt366_dma_lost_irq(ide_drive_t *drive)
  static void hpt370_clear_engine(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif = HWIF(drive);
@@ -410047,7 +416155,7 @@
  	printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff);
  
  	/* get DMA command mode */
-@@ -870,10 +846,11 @@ static void hpt370_dma_timeout(ide_drive_t *drive)
+@@ -870,10 +841,11 @@ static void hpt370_dma_timeout(ide_drive_t *drive)
  static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -410060,7 +416168,7 @@
  	if (bfifo & 0x1FF) {
  //		printk("%s: %d bytes in FIFO\n", drive->name, bfifo);
  		return 0;
-@@ -893,7 +870,7 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
+@@ -893,7 +865,7 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
  static int hpt374_ide_dma_end(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -410069,7 +416177,7 @@
  	u8 mcr	= 0, mcr_addr	= hwif->select_data;
  	u8 bwsr = 0, mask	= hwif->channel ? 0x02 : 0x01;
  
-@@ -914,32 +891,33 @@ static int hpt374_ide_dma_end(ide_drive_t *drive)
+@@ -914,32 +886,33 @@ static int hpt374_ide_dma_end(ide_drive_t *drive)
  
  static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
  {
@@ -410113,7 +416221,7 @@
  }
  
  /**
-@@ -967,7 +945,7 @@ static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
+@@ -967,7 +940,7 @@ static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
  static int hpt3xx_busproc(ide_drive_t *drive, int state)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -410122,7 +416230,7 @@
  	u8  mcr_addr		= hwif->select_data + 2;
  	u8  resetmask		= hwif->channel ? 0x80 : 0x40;
  	u8  bsr2		= 0;
-@@ -1210,7 +1188,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
+@@ -1210,7 +1183,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
  	 * We also  don't like using  the DPLL because this causes glitches
  	 * on PRST-/SRST- when the state engine gets reset...
  	 */
@@ -410131,7 +416239,7 @@
  		u16 f_low, delta = pci_clk < 50 ? 2 : 4;
  		int adjust;
  
-@@ -1226,7 +1204,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
+@@ -1226,7 +1199,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
  			clock = ATA_CLOCK_50MHZ;
  		}
  
@@ -410140,7 +416248,7 @@
  			printk(KERN_ERR "%s: unknown bus timing!\n", name);
  			kfree(info);
  			return -EIO;
-@@ -1267,15 +1245,10 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
+@@ -1267,15 +1240,10 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
  		printk("%s: using %d MHz PCI clock\n", name, pci_clk);
  	}
  
@@ -410157,16 +416265,65 @@
  
  	/* Point to this chip's own instance of the hpt_info structure. */
  	pci_set_drvdata(dev, info);
-@@ -1308,7 +1281,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
+@@ -1306,12 +1274,55 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
+ 	return dev->irq;
+ }
  
++static u8 __devinit hpt3xx_cable_detect(ide_hwif_t *hwif)
++{
++	struct pci_dev	*dev	= to_pci_dev(hwif->dev);
++	struct hpt_info *info	= pci_get_drvdata(dev);
++	u8 chip_type		= info->chip_type;
++	u8 scr1 = 0, ata66	= hwif->channel ? 0x01 : 0x02;
++
++	/*
++	 * The HPT37x uses the CBLID pins as outputs for MA15/MA16
++	 * address lines to access an external EEPROM.  To read valid
++	 * cable detect state the pins must be enabled as inputs.
++	 */
++	if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) {
++		/*
++		 * HPT374 PCI function 1
++		 * - set bit 15 of reg 0x52 to enable TCBLID as input
++		 * - set bit 15 of reg 0x56 to enable FCBLID as input
++		 */
++		u8  mcr_addr = hwif->select_data + 2;
++		u16 mcr;
++
++		pci_read_config_word(dev, mcr_addr, &mcr);
++		pci_write_config_word(dev, mcr_addr, (mcr | 0x8000));
++		/* now read cable id register */
++		pci_read_config_byte(dev, 0x5a, &scr1);
++		pci_write_config_word(dev, mcr_addr, mcr);
++	} else if (chip_type >= HPT370) {
++		/*
++		 * HPT370/372 and 374 pcifn 0
++		 * - clear bit 0 of reg 0x5b to enable P/SCBLID as inputs
++		 */
++		u8 scr2 = 0;
++
++		pci_read_config_byte(dev, 0x5b, &scr2);
++		pci_write_config_byte(dev, 0x5b, (scr2 & ~1));
++		/* now read cable id register */
++		pci_read_config_byte(dev, 0x5a, &scr1);
++		pci_write_config_byte(dev, 0x5b,  scr2);
++	} else
++		pci_read_config_byte(dev, 0x5a, &scr1);
++
++	return (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
++}
++
  static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
  {
 -	struct pci_dev	*dev	= hwif->pci_dev;
 +	struct pci_dev *dev	= to_pci_dev(hwif->dev);
  	struct hpt_info *info	= pci_get_drvdata(dev);
  	int serialize		= HPT_SERIALIZE_IO;
- 	u8  scr1 = 0, ata66	= hwif->channel ? 0x01 : 0x02;
-@@ -1320,8 +1293,8 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
+-	u8  scr1 = 0, ata66	= hwif->channel ? 0x01 : 0x02;
+ 	u8  chip_type		= info->chip_type;
+ 	u8  new_mcr, old_mcr	= 0;
+ 
+@@ -1320,14 +1331,16 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
  
  	hwif->set_pio_mode	= &hpt3xx_set_pio_mode;
  	hwif->set_dma_mode	= &hpt3xx_set_mode;
@@ -410176,7 +416333,59 @@
  	hwif->maskproc		= &hpt3xx_maskproc;
  	hwif->busproc		= &hpt3xx_busproc;
  
-@@ -1423,7 +1396,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
+ 	hwif->udma_filter	= &hpt3xx_udma_filter;
+ 	hwif->mdma_filter	= &hpt3xx_mdma_filter;
+ 
++	hwif->cable_detect	= hpt3xx_cable_detect;
++
+ 	/*
+ 	 * HPT3xxN chips have some complications:
+ 	 *
+@@ -1373,43 +1386,6 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
+ 	if (hwif->dma_base == 0)
+ 		return;
+ 
+-	/*
+-	 * The HPT37x uses the CBLID pins as outputs for MA15/MA16
+-	 * address lines to access an external EEPROM.  To read valid
+-	 * cable detect state the pins must be enabled as inputs.
+-	 */
+-	if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) {
+-		/*
+-		 * HPT374 PCI function 1
+-		 * - set bit 15 of reg 0x52 to enable TCBLID as input
+-		 * - set bit 15 of reg 0x56 to enable FCBLID as input
+-		 */
+-		u8  mcr_addr = hwif->select_data + 2;
+-		u16 mcr;
+-
+-		pci_read_config_word (dev, mcr_addr, &mcr);
+-		pci_write_config_word(dev, mcr_addr, (mcr | 0x8000));
+-		/* now read cable id register */
+-		pci_read_config_byte (dev, 0x5a, &scr1);
+-		pci_write_config_word(dev, mcr_addr, mcr);
+-	} else if (chip_type >= HPT370) {
+-		/*
+-		 * HPT370/372 and 374 pcifn 0
+-		 * - clear bit 0 of reg 0x5b to enable P/SCBLID as inputs
+-		 */
+-		u8 scr2 = 0;
+-
+-		pci_read_config_byte (dev, 0x5b, &scr2);
+-		pci_write_config_byte(dev, 0x5b, (scr2 & ~1));
+-		/* now read cable id register */
+-		pci_read_config_byte (dev, 0x5a, &scr1);
+-		pci_write_config_byte(dev, 0x5b,  scr2);
+-	} else
+-		pci_read_config_byte (dev, 0x5a, &scr1);
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
+-
+ 	if (chip_type >= HPT374) {
+ 		hwif->ide_dma_test_irq	= &hpt374_ide_dma_test_irq;
+ 		hwif->ide_dma_end	= &hpt374_ide_dma_end;
+@@ -1423,7 +1399,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
  
  static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
  {
@@ -410185,7 +416394,7 @@
  	u8 masterdma	= 0, slavedma	= 0;
  	u8 dma_new	= 0, dma_old	= 0;
  	unsigned long flags;
-@@ -1443,7 +1416,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
+@@ -1443,7 +1419,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
  
  	local_irq_restore(flags);
  
@@ -410194,7 +416403,7 @@
  }
  
  static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
-@@ -1494,6 +1467,11 @@ static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
+@@ -1494,6 +1470,11 @@ static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
  	return 0;
  }
  
@@ -410206,7 +416415,7 @@
  static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
  	{	/* 0 */
  		.name		= "HPT36x",
-@@ -1508,9 +1486,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+@@ -1508,9 +1489,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
  		 */
  		.enablebits	= {{0x50,0x10,0x10}, {0x54,0x04,0x04}},
  		.extra		= 240,
@@ -410217,7 +416426,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  	},{	/* 1 */
-@@ -1520,7 +1496,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+@@ -1520,7 +1499,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
  		.init_dma	= init_dma_hpt366,
  		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
  		.extra		= 240,
@@ -410226,7 +416435,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  	},{	/* 2 */
-@@ -1530,7 +1506,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+@@ -1530,7 +1509,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
  		.init_dma	= init_dma_hpt366,
  		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
  		.extra		= 240,
@@ -410235,7 +416444,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  	},{	/* 3 */
-@@ -1540,7 +1516,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+@@ -1540,7 +1519,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
  		.init_dma	= init_dma_hpt366,
  		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
  		.extra		= 240,
@@ -410244,7 +416453,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  	},{	/* 4 */
-@@ -1551,7 +1527,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+@@ -1551,7 +1530,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
  		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
  		.udma_mask	= ATA_UDMA5,
  		.extra		= 240,
@@ -410253,7 +416462,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  	},{	/* 5 */
-@@ -1561,7 +1537,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+@@ -1561,7 +1540,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
  		.init_dma	= init_dma_hpt366,
  		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
  		.extra		= 240,
@@ -410263,10 +416472,24 @@
  		.mwdma_mask	= ATA_MWDMA2,
  	}
 diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
-index 90b52ed..df74e58 100644
+index 90b52ed..e3427ea 100644
 --- a/drivers/ide/pci/it8213.c
 +++ b/drivers/ide/pci/it8213.c
-@@ -28,7 +28,7 @@
+@@ -10,13 +10,10 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+ 
+-#include <asm/io.h>
+-
+ /**
+  *	it8213_set_pio_mode	-	set host controller for PIO mode
+  *	@drive: drive
+@@ -28,7 +25,7 @@
  static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -410275,7 +416498,7 @@
  	int is_slave		= drive->dn & 1;
  	int master_port		= 0x40;
  	int slave_port		= 0x44;
-@@ -85,7 +85,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -85,7 +82,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
  static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -410284,7 +416507,7 @@
  	u8 maslave		= 0x40;
  	int a_speed		= 3 << (drive->dn * 4);
  	int u_flag		= 1 << drive->dn;
-@@ -101,24 +101,11 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -101,24 +98,11 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
  	pci_read_config_byte(dev, 0x54, &reg54);
  	pci_read_config_byte(dev, 0x55, &reg55);
  
@@ -410313,25 +416536,45 @@
  		if (!(reg48 & u_flag))
  			pci_write_config_byte(dev, 0x48, reg48 | u_flag);
  		if (speed >= XFER_UDMA_5) {
-@@ -165,6 +152,7 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -156,6 +140,16 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
+ 	}
+ }
  
- static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
- {
++static u8 __devinit it8213_cable_detect(ide_hwif_t *hwif)
++{
 +	struct pci_dev *dev = to_pci_dev(hwif->dev);
- 	u8 reg42h = 0;
++	u8 reg42h = 0;
++
++	pci_read_config_byte(dev, 0x42, &reg42h);
++
++	return (reg42h & 0x02) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
++}
++
+ /**
+  *	init_hwif_it8213	-	set up hwif structs
+  *	@hwif: interface to set up
+@@ -165,18 +159,10 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
  
+ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
+ {
+-	u8 reg42h = 0;
+-
  	hwif->set_dma_mode = &it8213_set_dma_mode;
-@@ -173,7 +161,7 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
- 	if (!hwif->dma_base)
- 		return;
+ 	hwif->set_pio_mode = &it8213_set_pio_mode;
  
+-	if (!hwif->dma_base)
+-		return;
+-
 -	pci_read_config_byte(hwif->pci_dev, 0x42, &reg42h);
-+	pci_read_config_byte(dev, 0x42, &reg42h);
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = (reg42h & 0x02) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
++	hwif->cable_detect = it8213_cable_detect;
+ }
+ 
  
- 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
- 		hwif->cbl = (reg42h & 0x02) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
 diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
-index 99b7d76..938d35f 100644
+index 99b7d76..1597f0c 100644
 --- a/drivers/ide/pci/it821x.c
 +++ b/drivers/ide/pci/it821x.c
 @@ -1,7 +1,4 @@
@@ -410342,7 +416585,21 @@
   * Copyright (C) 2004		Red Hat <alan at redhat.com>
   * Copyright (C) 2007		Bartlomiej Zolnierkiewicz
   *
-@@ -113,7 +110,8 @@ static int it8212_noraid;
+@@ -66,13 +63,10 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+ 
+-#include <asm/io.h>
+-
+ struct it821x_dev
+ {
+ 	unsigned int smart:1,		/* Are we in smart raid mode */
+@@ -113,7 +107,8 @@ static int it8212_noraid;
  
  static void it821x_program(ide_drive_t *drive, u16 timing)
  {
@@ -410352,7 +416609,7 @@
  	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
  	int channel = hwif->channel;
  	u8 conf;
-@@ -123,7 +121,8 @@ static void it821x_program(ide_drive_t *drive, u16 timing)
+@@ -123,7 +118,8 @@ static void it821x_program(ide_drive_t *drive, u16 timing)
  		conf = timing >> 8;
  	else
  		conf = timing & 0xFF;
@@ -410362,7 +416619,7 @@
  }
  
  /**
-@@ -137,7 +136,8 @@ static void it821x_program(ide_drive_t *drive, u16 timing)
+@@ -137,7 +133,8 @@ static void it821x_program(ide_drive_t *drive, u16 timing)
  
  static void it821x_program_udma(ide_drive_t *drive, u16 timing)
  {
@@ -410372,7 +416629,7 @@
  	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
  	int channel = hwif->channel;
  	int unit = drive->select.b.unit;
-@@ -148,11 +148,12 @@ static void it821x_program_udma(ide_drive_t *drive, u16 timing)
+@@ -148,11 +145,12 @@ static void it821x_program_udma(ide_drive_t *drive, u16 timing)
  		conf = timing >> 8;
  	else
  		conf = timing & 0xFF;
@@ -410389,7 +416646,7 @@
  	}
  }
  
-@@ -167,6 +168,7 @@ static void it821x_program_udma(ide_drive_t *drive, u16 timing)
+@@ -167,6 +165,7 @@ static void it821x_program_udma(ide_drive_t *drive, u16 timing)
  static void it821x_clock_strategy(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif = drive->hwif;
@@ -410397,7 +416654,7 @@
  	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
  
  	u8 unit = drive->select.b.unit;
-@@ -205,10 +207,11 @@ static void it821x_clock_strategy(ide_drive_t *drive)
+@@ -205,10 +204,11 @@ static void it821x_clock_strategy(ide_drive_t *drive)
  		itdev->clock_mode = ATA_50;
  		sel = 1;
  	}
@@ -410411,7 +416668,7 @@
  
  	/*
  	 *	Reprogram the UDMA/PIO of the pair drive for the switch
-@@ -282,7 +285,8 @@ static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -282,7 +282,8 @@ static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
  
  static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)
  {
@@ -410421,7 +416678,7 @@
  	struct it821x_dev *itdev = (void *)ide_get_hwifdata(hwif);
  	int unit = drive->select.b.unit;
  	int channel = hwif->channel;
-@@ -297,12 +301,12 @@ static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)
+@@ -297,12 +298,12 @@ static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)
  	itdev->udma[unit] = UDMA_OFF;
  
  	/* UDMA bits off - Revision 0x10 do them in pairs */
@@ -410437,7 +416694,7 @@
  
  	it821x_clock_strategy(drive);
  	/* FIXME: do we need to program this ? */
-@@ -320,7 +324,8 @@ static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)
+@@ -320,7 +321,8 @@ static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)
  
  static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted)
  {
@@ -410447,7 +416704,7 @@
  	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
  	int unit = drive->select.b.unit;
  	int channel = hwif->channel;
-@@ -337,12 +342,12 @@ static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted)
+@@ -337,12 +339,12 @@ static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted)
  		itdev->udma[unit] |= 0x8080;	/* UDMA 5/6 select on */
  
  	/* UDMA on. Again revision 0x10 must do the pair */
@@ -410463,7 +416720,7 @@
  
  	it821x_clock_strategy(drive);
  	it821x_program_udma(drive, itdev->udma[unit]);
-@@ -431,33 +436,29 @@ static u8 __devinit ata66_it821x(ide_hwif_t *hwif)
+@@ -431,33 +433,29 @@ static u8 __devinit ata66_it821x(ide_hwif_t *hwif)
  }
  
  /**
@@ -410507,7 +416764,7 @@
  	/*
  	 *	Perform fixups on smart mode. We need to "lose" some
  	 *	capabilities the firmware lacks but does not filter, and
-@@ -465,16 +466,6 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
+@@ -465,16 +463,6 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
  	 *	in RAID mode.
  	 */
  
@@ -410524,7 +416781,7 @@
  		/* Check for RAID v native */
  		if(strstr(id->model, "Integrated Technology Express")) {
  			/* In raid mode the ident block is slightly buggy
-@@ -534,9 +525,12 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
+@@ -534,9 +522,12 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
  
  static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
  {
@@ -410537,7 +416794,7 @@
  	if (idev == NULL) {
  		printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
  		return;
-@@ -544,7 +538,7 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
+@@ -544,7 +535,7 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
  
  	ide_set_hwifdata(hwif, idev);
  
@@ -410546,7 +416803,7 @@
  	if (conf & 1) {
  		idev->smart = 1;
  		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
-@@ -567,7 +561,7 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
+@@ -567,7 +558,7 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
  	 *	this is necessary.
  	 */
  
@@ -410555,7 +416812,24 @@
  	if (conf == 0x10) {
  		idev->timing10 = 1;
  		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
-@@ -633,7 +627,6 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
+@@ -585,14 +576,13 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
+ 	} else
+ 		hwif->host_flags |= IDE_HFLAG_NO_SET_MODE;
+ 
++	hwif->cable_detect = ata66_it821x;
++
+ 	if (hwif->dma_base == 0)
+ 		return;
+ 
+ 	hwif->ultra_mask = ATA_UDMA6;
+ 	hwif->mwdma_mask = ATA_MWDMA2;
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = ata66_it821x(hwif);
+ }
+ 
+ static void __devinit it8212_disable_raid(struct pci_dev *dev)
+@@ -633,7 +623,6 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
  		.name		= name_str,		\
  		.init_chipset	= init_chipset_it821x,	\
  		.init_hwif	= init_hwif_it821x,	\
@@ -410564,10 +416838,24 @@
  		.pio_mask	= ATA_PIO4,		\
  	}
 diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
-index 0083eaf..8b40f64 100644
+index 0083eaf..a56bcb4 100644
 --- a/drivers/ide/pci/jmicron.c
 +++ b/drivers/ide/pci/jmicron.c
-@@ -30,7 +30,7 @@ typedef enum {
+@@ -8,13 +8,10 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+ 
+-#include <asm/io.h>
+-
+ typedef enum {
+ 	PORT_PATA0 = 0,
+ 	PORT_PATA1 = 1,
+@@ -30,7 +27,7 @@ typedef enum {
  
  static u8 __devinit ata66_jmicron(ide_hwif_t *hwif)
  {
@@ -410576,8 +416864,21 @@
  
  	u32 control;
  	u32 control5;
+@@ -111,11 +108,7 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
+ 	hwif->set_pio_mode = &jmicron_set_pio_mode;
+ 	hwif->set_dma_mode = &jmicron_set_dma_mode;
+ 
+-	if (hwif->dma_base == 0)
+-		return;
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = ata66_jmicron(hwif);
++	hwif->cable_detect = ata66_jmicron;
+ }
+ 
+ static const struct ide_port_info jmicron_chipset __devinitdata = {
 diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
-index d4df464..fc9eee9 100644
+index d4df464..bf0d3b2 100644
 --- a/drivers/ide/pci/ns87415.c
 +++ b/drivers/ide/pci/ns87415.c
 @@ -1,6 +1,4 @@
@@ -410587,7 +416888,19 @@
   * Copyright (C) 1997-1998	Mark Lord <mlord at pobox.com>
   * Copyright (C) 1998		Eddie C. Dost <ecd at skynet.be>
   * Copyright (C) 1999-2000	Andre Hedrick <andre at linux-ide.org>
-@@ -71,10 +69,9 @@ static u8 superio_ide_inb (unsigned long port)
+@@ -12,11 +10,7 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+ #include <linux/interrupt.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/pci.h>
+ #include <linux/delay.h>
+@@ -71,10 +65,9 @@ static u8 superio_ide_inb (unsigned long port)
  
  static void __devinit superio_ide_init_iops (struct hwif_s *hwif)
  {
@@ -410600,7 +416913,7 @@
  
  	base = pci_resource_start(pdev, port * 2) & ~3;
  	dmabase = pci_resource_start(pdev, 4) & ~3;
-@@ -93,10 +90,11 @@ static void __devinit superio_ide_init_iops (struct hwif_s *hwif)
+@@ -93,10 +86,11 @@ static void __devinit superio_ide_init_iops (struct hwif_s *hwif)
  
  static void __devinit init_iops_ns87415(ide_hwif_t *hwif)
  {
@@ -410614,7 +416927,7 @@
  }
  #endif
  
-@@ -110,8 +108,8 @@ static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
+@@ -110,8 +104,8 @@ static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
  static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
  {
  	ide_hwif_t *hwif = HWIF(drive);
@@ -410624,7 +416937,7 @@
  	unsigned long flags;
  
  	local_irq_save(flags);
-@@ -189,7 +187,7 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive)
+@@ -189,7 +183,7 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive)
  
  static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
  {
@@ -410633,7 +416946,7 @@
  	unsigned int ctrl, using_inta;
  	u8 progif;
  #ifdef __sparc_v9__
-@@ -231,8 +229,8 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
+@@ -231,8 +225,8 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
  
  #ifdef __sparc_v9__
  		/*
@@ -410645,7 +416958,7 @@
  		timeout = 10000;
  		outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
 diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
-index 8953d9c..0ce92d3 100644
+index 8953d9c..46e8748 100644
 --- a/drivers/ide/pci/opti621.c
 +++ b/drivers/ide/pci/opti621.c
 @@ -1,6 +1,4 @@
@@ -410655,11 +416968,64 @@
   *  Copyright (C) 1996-1998  Linus Torvalds & authors (see below)
   */
  
+@@ -89,11 +87,6 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/pci.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+@@ -322,14 +315,18 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
+ 	spin_unlock_irqrestore(&opti621_lock, flags);
+ }
+ 
++static void __devinit opti621_port_init_devs(ide_hwif_t *hwif)
++{
++	hwif->drives[0].drive_data = PIO_DONT_KNOW;
++	hwif->drives[1].drive_data = PIO_DONT_KNOW;
++}
++
+ /*
+  * init_hwif_opti621() is called once for each hwif found at boot.
+  */
+ static void __devinit init_hwif_opti621 (ide_hwif_t *hwif)
+ {
+-	hwif->drives[0].drive_data = PIO_DONT_KNOW;
+-	hwif->drives[1].drive_data = PIO_DONT_KNOW;
+-
++	hwif->port_init_devs = opti621_port_init_devs;
+ 	hwif->set_pio_mode = &opti621_set_pio_mode;
+ }
+ 
 diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
-index 2b4f44e..bb29db0 100644
+index 2b4f44e..1c8cb77 100644
 --- a/drivers/ide/pci/pdc202xx_new.c
 +++ b/drivers/ide/pci/pdc202xx_new.c
-@@ -146,9 +146,10 @@ static struct udma_timing {
+@@ -19,18 +19,12 @@
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+-#include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/ide.h>
+ 
+ #include <asm/io.h>
+-#include <asm/irq.h>
+ 
+ #ifdef CONFIG_PPC_PMAC
+ #include <asm/prom.h>
+@@ -146,9 +140,10 @@ static struct udma_timing {
  	{ 0x1a, 0x01, 0xcb },	/* UDMA mode 6 */
  };
  
@@ -410671,7 +417037,7 @@
  	u8 adj			= (drive->dn & 1) ? 0x08 : 0x00;
  
  	/*
-@@ -159,48 +160,21 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
+@@ -159,48 +154,21 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
  	 * As we set up the PLL to output 133 MHz for UltraDMA/133 capable
  	 * chips, we must override the default register settings...
  	 */
@@ -410733,7 +417099,7 @@
  		}
  	} else if (speed == XFER_UDMA_2) {
  		/* Set tHOLD bit to 0 if using UDMA mode 2 */
-@@ -212,7 +186,15 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
+@@ -212,10 +180,18 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
  
  static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio)
  {
@@ -410749,8 +417115,12 @@
 +	}
  }
  
- static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
-@@ -223,14 +205,17 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
+-static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
++static u8 __devinit pdcnew_cable_detect(ide_hwif_t *hwif)
+ {
+ 	if (get_indexed_reg(hwif, 0x0b) & 0x04)
+ 		return ATA_CBL_PATA40;
+@@ -223,14 +199,17 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
  		return ATA_CBL_PATA80;
  }
  
@@ -410772,7 +417142,7 @@
  }
  
  static void pdcnew_reset(ide_drive_t *drive)
-@@ -466,7 +451,7 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha
+@@ -466,16 +445,12 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha
  static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
  {
  	hwif->set_pio_mode = &pdcnew_set_pio_mode;
@@ -410781,8 +417151,18 @@
  
  	hwif->quirkproc = &pdcnew_quirkproc;
  	hwif->resetproc = &pdcnew_reset;
+ 
+-	if (hwif->dma_base == 0)
+-		return;
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = pdcnew_cable_detect(hwif);
++	hwif->cable_detect = pdcnew_cable_detect;
+ }
+ 
+ static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
 diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
-index e09742e..31a1308 100644
+index e09742e..da43297 100644
 --- a/drivers/ide/pci/pdc202xx_old.c
 +++ b/drivers/ide/pci/pdc202xx_old.c
 @@ -1,6 +1,4 @@
@@ -410792,7 +417172,26 @@
   *  Copyright (C) 1998-2002		Andre Hedrick <andre at linux-ide.org>
   *  Copyright (C) 2006-2007		MontaVista Software, Inc.
   *  Copyright (C) 2007			Bartlomiej Zolnierkiewicz
-@@ -66,7 +64,7 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
+@@ -34,18 +32,13 @@
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+ #include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+-#include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/ide.h>
+ 
+ #include <asm/io.h>
+-#include <asm/irq.h>
+ 
+ #define PDC202XX_DEBUG_DRIVE_INFO	0
+ 
+@@ -66,7 +59,7 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
  static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -410801,19 +417200,23 @@
  	u8 drive_pci		= 0x60 + (drive->dn << 2);
  
  	u8			AP = 0, BP = 0, CP = 0;
-@@ -144,9 +142,10 @@ static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -142,11 +135,12 @@ static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
+ 	pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
+ }
  
- static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
+-static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
++static u8 __devinit pdc2026x_old_cable_detect(ide_hwif_t *hwif)
  {
+-	u16 CIS = 0, mask = (hwif->channel) ? (1<<11) : (1<<10);
 +	struct pci_dev *dev = to_pci_dev(hwif->dev);
- 	u16 CIS = 0, mask = (hwif->channel) ? (1<<11) : (1<<10);
++	u16 CIS, mask = hwif->channel ? (1 << 11) : (1 << 10);
  
 -	pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
 +	pci_read_config_word(dev, 0x50, &CIS);
  
  	return (CIS & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
  }
-@@ -162,7 +161,7 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
+@@ -162,7 +156,7 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
   */
  static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
  {
@@ -410822,7 +417225,7 @@
  	u8 clock = inb(clock_reg);
  
  	outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
-@@ -170,20 +169,23 @@ static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
+@@ -170,20 +164,23 @@ static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
  
  static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
  {
@@ -410851,7 +417254,7 @@
  }
  
  static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
-@@ -193,7 +195,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
+@@ -193,7 +190,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
  	if (drive->media != ide_disk || drive->addressing == 1) {
  		struct request *rq	= HWGROUP(drive)->rq;
  		ide_hwif_t *hwif	= HWIF(drive);
@@ -410860,7 +417263,7 @@
  		unsigned long atapi_reg	= high_16 + (hwif->channel ? 0x24 : 0x20);
  		u32 word_count	= 0;
  		u8 clock = inb(high_16 + 0x11);
-@@ -212,7 +214,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
+@@ -212,7 +209,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
  {
  	if (drive->media != ide_disk || drive->addressing == 1) {
  		ide_hwif_t *hwif	= HWIF(drive);
@@ -410869,7 +417272,7 @@
  		unsigned long atapi_reg	= high_16 + (hwif->channel ? 0x24 : 0x20);
  		u8 clock		= 0;
  
-@@ -228,7 +230,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
+@@ -228,7 +225,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
  static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -410878,7 +417281,7 @@
  	u8 dma_stat		= inb(hwif->dma_status);
  	u8 sc1d			= inb(high_16 + 0x001d);
  
-@@ -271,7 +273,7 @@ static void pdc202xx_dma_timeout(ide_drive_t *drive)
+@@ -271,7 +268,7 @@ static void pdc202xx_dma_timeout(ide_drive_t *drive)
  
  static void pdc202xx_reset_host (ide_hwif_t *hwif)
  {
@@ -410887,7 +417290,7 @@
  	u8 udma_speed_flag	= inb(high_16 | 0x001f);
  
  	outb(udma_speed_flag | 0x10, high_16 | 0x001f);
-@@ -302,12 +304,14 @@ static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
+@@ -302,24 +299,26 @@ static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
  
  static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
  {
@@ -410899,20 +417302,27 @@
  	hwif->quirkproc = &pdc202xx_quirkproc;
  
 -	if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
-+	if (dev->device != PCI_DEVICE_ID_PROMISE_20246)
++	if (dev->device != PCI_DEVICE_ID_PROMISE_20246) {
  		hwif->resetproc = &pdc202xx_reset;
  
++		hwif->cable_detect = pdc2026x_old_cable_detect;
++	}
++
  	if (hwif->dma_base == 0)
-@@ -316,7 +320,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
+ 		return;
+ 
  	hwif->dma_lost_irq = &pdc202xx_dma_lost_irq;
  	hwif->dma_timeout = &pdc202xx_dma_timeout;
  
 -	if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) {
+-		if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-			hwif->cbl = pdc202xx_old_cable_detect(hwif);
+-
 +	if (dev->device != PCI_DEVICE_ID_PROMISE_20246) {
- 		if (hwif->cbl != ATA_CBL_PATA40_SHORT)
- 			hwif->cbl = pdc202xx_old_cable_detect(hwif);
- 
-@@ -331,7 +335,7 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
+ 		hwif->dma_start = &pdc202xx_old_ide_dma_start;
+ 		hwif->ide_dma_end = &pdc202xx_old_ide_dma_end;
+ 	} 
+@@ -331,7 +330,7 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
  	u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
  
  	if (hwif->channel) {
@@ -410921,7 +417331,7 @@
  		return;
  	}
  
-@@ -355,7 +359,7 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
+@@ -355,7 +354,7 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
  	}
  #endif /* CONFIG_PDC202XX_BURST */
  
@@ -410930,7 +417340,7 @@
  }
  
  static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
-@@ -375,6 +379,11 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
+@@ -375,6 +374,11 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
  	}
  }
  
@@ -410942,7 +417352,7 @@
  #define DECLARE_PDC2026X_DEV(name_str, udma, extra_flags) \
  	{ \
  		.name		= name_str, \
-@@ -382,9 +391,7 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
+@@ -382,9 +386,7 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
  		.init_hwif	= init_hwif_pdc202xx, \
  		.init_dma	= init_dma_pdc202xx, \
  		.extra		= 48, \
@@ -410953,7 +417363,7 @@
  		.pio_mask	= ATA_PIO4, \
  		.mwdma_mask	= ATA_MWDMA2, \
  		.udma_mask	= udma, \
-@@ -397,8 +404,7 @@ static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
+@@ -397,8 +399,7 @@ static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
  		.init_hwif	= init_hwif_pdc202xx,
  		.init_dma	= init_dma_pdc202xx,
  		.extra		= 16,
@@ -410964,7 +417374,7 @@
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA2,
 diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
-index 27781d2..c1a6b68 100644
+index 27781d2..decef0f 100644
 --- a/drivers/ide/pci/piix.c
 +++ b/drivers/ide/pci/piix.c
 @@ -1,6 +1,4 @@
@@ -411006,8 +417416,7 @@
 - *
 - * 4a 84|21        hdb|hda
 - * 4b 84|21        hdd|hdc
-+ * Documentation:
-  *
+- *
 - *    ata-33/82371AB
 - *    ata-33/82371EB
 - *    ata-33/82801AB            ata-66/82801AA
@@ -411015,7 +417424,8 @@
 - *    01|01 udma 1              01|01 udma 3
 - *    10|10 udma 2              10|10 udma 4
 - *    11|11 reserved            11|11 reserved
-- *
++ * Documentation:
+  *
 - * 54 8421|8421    ata66 drive|ata66 enable
 - *
 - * pci_read_config_word(HWIF(drive)->pci_dev, 0x40, &reg40);
@@ -411029,7 +417439,19 @@
   *	Publically available from Intel web site. Errata documentation
   * is also publically available. As an aide to anyone hacking on this
   * driver the list of errata that are relevant is below.going back to
-@@ -116,7 +69,7 @@ static int no_piix_dma;
+@@ -94,11 +47,9 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/ioport.h>
+ #include <linux/pci.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+-#include <linux/delay.h>
+ #include <linux/init.h>
+ 
+ #include <asm/io.h>
+@@ -116,7 +67,7 @@ static int no_piix_dma;
  static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -411038,7 +417460,7 @@
  	int is_slave		= drive->dn & 1;
  	int master_port		= hwif->channel ? 0x42 : 0x40;
  	int slave_port		= 0x44;
-@@ -185,7 +138,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -185,7 +136,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
  static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -411047,7 +417469,7 @@
  	u8 maslave		= hwif->channel ? 0x42 : 0x40;
  	int a_speed		= 3 << (drive->dn * 4);
  	int u_flag		= 1 << drive->dn;
-@@ -203,20 +156,11 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -203,20 +154,11 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
  	pci_read_config_byte(dev, 0x54, &reg54);
  	pci_read_config_byte(dev, 0x55, &reg55);
  
@@ -411072,7 +417494,7 @@
  		if (!(reg48 & u_flag))
  			pci_write_config_byte(dev, 0x48, reg48 | u_flag);
  		if (speed == XFER_UDMA_5) {
-@@ -314,7 +258,7 @@ static const struct ich_laptop ich_laptop[] = {
+@@ -314,7 +256,7 @@ static const struct ich_laptop ich_laptop[] = {
  
  static u8 __devinit piix_cable_detect(ide_hwif_t *hwif)
  {
@@ -411081,8 +417503,25 @@
  	const struct ich_laptop *lap = &ich_laptop[0];
  	u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30;
  
+@@ -346,14 +288,11 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
+ 	hwif->set_pio_mode = &piix_set_pio_mode;
+ 	hwif->set_dma_mode = &piix_set_dma_mode;
+ 
++	hwif->cable_detect = piix_cable_detect;
++
+ 	if (!hwif->dma_base)
+ 		return;
+ 
+-	if (hwif->ultra_mask & 0x78) {
+-		if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-			hwif->cbl = piix_cable_detect(hwif);
+-	}
+-
+ 	if (no_piix_dma)
+ 		hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0;
+ }
 diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c
-index 6b10ae2..7ed6625 100644
+index 6b10ae2..5167661 100644
 --- a/drivers/ide/pci/rz1000.c
 +++ b/drivers/ide/pci/rz1000.c
 @@ -1,6 +1,4 @@
@@ -411092,8 +417531,22 @@
   *  Copyright (C) 1995-1998  Linus Torvalds & author (see below)
   */
  
-@@ -32,8 +30,8 @@
+@@ -18,22 +16,15 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/pci.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
  
+-#include <asm/io.h>
+-
  static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif)
  {
 +	struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -411102,8 +417555,18 @@
  
  	if (!pci_read_config_word (dev, 0x40, &reg) &&
  	    !pci_write_config_word(dev, 0x40, reg & 0xdfff)) {
+@@ -42,8 +33,7 @@ static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif)
+ 	} else {
+ 		if (hwif->mate)
+ 			hwif->mate->serialized = hwif->serialized = 1;
+-		hwif->drives[0].no_unmask = 1;
+-		hwif->drives[1].no_unmask = 1;
++		hwif->host_flags |= IDE_HFLAG_NO_UNMASK_IRQS;
+ 		printk(KERN_INFO "%s: serialized, disabled unmasking "
+ 			"(buggy RZ1000/RZ1001)\n", hwif->name);
+ 	}
 diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
-index 707d5ff..af499a6 100644
+index 707d5ff..561aa47 100644
 --- a/drivers/ide/pci/sc1200.c
 +++ b/drivers/ide/pci/sc1200.c
 @@ -1,6 +1,4 @@
@@ -411113,7 +417576,28 @@
   * Copyright (C) 2000-2002		Mark Lord <mlord at pobox.com>
   * Copyright (C)      2007		Bartlomiej Zolnierkiewicz
   *
-@@ -87,7 +85,7 @@ static const unsigned int sc1200_pio_timings[4][5] =
+@@ -16,19 +14,13 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+-#include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/ide.h>
+ #include <linux/pm.h>
++
+ #include <asm/io.h>
+-#include <asm/irq.h>
+ 
+ #define SC1200_REV_A	0x00
+ #define SC1200_REV_B1	0x01
+@@ -87,7 +79,7 @@ static const unsigned int sc1200_pio_timings[4][5] =
  static void sc1200_tunepio(ide_drive_t *drive, u8 pio)
  {
  	ide_hwif_t *hwif = drive->hwif;
@@ -411122,7 +417606,7 @@
  	unsigned int basereg = hwif->channel ? 0x50 : 0x40, format = 0;
  
  	pci_read_config_dword(pdev, basereg + 4, &format);
-@@ -130,72 +128,42 @@ out:
+@@ -130,72 +122,42 @@ out:
  static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
  {
  	ide_hwif_t		*hwif = HWIF(drive);
@@ -411217,7 +417701,7 @@
  }
  
  /*  Replacement for the standard ide_dma_end action in
-@@ -250,9 +218,9 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -250,9 +212,9 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
  	}
  	if (mode != -1) {
  		printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
@@ -411230,7 +417714,7 @@
  		return;
  	}
  
-@@ -260,66 +228,39 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -260,66 +222,39 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
  }
  
  #ifdef CONFIG_PM
@@ -411322,7 +417806,7 @@
  
  	pci_disable_device(dev);
  	pci_set_power_state(dev, pci_choose_state(dev, state));
-@@ -328,30 +269,25 @@ static int sc1200_suspend (struct pci_dev *dev, pm_message_t state)
+@@ -328,30 +263,25 @@ static int sc1200_suspend (struct pci_dev *dev, pm_message_t state)
  
  static int sc1200_resume (struct pci_dev *dev)
  {
@@ -411367,7 +417851,7 @@
  }
  #endif
 diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
-index ebb7132..7694969 100644
+index ebb7132..238e3e1 100644
 --- a/drivers/ide/pci/scc_pata.c
 +++ b/drivers/ide/pci/scc_pata.c
 @@ -254,19 +254,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
@@ -411409,7 +417893,7 @@
  	hwif->dma_base = dma_base;
  	hwif->config_data = ports->ctl;
  	hwif->mmio = 1;
-@@ -648,7 +636,8 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
+@@ -648,13 +636,19 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
  
  static void __devinit init_iops_scc(ide_hwif_t *hwif)
  {
@@ -411419,7 +417903,28 @@
  	hwif->hwif_data = NULL;
  	if (pci_get_drvdata(dev) == NULL)
  		return;
-@@ -738,10 +727,8 @@ static void __devexit scc_remove(struct pci_dev *dev)
+ 	init_mmio_iops_scc(hwif);
+ }
+ 
++static u8 __devinit scc_cable_detect(ide_hwif_t *hwif)
++{
++	return ATA_CBL_PATA80;
++}
++
+ /**
+  *	init_hwif_scc	-	set up hwif
+  *	@hwif: interface to set up
+@@ -689,8 +683,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
+ 	else
+ 		hwif->ultra_mask = ATA_UDMA5; /* 100MHz */
+ 
+-	/* we support 80c cable only. */
+-	hwif->cbl = ATA_CBL_PATA80;
++	hwif->cable_detect = scc_cable_detect;
+ }
+ 
+ #define DECLARE_SCC_DEV(name_str)			\
+@@ -738,14 +731,12 @@ static void __devexit scc_remove(struct pci_dev *dev)
  	unsigned long dma_size = pci_resource_len(dev, 1);
  
  	if (hwif->dmatable_cpu) {
@@ -411432,8 +417937,13 @@
  		hwif->dmatable_cpu = NULL;
  	}
  
+-	ide_unregister(hwif->index);
++	ide_unregister(hwif->index, 0, 0);
+ 
+ 	hwif->chipset = ide_unknown;
+ 	iounmap((void*)ports->dma);
 diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
-index a728031..f495253 100644
+index a728031..c11880b 100644
 --- a/drivers/ide/pci/serverworks.c
 +++ b/drivers/ide/pci/serverworks.c
 @@ -1,6 +1,4 @@
@@ -411443,7 +417953,20 @@
   * Copyright (C) 1998-2000 Michel Aubry
   * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
   * Copyright (C) 1998-2000 Andre Hedrick <andre at linux-ide.org>
-@@ -67,7 +65,7 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list)
+@@ -33,12 +31,10 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/ioport.h>
+ #include <linux/pci.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+-#include <linux/delay.h>
+ 
+ #include <asm/io.h>
+ 
+@@ -67,7 +63,7 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list)
  
  static u8 svwks_udma_filter(ide_drive_t *drive)
  {
@@ -411452,7 +417975,7 @@
  	u8 mask = 0;
  
  	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
-@@ -130,7 +128,7 @@ static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -130,7 +126,7 @@ static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
  	static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
  	static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
  
@@ -411461,7 +417984,7 @@
  
  	pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]);
  
-@@ -153,7 +151,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -153,7 +149,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
  	static const u8 drive_pci2[]		= { 0x45, 0x44, 0x47, 0x46 };
  
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -411470,7 +417993,7 @@
  	u8 unit			= (drive->select.b.unit & 0x01);
  
  	u8 ultra_enable	 = 0, ultra_timing = 0, dma_timing = 0;
-@@ -164,25 +162,12 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -164,25 +160,12 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
  	ultra_timing	&= ~(0x0F << (4*unit));
  	ultra_enable	&= ~(0x01 << drive->dn);
  
@@ -411502,7 +418025,7 @@
  
  	pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing);
  	pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing);
-@@ -300,7 +285,8 @@ static u8 __devinit ata66_svwks_svwks(ide_hwif_t *hwif)
+@@ -300,7 +283,8 @@ static u8 __devinit ata66_svwks_svwks(ide_hwif_t *hwif)
   */
  static u8 __devinit ata66_svwks_dell(ide_hwif_t *hwif)
  {
@@ -411512,7 +418035,7 @@
  	if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
  	    dev->vendor	== PCI_VENDOR_ID_SERVERWORKS &&
  	    (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE ||
-@@ -318,7 +304,8 @@ static u8 __devinit ata66_svwks_dell(ide_hwif_t *hwif)
+@@ -318,7 +302,8 @@ static u8 __devinit ata66_svwks_dell(ide_hwif_t *hwif)
   */
  static u8 __devinit ata66_svwks_cobalt(ide_hwif_t *hwif)
  {
@@ -411522,7 +418045,7 @@
  	if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&
  	    dev->vendor	== PCI_VENDOR_ID_SERVERWORKS &&
  	    dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
-@@ -329,7 +316,7 @@ static u8 __devinit ata66_svwks_cobalt(ide_hwif_t *hwif)
+@@ -329,7 +314,7 @@ static u8 __devinit ata66_svwks_cobalt(ide_hwif_t *hwif)
  
  static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
  {
@@ -411531,7 +418054,7 @@
  
  	/* Server Works */
  	if (dev->subsystem_vendor == PCI_VENDOR_ID_SERVERWORKS)
-@@ -353,6 +340,8 @@ static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
+@@ -353,25 +338,27 @@ static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
  
  static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
  {
@@ -411540,15 +418063,16 @@
  	hwif->set_pio_mode = &svwks_set_pio_mode;
  	hwif->set_dma_mode = &svwks_set_dma_mode;
  	hwif->udma_filter = &svwks_udma_filter;
-@@ -360,18 +349,23 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
- 	if (!hwif->dma_base)
- 		return;
  
+-	if (!hwif->dma_base)
+-		return;
+-
 -	if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
-+	if (dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
- 		if (hwif->cbl != ATA_CBL_PATA40_SHORT)
- 			hwif->cbl = ata66_svwks(hwif);
- 	}
+-		if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-			hwif->cbl = ata66_svwks(hwif);
+-	}
++	if (dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE)
++		hwif->cable_detect = ata66_svwks;
  }
  
 +#define IDE_HFLAGS_SVWKS \
@@ -411566,7 +418090,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= 0x00, /* UDMA is problematic on OSB4 */
-@@ -379,7 +373,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
+@@ -379,7 +366,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
  		.name		= "SvrWks CSB5",
  		.init_chipset	= init_chipset_svwks,
  		.init_hwif	= init_hwif_svwks,
@@ -411575,7 +418099,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA5,
-@@ -387,7 +381,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
+@@ -387,7 +374,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
  		.name		= "SvrWks CSB6",
  		.init_chipset	= init_chipset_svwks,
  		.init_hwif	= init_hwif_svwks,
@@ -411584,7 +418108,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA5,
-@@ -395,8 +389,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
+@@ -395,8 +382,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
  		.name		= "SvrWks CSB6",
  		.init_chipset	= init_chipset_svwks,
  		.init_hwif	= init_hwif_svwks,
@@ -411594,7 +418118,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA5,
-@@ -404,8 +397,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
+@@ -404,8 +390,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
  		.name		= "SvrWks HT1000",
  		.init_chipset	= init_chipset_svwks,
  		.init_hwif	= init_hwif_svwks,
@@ -411604,7 +418128,7 @@
  		.pio_mask	= ATA_PIO4,
  		.mwdma_mask	= ATA_MWDMA2,
  		.udma_mask	= ATA_UDMA5,
-@@ -428,7 +420,9 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device
+@@ -428,7 +413,9 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device
  
  	d = serverworks_chipsets[idx];
  
@@ -411616,10 +418140,19 @@
  			if (pci_resource_start(dev, 0) != 0x01f1)
  				d.host_flags &= ~IDE_HFLAG_BOOTABLE;
 diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
-index de820aa..8590207 100644
+index de820aa..0546264 100644
 --- a/drivers/ide/pci/sgiioc4.c
 +++ b/drivers/ide/pci/sgiioc4.c
-@@ -159,6 +159,7 @@ sgiioc4_clearirq(ide_drive_t * drive)
+@@ -25,8 +25,6 @@
+ #include <linux/hdreg.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+ #include <linux/ioport.h>
+ #include <linux/blkdev.h>
+ #include <linux/scatterlist.h>
+@@ -159,6 +157,7 @@ sgiioc4_clearirq(ide_drive_t * drive)
  		}
  
  		if (intr_reg & 0x02) {
@@ -411627,7 +418160,7 @@
  			/* Error when transferring DMA data on PCI bus */
  			u32 pci_err_addr_low, pci_err_addr_high,
  			    pci_stat_cmd_reg;
-@@ -167,7 +168,7 @@ sgiioc4_clearirq(ide_drive_t * drive)
+@@ -167,7 +166,7 @@ sgiioc4_clearirq(ide_drive_t * drive)
  				readl((void __iomem *)hwif->io_ports[IDE_IRQ_OFFSET]);
  			pci_err_addr_high =
  				readl((void __iomem *)(hwif->io_ports[IDE_IRQ_OFFSET] + 4));
@@ -411636,7 +418169,7 @@
  					      &pci_stat_cmd_reg);
  			printk(KERN_ERR
  			       "%s(%s) : PCI Bus Error when doing DMA:"
-@@ -178,8 +179,7 @@ sgiioc4_clearirq(ide_drive_t * drive)
+@@ -178,8 +177,7 @@ sgiioc4_clearirq(ide_drive_t * drive)
  			       __FUNCTION__, drive->name,
  			       pci_err_addr_high, pci_err_addr_low);
  			/* Clear the PCI Error indicator */
@@ -411646,7 +418179,7 @@
  		}
  
  		/* Clear the Interrupt, Error bits on the IOC4 */
-@@ -277,21 +277,6 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
+@@ -277,21 +275,6 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
  	return dma_stat;
  }
  
@@ -411668,24 +418201,24 @@
  static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
  {
  }
-@@ -303,13 +288,10 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
+@@ -303,13 +286,10 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
  	return sgiioc4_checkirq(HWIF(drive));
  }
  
 -static void sgiioc4_dma_host_on(ide_drive_t * drive)
--{
++static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
+ {
 -}
 -
 -static void sgiioc4_dma_host_off(ide_drive_t * drive)
-+static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
- {
+-{
 -	sgiioc4_clearirq(drive);
 +	if (!on)
 +		sgiioc4_clearirq(drive);
  }
  
  static void
-@@ -352,6 +334,7 @@ sgiioc4_INB(unsigned long port)
+@@ -352,6 +332,7 @@ sgiioc4_INB(unsigned long port)
  static int __devinit
  ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
  {
@@ -411693,7 +418226,7 @@
  	void __iomem *virt_dma_base;
  	int num_ports = sizeof (ioc4_dma_regs_t);
  	void *pad;
-@@ -377,7 +360,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
+@@ -377,7 +358,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
  	}
  	hwif->dma_base = (unsigned long) virt_dma_base;
  
@@ -411702,7 +418235,7 @@
  					  IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
  					  &hwif->dmatable_dma);
  
-@@ -386,7 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
+@@ -386,7 +367,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
  
  	hwif->sg_max_nents = IOC4_PRD_ENTRIES;
  
@@ -411711,7 +418244,7 @@
  				   (dma_addr_t *) &(hwif->dma_status));
  
  	if (pad) {
-@@ -394,8 +377,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
+@@ -394,8 +375,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
  		return 0;
  	}
  
@@ -411721,7 +418254,7 @@
  			    hwif->dmatable_cpu, hwif->dmatable_dma);
  	printk(KERN_INFO
  	       "%s() -- Error! Unable to allocate DMA Maps for drive %s\n",
-@@ -535,8 +517,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
+@@ -535,8 +515,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
  	}
  
  use_pio_instead:
@@ -411731,7 +418264,15 @@
  
  	return 0;		/* revert to PIO for this request */
  }
-@@ -582,7 +563,6 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
+@@ -574,7 +553,6 @@ static void __devinit
+ ide_init_sgiioc4(ide_hwif_t * hwif)
+ {
+ 	hwif->mmio = 1;
+-	hwif->pio_mask = 0x00;
+ 	hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */
+ 	hwif->set_dma_mode = &sgiioc4_set_dma_mode;
+ 	hwif->selectproc = NULL;/* Use the default routine to select drive */
+@@ -582,7 +560,6 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
  	hwif->pre_reset = NULL;	/* No HBA specific pre_set needed */
  	hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine,
  						clear interrupts */
@@ -411739,10 +418280,12 @@
  	hwif->maskproc = &sgiioc4_maskproc;	/* Mask on/off NIEN register */
  	hwif->quirkproc = NULL;
  	hwif->busproc = NULL;
-@@ -594,14 +574,11 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
- 
- 	hwif->mwdma_mask = ATA_MWDMA2_ONLY;
+@@ -592,20 +569,22 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
+ 	if (hwif->dma_base == 0)
+ 		return;
  
+-	hwif->mwdma_mask = ATA_MWDMA2_ONLY;
+-
 +	hwif->dma_host_set = &sgiioc4_dma_host_set;
  	hwif->dma_setup = &sgiioc4_ide_dma_setup;
  	hwif->dma_start = &sgiioc4_ide_dma_start;
@@ -411755,27 +418298,32 @@
  	hwif->dma_lost_irq = &sgiioc4_dma_lost_irq;
  	hwif->dma_timeout = &ide_dma_timeout;
  }
-@@ -615,6 +592,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
+ 
++static const struct ide_port_info sgiioc4_port_info __devinitdata = {
++	.chipset		= ide_pci,
++	.host_flags		= IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
++				  IDE_HFLAG_NO_AUTOTUNE,
++	.mwdma_mask		= ATA_MWDMA2_ONLY,
++};
++
+ static int __devinit
+ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
+ {
+@@ -615,6 +594,8 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
  	ide_hwif_t *hwif;
  	int h;
  	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 +	hw_regs_t hw;
++	struct ide_port_info d = sgiioc4_port_info;
  
  	/*
  	 * Find an empty HWIF; if none available, return -ENOMEM.
-@@ -654,21 +632,16 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
+@@ -654,21 +635,15 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
  		return -ENOMEM;
  	}
  
 -	if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) {
 -		hw_regs_t hw;
--
--		/* Initialize the IO registers */
--		memset(&hw, 0, sizeof(hw));
--		sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
--		memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
--		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
--	}
 +	/* Initialize the IO registers */
 +	memset(&hw, 0, sizeof(hw));
 +	sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
@@ -411784,17 +418332,44 @@
 +	hw.dev = &dev->dev;
 +	ide_init_port_hw(hwif, &hw);
  
+-		/* Initialize the IO registers */
+-		memset(&hw, 0, sizeof(hw));
+-		sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
+-		memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
+-		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
+-	}
+-
 -	hwif->irq = dev->irq;
 -	hwif->chipset = ide_pci;
 -	hwif->pci_dev = dev;
-+	hwif->dev = &dev->dev;
- 	hwif->channel = 0;	/* Single Channel chip */
+-	hwif->channel = 0;	/* Single Channel chip */
 -	hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */
++	hwif->dev = &dev->dev;
  
  	/* The IOC4 uses MMIO rather than Port IO. */
  	default_hwif_mmiops(hwif);
+@@ -676,15 +651,17 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
+ 	/* Initializing chipset IRQ Registers */
+ 	writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
+ 
+-	if (dma_base == 0 || ide_dma_sgiioc4(hwif, dma_base))
++	if (dma_base == 0 || ide_dma_sgiioc4(hwif, dma_base)) {
+ 		printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n",
+ 				 hwif->name, DRV_NAME);
++		d.mwdma_mask = 0;
++	}
+ 
+ 	ide_init_sgiioc4(hwif);
+ 
+ 	idx[0] = hwif->index;
+ 
+-	if (ide_device_add(idx))
++	if (ide_device_add(idx, &d))
+ 		return -EIO;
+ 
+ 	return 0;
 diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
-index 5709c25..4877bc8 100644
+index 5709c25..ef5b39f 100644
 --- a/drivers/ide/pci/siimage.c
 +++ b/drivers/ide/pci/siimage.c
 @@ -1,6 +1,4 @@
@@ -411804,7 +418379,15 @@
   * Copyright (C) 2001-2002	Andre Hedrick <andre at linux-ide.org>
   * Copyright (C) 2003		Red Hat <alan at redhat.com>
   * Copyright (C) 2007		MontaVista Software, Inc.
-@@ -79,7 +77,7 @@ static int pdev_is_sata(struct pci_dev *pdev)
+@@ -41,7 +39,6 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+ #include <linux/init.h>
+@@ -79,7 +76,7 @@ static int pdev_is_sata(struct pci_dev *pdev)
   
  static inline int is_sata(ide_hwif_t *hwif)
  {
@@ -411813,7 +418396,7 @@
  }
  
  /**
-@@ -140,13 +138,14 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
+@@ -140,13 +137,14 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
  static u8 sil_pata_udma_filter(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif = drive->hwif;
@@ -411829,7 +418412,7 @@
  
  	if ((scsc & 0x30) == 0x10)	/* 133 */
  		mask = ATA_UDMA6;
-@@ -219,19 +218,21 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
+@@ -219,19 +217,21 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
  		mode |= (unit ? 0x10 : 0x01);
  		hwif->OUTB(mode, base + addr_mask);
  	} else {
@@ -411857,7 +418440,7 @@
  	}
  }
  
-@@ -250,6 +251,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -250,6 +250,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
  	u16 dma[]		= { 0x2208, 0x10C2, 0x10C1 };
  
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -411865,7 +418448,7 @@
  	u16 ultra = 0, multi	= 0;
  	u8 mode = 0, unit	= drive->select.b.unit;
  	unsigned long base	= (unsigned long)hwif->hwif_data;
-@@ -266,10 +268,10 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -266,10 +267,10 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
  		multi = hwif->INW(ma);
  		ultra = hwif->INW(ua);
  	} else {
@@ -411880,7 +418463,7 @@
  	}
  
  	mode &= ~((unit) ? 0x30 : 0x03);
-@@ -278,27 +280,14 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -278,27 +279,14 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
  
  	scsc = is_sata(hwif) ? 1 : scsc;
  
@@ -411916,7 +418499,7 @@
  	}
  
  	if (hwif->mmio) {
-@@ -306,9 +295,9 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -306,9 +294,9 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
  		hwif->OUTW(multi, ma);
  		hwif->OUTW(ultra, ua);
  	} else {
@@ -411929,7 +418512,7 @@
  	}
  }
  
-@@ -316,6 +305,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -316,6 +304,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
  static int siimage_io_ide_dma_test_irq (ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -411937,7 +418520,7 @@
  	u8 dma_altstat		= 0;
  	unsigned long addr	= siimage_selreg(hwif, 1);
  
-@@ -324,7 +314,7 @@ static int siimage_io_ide_dma_test_irq (ide_drive_t *drive)
+@@ -324,7 +313,7 @@ static int siimage_io_ide_dma_test_irq (ide_drive_t *drive)
  		return 1;
  
  	/* return 1 if Device INTR asserted */
@@ -411946,7 +418529,30 @@
  	if (dma_altstat & 8)
  		return 0;	//return 1;
  	return 0;
-@@ -390,13 +380,14 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
+@@ -342,15 +331,18 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
+ {
+ 	ide_hwif_t *hwif	= HWIF(drive);
+ 	unsigned long addr	= siimage_selreg(hwif, 0x1);
++	void __iomem *sata_error_addr
++		= (void __iomem *)hwif->sata_scr[SATA_ERROR_OFFSET];
+ 
+-	if (SATA_ERROR_REG) {
++	if (sata_error_addr) {
+ 		unsigned long base = (unsigned long)hwif->hwif_data;
+-
+ 		u32 ext_stat = readl((void __iomem *)(base + 0x10));
+ 		u8 watchdog = 0;
++
+ 		if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
+-			u32 sata_error = readl((void __iomem *)SATA_ERROR_REG);
+-			writel(sata_error, (void __iomem *)SATA_ERROR_REG);
++			u32 sata_error = readl(sata_error_addr);
++
++			writel(sata_error, sata_error_addr);
+ 			watchdog = (sata_error & 0x00680000) ? 1 : 0;
+ 			printk(KERN_WARNING "%s: sata_error = 0x%08x, "
+ 				"watchdog = %d, %s\n",
+@@ -390,13 +382,14 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
  static int sil_sata_busproc(ide_drive_t * drive, int state)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -411962,7 +418568,30 @@
  
  	switch (state) {
  		case BUSSTATE_ON:
-@@ -656,7 +647,7 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const ch
+@@ -428,13 +421,17 @@ static int sil_sata_busproc(ide_drive_t * drive, int state)
+ 
+ static int sil_sata_reset_poll(ide_drive_t *drive)
+ {
+-	if (SATA_STATUS_REG) {
+-		ide_hwif_t *hwif	= HWIF(drive);
++	ide_hwif_t *hwif = drive->hwif;
++	void __iomem *sata_status_addr
++		= (void __iomem *)hwif->sata_scr[SATA_STATUS_OFFSET];
+ 
+-		/* SATA_STATUS_REG is valid only when in MMIO mode */
+-		if ((readl((void __iomem *)SATA_STATUS_REG) & 0x03) != 0x03) {
++	if (sata_status_addr) {
++		/* SATA Status is available only when in MMIO mode */
++		u32 sata_stat = readl(sata_status_addr);
++
++		if ((sata_stat & 0x03) != 0x03) {
+ 			printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
+-				hwif->name, readl((void __iomem *)SATA_STATUS_REG));
++					    hwif->name, sata_stat);
+ 			HWGROUP(drive)->polling = 0;
+ 			return ide_started;
+ 		}
+@@ -656,7 +653,7 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const ch
  
  static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
  {
@@ -411971,7 +418600,7 @@
  	void *addr		= pci_get_drvdata(dev);
  	u8 ch			= hwif->channel;
  	hw_regs_t		hw;
-@@ -726,9 +717,6 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
+@@ -726,9 +723,6 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
  	const char *s = &drive->id->model[0];
  	unsigned len;
  
@@ -411981,7 +418610,7 @@
  	len = strnlen(s, sizeof(drive->id->model));
  
  	if ((len > 4) && (!memcmp(s, "ST", 2))) {
-@@ -743,18 +731,20 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
+@@ -743,18 +737,20 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
  }
  
  /**
@@ -412006,7 +418635,7 @@
  		hwif->rqsize = 128;
  }
  
-@@ -770,12 +760,14 @@ static void __devinit siimage_fixup(ide_hwif_t *hwif)
+@@ -770,12 +766,14 @@ static void __devinit siimage_fixup(ide_hwif_t *hwif)
  
  static void __devinit init_iops_siimage(ide_hwif_t *hwif)
  {
@@ -412022,7 +418651,7 @@
  		return;
  
  	init_mmio_iops_siimage(hwif);
-@@ -791,11 +783,12 @@ static void __devinit init_iops_siimage(ide_hwif_t *hwif)
+@@ -791,11 +789,12 @@ static void __devinit init_iops_siimage(ide_hwif_t *hwif)
  
  static u8 __devinit ata66_siimage(ide_hwif_t *hwif)
  {
@@ -412037,7 +418666,7 @@
  	else
  		ata66 = hwif->INB(addr);
  
-@@ -817,6 +810,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
+@@ -817,6 +816,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
  
  	hwif->set_pio_mode = &sil_set_pio_mode;
  	hwif->set_dma_mode = &sil_set_dma_mode;
@@ -412045,7 +418674,25 @@
  
  	if (sata) {
  		static int first = 1;
-@@ -855,7 +849,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
+@@ -833,15 +833,14 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
+ 	} else
+ 		hwif->udma_filter = &sil_pata_udma_filter;
+ 
++	hwif->cable_detect = ata66_siimage;
++
+ 	if (hwif->dma_base == 0)
+ 		return;
+ 
+ 	if (sata)
+ 		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+ 
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = ata66_siimage(hwif);
+-
+ 	if (hwif->mmio) {
+ 		hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq;
+ 	} else {
+@@ -855,7 +854,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
  		.init_chipset	= init_chipset_siimage,	\
  		.init_iops	= init_iops_siimage,	\
  		.init_hwif	= init_hwif_siimage,	\
@@ -412054,7 +418701,7 @@
  		.pio_mask	= ATA_PIO4,		\
  		.mwdma_mask	= ATA_MWDMA2,		\
 diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
-index d90b429..2a461de 100644
+index d90b429..512bb4c 100644
 --- a/drivers/ide/pci/sis5513.c
 +++ b/drivers/ide/pci/sis5513.c
 @@ -1,6 +1,4 @@
@@ -412064,7 +418711,28 @@
   * Copyright (C) 1999-2000	Andre Hedrick <andre at linux-ide.org>
   * Copyright (C) 2002		Lionel Bouton <Lionel.Bouton at inet6.fr>, Maintainer
   * Copyright (C) 2003		Vojtech Pavlik <vojtech at suse.cz>
-@@ -197,7 +195,7 @@ static char* chipset_capability[] = {
+@@ -49,20 +47,11 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+-
+-#include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/ide.h>
+ 
+-#include <asm/irq.h>
+-
+ #include "ide-timing.h"
+ 
+ /* registers layout and init values are chipset family dependant */
+@@ -197,7 +186,7 @@ static char* chipset_capability[] = {
  
  static u8 sis_ata133_get_base(ide_drive_t *drive)
  {
@@ -412073,7 +418741,7 @@
  	u32 reg54 = 0;
  
  	pci_read_config_dword(dev, 0x54, &reg54);
-@@ -207,7 +205,7 @@ static u8 sis_ata133_get_base(ide_drive_t *drive)
+@@ -207,7 +196,7 @@ static u8 sis_ata133_get_base(ide_drive_t *drive)
  
  static void sis_ata16_program_timings(ide_drive_t *drive, const u8 mode)
  {
@@ -412082,7 +418750,7 @@
  	u16 t1 = 0;
  	u8 drive_pci = 0x40 + drive->dn * 2;
  
-@@ -230,7 +228,7 @@ static void sis_ata16_program_timings(ide_drive_t *drive, const u8 mode)
+@@ -230,7 +219,7 @@ static void sis_ata16_program_timings(ide_drive_t *drive, const u8 mode)
  
  static void sis_ata100_program_timings(ide_drive_t *drive, const u8 mode)
  {
@@ -412091,7 +418759,7 @@
  	u8 t1, drive_pci = 0x40 + drive->dn * 2;
  
  	/* timing bits: 7:4 active 3:0 recovery */
-@@ -253,7 +251,7 @@ static void sis_ata100_program_timings(ide_drive_t *drive, const u8 mode)
+@@ -253,7 +242,7 @@ static void sis_ata100_program_timings(ide_drive_t *drive, const u8 mode)
  
  static void sis_ata133_program_timings(ide_drive_t *drive, const u8 mode)
  {
@@ -412100,7 +418768,7 @@
  	u32 t1 = 0;
  	u8 drive_pci = sis_ata133_get_base(drive), clk, idx;
  
-@@ -286,7 +284,7 @@ static void sis_program_timings(ide_drive_t *drive, const u8 mode)
+@@ -286,7 +275,7 @@ static void sis_program_timings(ide_drive_t *drive, const u8 mode)
  static void config_drive_art_rwp (ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -412109,7 +418777,7 @@
  	u8 reg4bh		= 0;
  	u8 rw_prefetch		= 0;
  
-@@ -305,64 +303,61 @@ static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -305,64 +294,61 @@ static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
  	sis_program_timings(drive, XFER_PIO_0 + pio);
  }
  
@@ -412223,7 +418891,7 @@
  	u32 regdw = 0;
  	u8 drive_pci = sis_ata133_get_base(drive);
  
-@@ -533,7 +528,7 @@ static const struct sis_laptop sis_laptop[] = {
+@@ -533,7 +519,7 @@ static const struct sis_laptop sis_laptop[] = {
  
  static u8 __devinit ata66_sis5513(ide_hwif_t *hwif)
  {
@@ -412232,7 +418900,7 @@
  	const struct sis_laptop *lap = &sis_laptop[0];
  	u8 ata66 = 0;
  
-@@ -548,12 +543,12 @@ static u8 __devinit ata66_sis5513(ide_hwif_t *hwif)
+@@ -548,12 +534,12 @@ static u8 __devinit ata66_sis5513(ide_hwif_t *hwif)
  	if (chipset_family >= ATA_133) {
  		u16 regw = 0;
  		u16 reg_addr = hwif->channel ? 0x52: 0x50;
@@ -412247,8 +418915,24 @@
  		ata66 = (reg48h & mask) ? 0 : 1;
  	}
  
+@@ -570,13 +556,12 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
+ 	if (chipset_family >= ATA_133)
+ 		hwif->udma_filter = sis5513_ata133_udma_filter;
+ 
++	hwif->cable_detect = ata66_sis5513;
++
+ 	if (hwif->dma_base == 0)
+ 		return;
+ 
+ 	hwif->ultra_mask = udma_rates[chipset_family];
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = ata66_sis5513(hwif);
+ }
+ 
+ static const struct ide_port_info sis5513_chipset __devinitdata = {
 diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
-index 147d783..da13a12 100644
+index 147d783..ee261ae 100644
 --- a/drivers/ide/pci/sl82c105.c
 +++ b/drivers/ide/pci/sl82c105.c
 @@ -1,6 +1,4 @@
@@ -412258,7 +418942,7 @@
   * SL82C105/Winbond 553 IDE driver
   *
   * Maintainer unknown.
-@@ -13,6 +11,7 @@
+@@ -13,22 +11,17 @@
   *  -- Benjamin Herrenschmidt (01/11/03) benh at kernel.crashing.org
   *
   * Copyright (C) 2006-2007 MontaVista Software, Inc. <source at mvista.com>
@@ -412266,7 +418950,23 @@
   */
  
  #include <linux/types.h>
-@@ -77,7 +76,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/interrupt.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/pci.h>
+ #include <linux/ide.h>
+ 
+ #include <asm/io.h>
+-#include <asm/dma.h>
+ 
+ #undef DEBUG
+ 
+@@ -77,7 +70,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
   */
  static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
  {
@@ -412275,7 +418975,7 @@
  	int reg			= 0x44 + drive->dn * 4;
  	u16 drv_ctrl;
  
-@@ -90,14 +89,8 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -90,14 +83,8 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
  	drive->drive_data &= 0xffff0000;
  	drive->drive_data |= drv_ctrl;
  
@@ -412292,7 +418992,7 @@
  
  	printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name,
  			  ide_xfer_verbose(pio + XFER_PIO_0),
-@@ -115,33 +108,14 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -115,33 +102,14 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
   	DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n",
  	     drive->name, ide_xfer_verbose(speed)));
  
@@ -412333,7 +419033,7 @@
  }
  
  /*
-@@ -171,7 +145,7 @@ static inline void sl82c105_reset_host(struct pci_dev *dev)
+@@ -171,7 +139,7 @@ static inline void sl82c105_reset_host(struct pci_dev *dev)
  static void sl82c105_dma_lost_irq(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -412342,7 +419042,7 @@
  	u32 val, mask		= hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
  	u8 dma_cmd;
  
-@@ -208,7 +182,12 @@ static void sl82c105_dma_lost_irq(ide_drive_t *drive)
+@@ -208,7 +176,12 @@ static void sl82c105_dma_lost_irq(ide_drive_t *drive)
  static void sl82c105_dma_start(ide_drive_t *drive)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -412356,7 +419056,7 @@
  
  	sl82c105_reset_host(dev);
  	ide_dma_start(drive);
-@@ -216,80 +195,43 @@ static void sl82c105_dma_start(ide_drive_t *drive)
+@@ -216,80 +189,43 @@ static void sl82c105_dma_start(ide_drive_t *drive)
  
  static void sl82c105_dma_timeout(ide_drive_t *drive)
  {
@@ -412451,7 +419151,7 @@
  }
  
  /*
-@@ -342,7 +284,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
+@@ -342,7 +278,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
  	pci_read_config_dword(dev, 0x40, &val);
  	val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
  	pci_write_config_dword(dev, 0x40, val);
@@ -412459,7 +419159,7 @@
  
  	return dev->irq;
  }
-@@ -352,19 +293,19 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
+@@ -352,19 +287,19 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
   */
  static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
  {
@@ -412481,7 +419181,7 @@
  	if (rev <= 5) {
  		/*
  		 * Never ever EVER under any circumstances enable
-@@ -377,10 +318,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
+@@ -377,10 +312,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
  
  	hwif->mwdma_mask = ATA_MWDMA2;
  
@@ -412494,7 +419194,7 @@
  
  	if (hwif->mate)
 diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
-index eb4445b..a6cf810 100644
+index eb4445b..65f4c2f 100644
 --- a/drivers/ide/pci/slc90e66.c
 +++ b/drivers/ide/pci/slc90e66.c
 @@ -1,6 +1,4 @@
@@ -412504,7 +419204,21 @@
   *  Copyright (C) 2000-2002 Andre Hedrick <andre at linux-ide.org>
   *  Copyright (C) 2006-2007 MontaVista Software, Inc. <source at mvista.com>
   *
-@@ -26,7 +24,7 @@ static DEFINE_SPINLOCK(slc90e66_lock);
+@@ -12,21 +10,17 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/ioport.h>
+ #include <linux/pci.h>
+ #include <linux/hdreg.h>
+ #include <linux/ide.h>
+-#include <linux/delay.h>
+ #include <linux/init.h>
+ 
+-#include <asm/io.h>
+-
+ static DEFINE_SPINLOCK(slc90e66_lock);
+ 
  static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -412513,7 +419227,7 @@
  	int is_slave		= drive->dn & 1;
  	int master_port		= hwif->channel ? 0x42 : 0x40;
  	int slave_port		= 0x44;
-@@ -79,7 +77,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
+@@ -79,7 +73,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
  static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
  {
  	ide_hwif_t *hwif	= HWIF(drive);
@@ -412522,7 +419236,7 @@
  	u8 maslave		= hwif->channel ? 0x42 : 0x40;
  	int sitre = 0, a_speed	= 7 << (drive->dn * 4);
  	int u_speed = 0, u_flag = 1 << drive->dn;
-@@ -91,19 +89,9 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -91,19 +85,9 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
  	pci_read_config_word(dev, 0x48, &reg48);
  	pci_read_config_word(dev, 0x4a, &reg4a);
  
@@ -412544,24 +419258,43 @@
  		if (!(reg48 & u_flag))
  			pci_write_config_word(dev, 0x48, reg48|u_flag);
  		/* FIXME: (reg4a & a_speed) ? */
-@@ -132,13 +120,14 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
+@@ -130,22 +114,23 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
+ 	}
+ }
  
- static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
+-static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
++static u8 __devinit slc90e66_cable_detect(ide_hwif_t *hwif)
  {
+-	u8 reg47 = 0;
+-	u8 mask = hwif->channel ? 0x01 : 0x02;  /* bit0:Primary */
 +	struct pci_dev *dev = to_pci_dev(hwif->dev);
- 	u8 reg47 = 0;
- 	u8 mask = hwif->channel ? 0x01 : 0x02;  /* bit0:Primary */
++	u8 reg47 = 0, mask = hwif->channel ? 0x01 : 0x02;
  
- 	hwif->set_pio_mode = &slc90e66_set_pio_mode;
- 	hwif->set_dma_mode = &slc90e66_set_dma_mode;
+-	hwif->set_pio_mode = &slc90e66_set_pio_mode;
+-	hwif->set_dma_mode = &slc90e66_set_dma_mode;
++	pci_read_config_byte(dev, 0x47, &reg47);
  
 -	pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
-+	pci_read_config_byte(dev, 0x47, &reg47);
++	/* bit[0(1)]: 0:80, 1:40 */
++	return (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
++}
  
- 	if (hwif->dma_base == 0)
- 		return;
+-	if (hwif->dma_base == 0)
+-		return;
++static void __devinit init_hwif_slc90e66(ide_hwif_t *hwif)
++{
++	hwif->set_pio_mode = &slc90e66_set_pio_mode;
++	hwif->set_dma_mode = &slc90e66_set_dma_mode;
+ 
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		/* bit[0(1)]: 0:80, 1:40 */
+-		hwif->cbl = (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
++	hwif->cable_detect = slc90e66_cable_detect;
+ }
+ 
+ static const struct ide_port_info slc90e66_chipset __devinitdata = {
 diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
-index a66ebd1..9fbbb4f 100644
+index a66ebd1..2ef2ed2 100644
 --- a/drivers/ide/pci/tc86c001.c
 +++ b/drivers/ide/pci/tc86c001.c
 @@ -1,6 +1,4 @@
@@ -412571,8 +419304,23 @@
   * Copyright (C) 2002 Toshiba Corporation
   * Copyright (C) 2005-2006 MontaVista Software, Inc. <source at mvista.com>
   *
-@@ -164,7 +162,8 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
+@@ -162,9 +160,23 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
+ 	return 0;
+ }
  
++static u8 __devinit tc86c001_cable_detect(ide_hwif_t *hwif)
++{
++	struct pci_dev *dev = to_pci_dev(hwif->dev);
++	unsigned long sc_base = pci_resource_start(dev, 5);
++	u16 scr1 = inw(sc_base + 0x00);
++
++	/*
++	 * System Control  1 Register bit 13 (PDIAGN):
++	 * 0=80-pin cable, 1=40-pin cable
++	 */
++	return (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
++}
++
  static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
  {
 -	unsigned long sc_base	= pci_resource_start(hwif->pci_dev, 5);
@@ -412581,7 +419329,32 @@
  	u16 scr1		= inw(sc_base + 0x00);
  
  	/* System Control 1 Register bit 15 (Soft Reset) set */
-@@ -222,7 +221,8 @@ static const struct ide_port_info tc86c001_chipset __devinitdata = {
+@@ -184,6 +196,8 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
+ 
+ 	hwif->busproc	= &tc86c001_busproc;
+ 
++	hwif->cable_detect = tc86c001_cable_detect;
++
+ 	if (!hwif->dma_base)
+ 		return;
+ 
+@@ -197,15 +211,6 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
+ 	hwif->rqsize	 = 0xffff;
+ 
+ 	hwif->dma_start 	= &tc86c001_dma_start;
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
+-		/*
+-		 * System Control  1 Register bit 13 (PDIAGN):
+-		 * 0=80-pin cable, 1=40-pin cable
+-		 */
+-		scr1 = inw(sc_base + 0x00);
+-		hwif->cbl = (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
+-	}
+ }
+ 
+ static unsigned int __devinit init_chipset_tc86c001(struct pci_dev *dev,
+@@ -222,7 +227,8 @@ static const struct ide_port_info tc86c001_chipset __devinitdata = {
  	.name		= "TC86C001",
  	.init_chipset	= init_chipset_tc86c001,
  	.init_hwif	= init_hwif_tc86c001,
@@ -412592,7 +419365,7 @@
  	.mwdma_mask	= ATA_MWDMA2,
  	.udma_mask	= ATA_UDMA4,
 diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
-index a227c41..852b726 100644
+index a227c41..a67d02a 100644
 --- a/drivers/ide/pci/triflex.c
 +++ b/drivers/ide/pci/triflex.c
 @@ -1,6 +1,4 @@
@@ -412602,7 +419375,19 @@
   * IDE Chipset driver for the Compaq TriFlex IDE controller.
   * 
   * Known to work with the Compaq Workstation 5x00 series.
-@@ -43,7 +41,7 @@
+@@ -30,11 +28,6 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/mm.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/pci.h>
+ #include <linux/ide.h>
+@@ -43,7 +36,7 @@
  static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
  {
  	ide_hwif_t *hwif = HWIF(drive);
@@ -412611,7 +419396,7 @@
  	u8 channel_offset = hwif->channel ? 0x74 : 0x70;
  	u16 timing = 0;
  	u32 triflex_timings = 0;
-@@ -81,8 +79,6 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
+@@ -81,8 +74,6 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
  		case XFER_PIO_0:
  			timing = 0x0808;
  			break;
@@ -412621,7 +419406,7 @@
  
  	triflex_timings &= ~(0xFFFF << (16 * unit));
 diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
-index 0151d7f..d9ebb69 100644
+index 0151d7f..de750f7 100644
 --- a/drivers/ide/pci/trm290.c
 +++ b/drivers/ide/pci/trm290.c
 @@ -1,8 +1,7 @@
@@ -412634,7 +419419,34 @@
   *  May be copied or modified under the terms of the GNU General Public License
   *
   *  June 22, 2004 - get rid of check_region
-@@ -209,10 +208,10 @@ static int trm290_dma_setup(ide_drive_t *drive)
+@@ -132,14 +131,12 @@
+ #include <linux/types.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/mm.h>
+ #include <linux/ioport.h>
+ #include <linux/interrupt.h>
+ #include <linux/blkdev.h>
+ #include <linux/init.h>
+ #include <linux/hdreg.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+ #include <linux/ide.h>
+ 
+ #include <asm/io.h>
+@@ -180,10 +177,7 @@ static void trm290_selectproc (ide_drive_t *drive)
+ 
+ static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command)
+ {
+-	BUG_ON(HWGROUP(drive)->handler != NULL);	/* paranoia check */
+-	ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
+-	/* issue cmd to drive */
+-	outb(command, IDE_COMMAND_REG);
++	ide_execute_command(drive, command, &ide_dma_intr, WAIT_CMD, NULL);
+ }
+ 
+ static int trm290_dma_setup(ide_drive_t *drive)
+@@ -209,10 +203,10 @@ static int trm290_dma_setup(ide_drive_t *drive)
  	}
  	/* select DMA xfer */
  	trm290_prepare_drive(drive, 1);
@@ -412647,7 +419459,7 @@
  	return 0;
  }
  
-@@ -222,51 +221,61 @@ static void trm290_dma_start(ide_drive_t *drive)
+@@ -222,51 +216,61 @@ static void trm290_dma_start(ide_drive_t *drive)
  
  static int trm290_ide_dma_end (ide_drive_t *drive)
  {
@@ -412734,7 +419546,7 @@
  	local_irq_save(flags);
  	/* put config reg into first byte of hwif->select_data */
  	outb(0x51 | (hwif->channel << 3), hwif->config_data + 1);
-@@ -280,17 +289,14 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
+@@ -280,17 +284,14 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
  	outb(reg, hwif->config_data + 3);
  	local_irq_restore(flags);
  
@@ -412755,7 +419567,7 @@
  	hwif->dma_exec_cmd	= &trm290_dma_exec_cmd;
  	hwif->dma_start 	= &trm290_dma_start;
 diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
-index a0d3c16..24cb904 100644
+index a0d3c16..f3f79f8 100644
 --- a/drivers/ide/pci/via82cxxx.c
 +++ b/drivers/ide/pci/via82cxxx.c
 @@ -1,7 +1,4 @@
@@ -412766,7 +419578,23 @@
   * VIA IDE driver for Linux. Supported southbridges:
   *
   *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
-@@ -121,8 +118,8 @@ struct via82cxxx_dev
+@@ -29,15 +26,11 @@
+ 
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/ioport.h>
+-#include <linux/blkdev.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/ide.h>
+ #include <linux/dmi.h>
+ 
+-#include <asm/io.h>
+-
+ #ifdef CONFIG_PPC_CHRP
+ #include <asm/processor.h>
+ #endif
+@@ -121,8 +114,8 @@ struct via82cxxx_dev
  
  static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
  {
@@ -412777,7 +419605,7 @@
  	u8 t;
  
  	if (~vdev->via_config->flags & VIA_BAD_AST) {
-@@ -159,8 +156,10 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
+@@ -159,8 +152,10 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
  
  static void via_set_drive(ide_drive_t *drive, const u8 speed)
  {
@@ -412790,7 +419618,7 @@
  	struct ide_timing t, p;
  	unsigned int T, UT;
  
-@@ -408,7 +407,7 @@ static int via_cable_override(struct pci_dev *pdev)
+@@ -408,7 +403,7 @@ static int via_cable_override(struct pci_dev *pdev)
  
  static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif)
  {
@@ -412799,7 +419627,20 @@
  	struct via82cxxx_dev *vdev = pci_get_drvdata(pdev);
  
  	if (via_cable_override(pdev))
-@@ -439,6 +438,7 @@ static const struct ide_port_info via82cxxx_chipset __devinitdata = {
+@@ -425,11 +420,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
+ 	hwif->set_pio_mode = &via_set_pio_mode;
+ 	hwif->set_dma_mode = &via_set_drive;
+ 
+-	if (!hwif->dma_base)
+-		return;
+-
+-	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
+-		hwif->cbl = via82cxxx_cable_detect(hwif);
++	hwif->cable_detect = via82cxxx_cable_detect;
+ }
+ 
+ static const struct ide_port_info via82cxxx_chipset __devinitdata = {
+@@ -439,6 +430,7 @@ static const struct ide_port_info via82cxxx_chipset __devinitdata = {
  	.enablebits	= { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
  	.host_flags	= IDE_HFLAG_PIO_NO_BLACKLIST |
  			  IDE_HFLAG_PIO_NO_DOWNGRADE |
@@ -412817,7 +419658,7 @@
 +obj-$(CONFIG_BLK_DEV_IDE_PMAC)		+= pmac.o
 +obj-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= mpc8xx.o
 diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
-index 5f0da35..45c1d55 100644
+index 5f0da35..06190b1 100644
 --- a/drivers/ide/ppc/mpc8xx.c
 +++ b/drivers/ide/ppc/mpc8xx.c
 @@ -1,6 +1,4 @@
@@ -412843,14 +419684,14 @@
 +#endif
 +#endif
 +
-+	ide_device_add(idx);
++	ide_device_add(idx, NULL);
 +
 +	return 0;
 +}
 +
 +module_init(mpc8xx_ide_probe);
 diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
-index 7f7a598..23112ef 100644
+index 7f7a598..12ac3bf 100644
 --- a/drivers/ide/ppc/pmac.c
 +++ b/drivers/ide/ppc/pmac.c
 @@ -1,7 +1,6 @@
@@ -412862,6 +419703,15 @@
   * These IDE interfaces are memory-mapped and have a DBDMA channel
   * for doing DMA.
   *
+@@ -413,7 +412,7 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
+  */
+ #define IDE_WAKEUP_DELAY	(1*HZ)
+ 
+-static void pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif);
++static int pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif);
+ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq);
+ static void pmac_ide_selectproc(ide_drive_t *drive);
+ static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
 @@ -438,13 +437,8 @@ pmac_ide_init_hwif_ports(hw_regs_t *hw,
  		if (data_port == pmac_ide[ix].regbase)
  			break;
@@ -412929,7 +419779,25 @@
  	if (ret)
  		return;
  
-@@ -1034,13 +1010,12 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
+@@ -1027,6 +1003,17 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
+ 	return 0;
+ }
+ 
++static const struct ide_port_info pmac_port_info = {
++	.chipset		= ide_pmac,
++	.host_flags		= IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
++				  IDE_HFLAG_PIO_NO_DOWNGRADE |
++				  IDE_HFLAG_POST_SET_MODE |
++				  IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
++				  IDE_HFLAG_UNMASK_IRQS,
++	.pio_mask		= ATA_PIO4,
++	.mwdma_mask		= ATA_MWDMA2,
++};
++
+ /*
+  * Setup, register & probe an IDE channel driven by this driver, this is
+  * called by one of the 2 probe functions (macio or PCI). Note that a channel
+@@ -1034,30 +1021,34 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
   * (it is kept in 2.4). This introduce an interface numbering change on some
   * rare machines unfortunately, but it's better this way.
   */
@@ -412942,10 +419810,40 @@
  	const int *bidp;
  	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 -	hw_regs_t hw;
++	struct ide_port_info d = pmac_port_info;
  
  	pmif->cable_80 = 0;
  	pmif->broken_dma = pmif->broken_dma_warn = 0;
-@@ -1126,11 +1101,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+-	if (of_device_is_compatible(np, "shasta-ata"))
++	if (of_device_is_compatible(np, "shasta-ata")) {
+ 		pmif->kind = controller_sh_ata6;
+-	else if (of_device_is_compatible(np, "kauai-ata"))
++		d.udma_mask = ATA_UDMA6;
++	} else if (of_device_is_compatible(np, "kauai-ata")) {
+ 		pmif->kind = controller_un_ata6;
+-	else if (of_device_is_compatible(np, "K2-UATA"))
++		d.udma_mask = ATA_UDMA5;
++	} else if (of_device_is_compatible(np, "K2-UATA")) {
+ 		pmif->kind = controller_k2_ata6;
+-	else if (of_device_is_compatible(np, "keylargo-ata")) {
+-		if (strcmp(np->name, "ata-4") == 0)
++		d.udma_mask = ATA_UDMA5;
++	} else if (of_device_is_compatible(np, "keylargo-ata")) {
++		if (strcmp(np->name, "ata-4") == 0) {
+ 			pmif->kind = controller_kl_ata4;
+-		else
++			d.udma_mask = ATA_UDMA4;
++		} else
+ 			pmif->kind = controller_kl_ata3;
+-	} else if (of_device_is_compatible(np, "heathrow-ata"))
++	} else if (of_device_is_compatible(np, "heathrow-ata")) {
+ 		pmif->kind = controller_heathrow;
+-	else {
++	} else {
+ 		pmif->kind = controller_ohare;
+ 		pmif->broken_dma = 1;
+ 	}
+@@ -1126,21 +1117,10 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
  	/* Tell common code _not_ to mess with resources */
  	hwif->mmio = 1;
  	hwif->hwif_data = pmif;
@@ -412954,22 +419852,46 @@
 -	memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
 -	hwif->chipset = ide_pmac;
 -	hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;
-+	hw->chipset = ide_pmac;
 +	ide_init_port_hw(hwif, hw);
 +	hwif->noprobe = pmif->mediabay;
  	hwif->hold = pmif->mediabay;
  	hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
- 	hwif->drives[0].unmask = 1;
-@@ -1159,8 +1132,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+-	hwif->drives[0].unmask = 1;
+-	hwif->drives[1].unmask = 1;
+-	hwif->drives[0].autotune = IDE_TUNE_AUTO;
+-	hwif->drives[1].autotune = IDE_TUNE_AUTO;
+-	hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
+-			   IDE_HFLAG_PIO_NO_DOWNGRADE |
+-			   IDE_HFLAG_POST_SET_MODE;
+-	hwif->pio_mask = ATA_PIO4;
+ 	hwif->set_pio_mode = pmac_ide_set_pio_mode;
+ 	if (pmif->kind == controller_un_ata6
+ 	    || pmif->kind == controller_k2_ata6
+@@ -1159,17 +1139,17 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
  		hwif->noprobe = 0;
  #endif /* CONFIG_PMAC_MEDIABAY */
  
 -	hwif->sg_max_nents = MAX_DCMDS;
 -
  #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
++	if (pmif->cable_80 == 0)
++		d.udma_mask &= ATA_UDMA2;
  	/* has a DBDMA controller channel */
- 	if (pmif->dma_regs)
-@@ -1186,6 +1157,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
+-	if (pmif->dma_regs)
+-		pmac_ide_setup_dma(pmif, hwif);
+-#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
++	if (pmif->dma_regs == 0 || pmac_ide_setup_dma(pmif, hwif) < 0)
++#endif
++		d.udma_mask = d.mwdma_mask = 0;
+ 
+ 	idx[0] = hwif->index;
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, &d);
+ 
+ 	return 0;
+ }
+@@ -1186,6 +1166,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
  	ide_hwif_t *hwif;
  	pmac_ide_hwif_t *pmif;
  	int i, rc;
@@ -412977,7 +419899,7 @@
  
  	i = 0;
  	while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0
-@@ -1227,8 +1199,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
+@@ -1227,8 +1208,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
  	base = ioremap(macio_resource_start(mdev, 0), 0x400);
  	regbase = (unsigned long) base;
  
@@ -412987,7 +419909,7 @@
  
  	pmif->mdev = mdev;
  	pmif->node = mdev->ofdev.node;
-@@ -1246,17 +1217,22 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
+@@ -1246,17 +1226,22 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
  #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
  	dev_set_drvdata(&mdev->ofdev.dev, hwif);
  
@@ -413014,7 +419936,7 @@
  	}
  
  	return rc;
-@@ -1305,6 +1281,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
+@@ -1305,6 +1290,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
  	void __iomem *base;
  	unsigned long rbase, rlen;
  	int i, rc;
@@ -413022,7 +419944,7 @@
  
  	np = pci_device_to_OF_node(pdev);
  	if (np == NULL) {
-@@ -1337,8 +1314,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
+@@ -1337,8 +1323,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
  		return -ENXIO;
  	}
  
@@ -413032,7 +419954,7 @@
  	pmif->mdev = NULL;
  	pmif->node = np;
  
-@@ -1355,7 +1331,12 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
+@@ -1355,7 +1340,12 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
  
  	pci_set_drvdata(pdev, hwif);
  
@@ -413046,7 +419968,7 @@
  	if (rc != 0) {
  		/* The inteface is released to the common IDE layer */
  		pci_set_drvdata(pdev, NULL);
-@@ -1553,11 +1534,10 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+@@ -1553,11 +1543,10 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
  	}
  
  	printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
@@ -413062,7 +419984,7 @@
  	return 0; /* revert to PIO for this request */
  }
  
-@@ -1566,12 +1546,9 @@ static void
+@@ -1566,12 +1555,9 @@ static void
  pmac_ide_destroy_dmatable (ide_drive_t *drive)
  {
  	ide_hwif_t *hwif = drive->hwif;
@@ -413077,7 +419999,7 @@
  		hwif->sg_nents = 0;
  	}
  }
-@@ -1721,11 +1698,7 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
+@@ -1721,11 +1707,7 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
  	return 1;
  }
  
@@ -413090,13 +420012,13 @@
  {
  }
  
-@@ -1748,13 +1721,15 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive)
+@@ -1748,64 +1730,44 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive)
   * Allocate the data structures needed for using DMA with an interface
   * and fill the proper list of functions pointers
   */
 -static void __init 
-+static void __devinit
- pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+-pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
++static int __devinit pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
  {
 +	struct pci_dev *dev = to_pci_dev(hwif->dev);
 +
@@ -413104,11 +420026,12 @@
  	 * DMA routines ...
  	 */
 -	if (hwif->pci_dev == NULL)
+-		return;
 +	if (dev == NULL)
- 		return;
++		return -ENODEV;
  	/*
  	 * Allocate space for the DBDMA commands.
-@@ -1762,7 +1737,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+ 	 * The +2 is +1 for the stop command and +1 to allow for
  	 * aligning the start address to a multiple of 16 bytes.
  	 */
  	pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent(
@@ -413117,8 +420040,10 @@
  		(MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
  		&hwif->dmatable_dma);
  	if (pmif->dma_table_cpu == NULL) {
-@@ -1771,15 +1746,14 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
- 		return;
+ 		printk(KERN_ERR "%s: unable to allocate DMA command list\n",
+ 		       hwif->name);
+-		return;
++		return -ENOMEM;
  	}
  
 -	hwif->dma_off_quietly = &ide_dma_off_quietly;
@@ -413136,14 +420061,37 @@
  	hwif->dma_timeout = &ide_dma_timeout;
  	hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
  
-@@ -1809,3 +1783,5 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+-	switch(pmif->kind) {
+-		case controller_sh_ata6:
+-			hwif->ultra_mask = pmif->cable_80 ? 0x7f : 0x07;
+-			hwif->mwdma_mask = 0x07;
+-			hwif->swdma_mask = 0x00;
+-			break;
+-		case controller_un_ata6:
+-		case controller_k2_ata6:
+-			hwif->ultra_mask = pmif->cable_80 ? 0x3f : 0x07;
+-			hwif->mwdma_mask = 0x07;
+-			hwif->swdma_mask = 0x00;
+-			break;
+-		case controller_kl_ata4:
+-			hwif->ultra_mask = pmif->cable_80 ? 0x1f : 0x07;
+-			hwif->mwdma_mask = 0x07;
+-			hwif->swdma_mask = 0x00;
+-			break;
+-		default:
+-			hwif->ultra_mask = 0x00;
+-			hwif->mwdma_mask = 0x07;
+-			hwif->swdma_mask = 0x00;
+-			break;
+-	}
++	return 0;
  }
  
  #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 +
 +module_init(pmac_ide_probe);
 diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
-index d2cd5a3..05db429 100644
+index d2cd5a3..634e3f6 100644
 --- a/drivers/ide/setup-pci.c
 +++ b/drivers/ide/setup-pci.c
 @@ -1,9 +1,8 @@
@@ -413254,7 +420202,7 @@
 +	if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) {
 +		ide_pci_clear_simplex(dma_base, d->name);
 +		goto out;
-+	}
+ 	}
 +
 +	/*
 +	 * If the device claims "simplex" DMA, this means that only one of
@@ -413270,7 +420218,7 @@
 +	if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) {
 +		printk(KERN_INFO "%s: simplex device: DMA disabled\n", d->name);
 +		dma_base = 0;
- 	}
++	}
 +out:
  	return dma_base;
  }
@@ -413295,7 +420243,25 @@
  		if (ret < 0) {
  			printk(KERN_WARNING "%s: (ide_setup_pci_device:) "
  				"Could not enable device.\n", d->name);
-@@ -359,6 +353,8 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port
+@@ -345,7 +339,8 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
+  *	ide_hwif_configure	-	configure an IDE interface
+  *	@dev: PCI device holding interface
+  *	@d: IDE port info
+- *	@mate: Paired interface if any
++ *	@port: port number
++ *	@irq: PCI IRQ
+  *
+  *	Perform the initial set up for the hardware interface structure. This
+  *	is done per interface port rather than per PCI device. There may be
+@@ -354,11 +349,15 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
+  *	Returns the new hardware interface structure, or NULL on a failure
+  */
+ 
+-static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *mate, int port, int irq)
++static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
++				      const struct ide_port_info *d,
++				      unsigned int port, int irq)
+ {
  	unsigned long ctl = 0, base = 0;
  	ide_hwif_t *hwif;
  	u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0;
@@ -413304,7 +420270,7 @@
  
  	if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
  		/*  Possibly we should fail if these checks report true */
-@@ -381,26 +377,25 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port
+@@ -381,47 +380,41 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port
  	}
  	if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL)
  		return NULL;	/* no room in ide_hwifs[] */
@@ -413340,14 +420306,39 @@
 +
 +	hwif->dev = &dev->dev;
  	hwif->cds = d;
- 	hwif->channel = port;
+-	hwif->channel = port;
  
 -	if (!hwif->irq)
 -		hwif->irq = irq;
- 	if (mate) {
- 		hwif->mate = mate;
- 		mate->mate = hwif;
-@@ -446,7 +441,7 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *
+-	if (mate) {
+-		hwif->mate = mate;
+-		mate->mate = hwif;
+-	}
+ 	return hwif;
+ }
+ 
++#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+ /**
+  *	ide_hwif_setup_dma	-	configure DMA interface
+- *	@dev: PCI device
+- *	@d: IDE port info
+  *	@hwif: IDE interface
++ *	@d: IDE port info
+  *
+  *	Set up the DMA base for the interface. Enable the master bits as
+  *	necessary and attempt to bring the device DMA into a ready to use
+  *	state
+  */
+ 
+-static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *hwif)
++void ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
+ {
+-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
++	struct pci_dev *dev = to_pci_dev(hwif->dev);
+ 	u16 pcicmd;
+ 
+ 	pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
+@@ -446,15 +439,15 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *
  			if (d->init_dma) {
  				d->init_dma(hwif, dma_base);
  			} else {
@@ -413356,29 +420347,106 @@
  			}
  		} else {
  			printk(KERN_INFO "%s: %s Bus-Master DMA disabled "
-@@ -535,12 +530,8 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
- 		if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
+ 				"(BIOS)\n", hwif->name, d->name);
+ 		}
+ 	}
+-#endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/
+ }
++#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
+ 
+ /**
+  *	ide_setup_pci_controller	-	set up IDE PCI
+@@ -516,7 +509,7 @@ out:
+ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int pciirq, u8 *idx)
+ {
+ 	int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
+-	ide_hwif_t *hwif, *mate = NULL;
++	ide_hwif_t *hwif;
+ 	u8 tmp;
+ 
+ 	/*
+@@ -532,62 +525,11 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
+ 			continue;	/* port not enabled */
+ 		}
+ 
+-		if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
++		hwif = ide_hwif_configure(dev, d, port, pciirq);
++		if (hwif == NULL)
  			continue;
  
 -		/* setup proper ancestral information */
 -		hwif->gendev.parent = &dev->dev;
 -
  		*(idx + port) = hwif->index;
- 
+-
 -		
- 		if (d->init_iops)
- 			d->init_iops(hwif);
- 
-@@ -551,8 +542,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
- 		    (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
- 			hwif->irq = port ? 15 : 14;
- 
+-		if (d->init_iops)
+-			d->init_iops(hwif);
+-
+-		if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
+-			ide_hwif_setup_dma(dev, d, hwif);
+-
+-		if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
+-		    (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
+-			hwif->irq = port ? 15 : 14;
+-
 -		hwif->fixup = d->fixup;
 -
- 		hwif->host_flags = d->host_flags;
- 		hwif->pio_mask = d->pio_mask;
+-		hwif->host_flags = d->host_flags;
+-		hwif->pio_mask = d->pio_mask;
+-
+-		if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)
+-			hwif->mate->serialized = hwif->serialized = 1;
+-
+-		if (d->host_flags & IDE_HFLAG_IO_32BIT) {
+-			hwif->drives[0].io_32bit = 1;
+-			hwif->drives[1].io_32bit = 1;
+-		}
+-
+-		if (d->host_flags & IDE_HFLAG_UNMASK_IRQS) {
+-			hwif->drives[0].unmask = 1;
+-			hwif->drives[1].unmask = 1;
+-		}
+-
+-		if (hwif->dma_base) {
+-			hwif->swdma_mask = d->swdma_mask;
+-			hwif->mwdma_mask = d->mwdma_mask;
+-			hwif->ultra_mask = d->udma_mask;
+-		}
+-
+-		hwif->drives[0].autotune = 1;
+-		hwif->drives[1].autotune = 1;
+-
+-		if (d->host_flags & IDE_HFLAG_RQSIZE_256)
+-			hwif->rqsize = 256;
+-
+-		if (d->init_hwif)
+-			/* Call chipset-specific routine
+-			 * for each enabled hwif
+-			 */
+-			d->init_hwif(hwif);
+-
+-		mate = hwif;
+ 	}
+ }
+ 
+@@ -669,7 +611,7 @@ int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d)
+ 	ret = do_ide_setup_pci_device(dev, d, &idx[0], 1);
+ 
+ 	if (ret >= 0)
+-		ide_device_add(idx);
++		ide_device_add(idx, d);
  
-@@ -699,105 +688,3 @@ out:
+ 	return ret;
+ }
+@@ -693,111 +635,9 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
+ 			goto out;
+ 	}
+ 
+-	ide_device_add(idx);
++	ide_device_add(idx, d);
+ out:
+ 	return ret;
  }
  
  EXPORT_SYMBOL_GPL(ide_setup_pci_devices);
@@ -414397,7 +421465,7 @@
  	       (u16) ((addr >> 32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
  	       length);
 diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
-index b83d254..2b889d9 100644
+index b83d254..28e155a 100644
 --- a/drivers/ieee1394/sbp2.c
 +++ b/drivers/ieee1394/sbp2.c
 @@ -51,6 +51,7 @@
@@ -414447,15 +421515,16 @@
  				     u32 orb_direction,
  				     enum dma_data_direction dma_dir)
  {
-@@ -1461,12 +1466,12 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
+@@ -1460,13 +1465,12 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
+ 	orb->misc |= ORB_SET_DIRECTION(orb_direction);
  
  	/* special case if only one element (and less than 64KB in size) */
- 	if ((scsi_use_sg == 1) &&
+-	if ((scsi_use_sg == 1) &&
 -	    (sgpnt[0].length <= SBP2_MAX_SG_ELEMENT_LENGTH)) {
-+	    (sg_dma_len(sg) <= SBP2_MAX_SG_ELEMENT_LENGTH)) {
++	if (scsi_use_sg == 1 && sg->length <= SBP2_MAX_SG_ELEMENT_LENGTH) {
  
 -		cmd->dma_size = sgpnt[0].length;
-+		cmd->dma_size = sg_dma_len(sg);
++		cmd->dma_size = sg->length;
  		cmd->dma_type = CMD_DMA_PAGE;
  		cmd->cmd_dma = dma_map_page(hi->host->device.parent,
 -					    sg_page(&sgpnt[0]), sgpnt[0].offset,
@@ -414463,7 +421532,7 @@
  					    cmd->dma_size, cmd->dma_dir);
  
  		orb->data_descriptor_lo = cmd->cmd_dma;
-@@ -1477,11 +1482,11 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
+@@ -1477,11 +1481,11 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
  						&cmd->scatter_gather_element[0];
  		u32 sg_count, sg_len;
  		dma_addr_t sg_addr;
@@ -414477,7 +421546,7 @@
  
  		/* use page tables (s/g) */
  		orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
-@@ -1489,9 +1494,9 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
+@@ -1489,9 +1493,9 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
  
  		/* loop through and fill out our SBP-2 page tables
  		 * (and split up anything too large) */
@@ -414490,7 +421559,7 @@
  			while (sg_len) {
  				sg_element[sg_count].segment_base_lo = sg_addr;
  				if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
-@@ -1521,11 +1526,10 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu,
+@@ -1521,11 +1525,10 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu,
  				    unchar *scsi_cmd,
  				    unsigned int scsi_use_sg,
  				    unsigned int scsi_request_bufflen,
@@ -414503,7 +421572,7 @@
  	struct sbp2_command_orb *orb = &cmd->command_orb;
  	u32 orb_direction;
  
-@@ -1560,7 +1564,7 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu,
+@@ -1560,7 +1563,7 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu,
  		orb->data_descriptor_lo = 0x0;
  		orb->misc |= ORB_SET_DIRECTION(1);
  	} else
@@ -414512,7 +421581,7 @@
  					 orb_direction, dma_dir);
  
  	sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb));
-@@ -1650,7 +1654,6 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt,
+@@ -1650,7 +1653,6 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt,
  			     void (*done)(struct scsi_cmnd *))
  {
  	unchar *scsi_cmd = (unchar *)SCpnt->cmnd;
@@ -414520,7 +421589,7 @@
  	struct sbp2_command_info *cmd;
  
  	cmd = sbp2util_allocate_command_orb(lu, SCpnt, done);
-@@ -1658,7 +1661,7 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt,
+@@ -1658,7 +1660,7 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt,
  		return -EIO;
  
  	sbp2_create_command_orb(lu, cmd, scsi_cmd, scsi_sg_count(SCpnt),
@@ -414529,7 +421598,7 @@
  				SCpnt->sc_data_direction);
  	sbp2_link_orb_command(lu, cmd);
  
-@@ -1963,6 +1966,12 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
+@@ -1963,6 +1965,12 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
  	lu->sdev = sdev;
  	sdev->allow_restart = 1;
  
@@ -414542,7 +421611,7 @@
  	if (lu->workarounds & SBP2_WORKAROUND_INQUIRY_36)
  		sdev->inquiry_len = 36;
  	return 0;
-@@ -1981,6 +1990,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev)
+@@ -1981,6 +1989,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev)
  		sdev->skip_ms_page_8 = 1;
  	if (lu->workarounds & SBP2_WORKAROUND_FIX_CAPACITY)
  		sdev->fix_capacity = 1;
@@ -414551,7 +421620,7 @@
  	return 0;
  }
  
-@@ -2087,9 +2098,6 @@ static int sbp2_module_init(void)
+@@ -2087,9 +2097,6 @@ static int sbp2_module_init(void)
  		sbp2_shost_template.cmd_per_lun = 1;
  	}
  
@@ -441595,7 +448664,7 @@
 +	platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
  }
 diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
-index 48d647a..18dde2a 100644
+index 48d647a..de9ebbf 100644
 --- a/drivers/macintosh/mediabay.c
 +++ b/drivers/macintosh/mediabay.c
 @@ -20,6 +20,7 @@
@@ -441624,6 +448693,15 @@
  				pmu_resume();
  			}
  			if (bay->cd_index == -1) {
+@@ -594,7 +595,7 @@ static void media_bay_step(int i)
+     	        if (bay->cd_index >= 0) {
+ 			printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i,
+ 			       bay->cd_index);
+-			ide_unregister(bay->cd_index);
++			ide_unregister(bay->cd_index, 1, 1);
+ 			bay->cd_index = -1;
+ 		}
+ 	    	if (bay->cd_retry) {
 @@ -622,12 +623,7 @@ static int media_bay_task(void *x)
  {
  	int	i;
@@ -708186,7 +715264,7 @@
  
  	spin_lock_irqsave(&target->lock, flags);
 diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
-index 9706de9..5ed0006 100644
+index 9706de9..6c4f0f0 100644
 --- a/drivers/scsi/ide-scsi.c
 +++ b/drivers/scsi/ide-scsi.c
 @@ -1,7 +1,6 @@
@@ -708326,7 +715404,7 @@
  		printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while "
  				"issuing a packet command\n");
  		return ide_do_reset (drive);
-@@ -573,30 +573,26 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
+@@ -573,38 +573,29 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
  {
  	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
  	ide_hwif_t *hwif = drive->hwif;
@@ -708350,21 +715428,31 @@
  		hwif->sg_mapped = 0;
  	}
  
- 	SELECT_DRIVE(drive);
+-	SELECT_DRIVE(drive);
 -	if (IDE_CONTROL_REG)
 -		HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
++	ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK, bcount, dma);
  
 -	HWIF(drive)->OUTB(feature.all, IDE_FEATURE_REG);
 -	HWIF(drive)->OUTB(bcount.b.high, IDE_BCOUNTH_REG);
 -	HWIF(drive)->OUTB(bcount.b.low, IDE_BCOUNTL_REG);
-+	ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK, bcount, dma);
- 
+-
 -	if (feature.b.dma)
 +	if (dma)
  		set_bit(PC_DMA_OK, &pc->flags);
  
  	if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
-@@ -922,8 +918,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
+-		BUG_ON(HWGROUP(drive)->handler != NULL);
+-		ide_set_handler(drive, &idescsi_transfer_pc,
+-				get_timeout(pc), idescsi_expiry);
+-		/* Issue the packet command */
+-		HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG);
++		ide_execute_command(drive, WIN_PACKETCMD, &idescsi_transfer_pc,
++				    get_timeout(pc), idescsi_expiry);
+ 		return ide_started;
+ 	} else {
+ 		/* Issue the packet command */
+@@ -922,8 +913,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
  	}
  
  	/* kill current request */
@@ -708375,7 +715463,7 @@
  	if (blk_sense_request(req))
  		kfree(scsi->pc->buffer);
  	kfree(scsi->pc);
-@@ -932,8 +928,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
+@@ -932,8 +923,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd)
  
  	/* now nuke the drive queue */
  	while ((req = elv_next_request(drive->queue))) {
@@ -854584,7 +861672,7 @@
  #ifdef CONFIG_PREEMPT
  # define PREEMPT_CHECK_OFFSET 1
 diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h
-index 818c6af..ff43f8d 100644
+index 818c6af..3882013 100644
 --- a/include/linux/hdreg.h
 +++ b/include/linux/hdreg.h
 @@ -44,7 +44,9 @@
@@ -854721,6 +861809,18 @@
  
  /* ATA/ATAPI Commands pre T13 Spec */
  #define WIN_NOP				0x00
+@@ -700,8 +706,10 @@ struct hd_driveid {
+  */
+ #define IDE_NICE_DSC_OVERLAP	(0)	/* per the DSC overlap protocol */
+ #define IDE_NICE_ATAPI_OVERLAP	(1)	/* not supported yet */
+-#define IDE_NICE_0		(2)	/* when sure that it won't affect us */
+ #define IDE_NICE_1		(3)	/* when probably won't affect us much */
++#ifndef __KERNEL__
++#define IDE_NICE_0		(2)	/* when sure that it won't affect us */
+ #define IDE_NICE_2		(4)	/* when we know it's on our expense */
++#endif
+ 
+ #endif	/* _LINUX_HDREG_H */
 diff --git a/include/linux/hdsmart.h b/include/linux/hdsmart.h
 index 7974a47..e691921 100644
 --- a/include/linux/hdsmart.h
@@ -855509,7 +862609,7 @@
 +#endif /*  __LINUX_I2C_TPS65010_H */
 +
 diff --git a/include/linux/ide.h b/include/linux/ide.h
-index 9a6a41e..ec10b2a 100644
+index 9a6a41e..367c170 100644
 --- a/include/linux/ide.h
 +++ b/include/linux/ide.h
 @@ -9,7 +9,6 @@
@@ -855570,7 +862670,7 @@
  #define IDE_DATA_REG		(HWIF(drive)->io_ports[IDE_DATA_OFFSET])
  #define IDE_ERROR_REG		(HWIF(drive)->io_ports[IDE_ERROR_OFFSET])
  #define IDE_NSECTOR_REG		(HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET])
-@@ -128,7 +106,6 @@ typedef unsigned char	byte;	/* used everywhere */
+@@ -128,25 +106,18 @@ typedef unsigned char	byte;	/* used everywhere */
  #define BAD_W_STAT		(BAD_R_STAT  | WRERR_STAT)
  #define BAD_STAT		(BAD_R_STAT  | DRQ_STAT)
  #define DRIVE_READY		(READY_STAT  | SEEK_STAT)
@@ -855578,10 +862678,29 @@
  
  #define BAD_CRC			(ABRT_ERR    | ICRC_ERR)
  
-@@ -219,8 +196,11 @@ typedef struct hw_regs_s {
+ #define SATA_NR_PORTS		(3)	/* 16 possible ?? */
+ 
+ #define SATA_STATUS_OFFSET	(0)
+-#define SATA_STATUS_REG		(HWIF(drive)->sata_scr[SATA_STATUS_OFFSET])
+ #define SATA_ERROR_OFFSET	(1)
+-#define SATA_ERROR_REG		(HWIF(drive)->sata_scr[SATA_ERROR_OFFSET])
+ #define SATA_CONTROL_OFFSET	(2)
+-#define SATA_CONTROL_REG	(HWIF(drive)->sata_scr[SATA_CONTROL_OFFSET])
+ 
+ #define SATA_MISC_OFFSET	(0)
+-#define SATA_MISC_REG		(HWIF(drive)->sata_misc[SATA_MISC_OFFSET])
+ #define SATA_PHY_OFFSET		(1)
+-#define SATA_PHY_REG		(HWIF(drive)->sata_misc[SATA_PHY_OFFSET])
+ #define SATA_IEN_OFFSET		(2)
+-#define SATA_IEN_REG		(HWIF(drive)->sata_misc[SATA_IEN_OFFSET])
+ 
+ /*
+  * Our Physical Region Descriptor (PRD) table should be large enough
+@@ -219,8 +190,12 @@ typedef struct hw_regs_s {
  } hw_regs_t;
  
  struct hwif_s * ide_find_port(unsigned long);
++struct hwif_s *ide_deprecated_find_port(unsigned long);
 +void ide_init_port_data(struct hwif_s *, unsigned int);
 +void ide_init_port_hw(struct hwif_s *, hw_regs_t *);
  
@@ -855591,7 +862710,7 @@
  		    struct hwif_s **);
  
  void ide_setup_ports(	hw_regs_t *hw,
-@@ -327,47 +307,16 @@ static inline void ide_init_hwif_ports(hw_regs_t *hw,
+@@ -327,47 +302,16 @@ static inline void ide_init_hwif_ports(hw_regs_t *hw,
  typedef union {
  	unsigned all			: 8;
  	struct {
@@ -855639,7 +862758,7 @@
   * ATA-IDE Select Register, aka Device-Head
   *
   * head		: always zeros here
-@@ -398,131 +347,6 @@ typedef union {
+@@ -398,131 +342,6 @@ typedef union {
  } select_t, ata_select_t;
  
  /*
@@ -855771,7 +862890,7 @@
   * Status returned from various ide_ functions
   */
  typedef enum {
-@@ -568,7 +392,6 @@ typedef struct ide_drive_s {
+@@ -568,7 +387,6 @@ typedef struct ide_drive_s {
  	u8	state;			/* retry state */
  	u8	waiting_for_dma;	/* dma currently in progress */
  	u8	unmask;			/* okay to unmask other irqs */
@@ -855779,7 +862898,24 @@
  	u8	noflush;		/* don't attempt flushes */
  	u8	dsc_overlap;		/* DSC overlap */
  	u8	nice1;			/* give potential excess bandwidth */
-@@ -679,7 +502,8 @@ typedef struct hwif_s {
+@@ -583,8 +401,6 @@ typedef struct ide_drive_s {
+ 	unsigned no_unmask	: 1;	/* disallow setting unmask bit */
+ 	unsigned no_io_32bit	: 1;	/* disallow enabling 32bit I/O */
+ 	unsigned atapi_overlap	: 1;	/* ATAPI overlap (not supported) */
+-	unsigned nice0		: 1;	/* give obvious excess bandwidth */
+-	unsigned nice2		: 1;	/* give a share in our own bandwidth */
+ 	unsigned doorlocking	: 1;	/* for removable only: door lock/unlock works */
+ 	unsigned nodma		: 1;	/* disallow DMA */
+ 	unsigned autotune	: 2;	/* 0=default, 1=autotune, 2=noautotune */
+@@ -664,7 +480,6 @@ typedef struct hwif_s {
+ 	u8 major;	/* our major number */
+ 	u8 index;	/* 0 for ide0; 1 for ide1; ... */
+ 	u8 channel;	/* for dual-port chips: 0=primary, 1=secondary */
+-	u8 straight8;	/* Alan's straight 8 check */
+ 	u8 bus_state;	/* power state of the IDE bus */
+ 
+ 	u32 host_flags;
+@@ -679,7 +494,8 @@ typedef struct hwif_s {
  
  	hwif_chipset_t chipset;	/* sub-module for tuning.. */
  
@@ -855789,7 +862925,16 @@
  	const struct ide_port_info *cds;	/* chipset device struct */
  
  	ide_ack_intr_t *ack_intr;
-@@ -701,36 +525,29 @@ typedef struct hwif_s {
+@@ -689,6 +505,8 @@ typedef struct hwif_s {
+ #if 0
+ 	ide_hwif_ops_t	*hwifops;
+ #else
++	/* host specific initialization of devices on a port */
++	void	(*port_init_devs)(struct hwif_s *);
+ 	/* routine to program host for PIO mode */
+ 	void	(*set_pio_mode)(ide_drive_t *, const u8);
+ 	/* routine to program host for DMA mode */
+@@ -701,19 +519,17 @@ typedef struct hwif_s {
  	void	(*pre_reset)(ide_drive_t *);
  	/* routine to reset controller after a disk reset */
  	void	(*resetproc)(ide_drive_t *);
@@ -855807,10 +862952,11 @@
  	u8 (*udma_filter)(ide_drive_t *);
  
 -	void (*fixup)(struct hwif_s *);
--
++	u8 (*cable_detect)(struct hwif_s *);
+ 
  	void (*ata_input_data)(ide_drive_t *, void *, u32);
  	void (*ata_output_data)(ide_drive_t *, void *, u32);
- 
+@@ -721,16 +537,13 @@ typedef struct hwif_s {
  	void (*atapi_input_bytes)(ide_drive_t *, void *, u32);
  	void (*atapi_output_bytes)(ide_drive_t *, void *, u32);
  
@@ -855828,7 +862974,7 @@
  	void (*dma_lost_irq)(ide_drive_t *drive);
  	void (*dma_timeout)(ide_drive_t *drive);
  
-@@ -766,7 +583,6 @@ typedef struct hwif_s {
+@@ -766,7 +579,6 @@ typedef struct hwif_s {
  	int		rqsize;		/* max sectors per request */
  	int		irq;		/* our irq number */
  
@@ -855836,7 +862982,19 @@
  	unsigned long	dma_base;	/* base addr for dma ports */
  	unsigned long	dma_command;	/* dma command register */
  	unsigned long	dma_vendor1;	/* dma vendor 1 register */
-@@ -806,15 +622,13 @@ typedef struct hwif_s {
+@@ -786,10 +598,9 @@ typedef struct hwif_s {
+ 	unsigned	serialized : 1;	/* serialized all channel operation */
+ 	unsigned	sharing_irq: 1;	/* 1 = sharing irq with another hwif */
+ 	unsigned	reset      : 1;	/* reset after probe */
+-	unsigned	auto_poll  : 1; /* supports nop auto-poll */
+ 	unsigned	sg_mapped  : 1;	/* sg_table and sg_nents are ready */
+-	unsigned	no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */
+ 	unsigned	mmio       : 1; /* host uses MMIO */
++	unsigned	straight8  : 1;	/* Alan's straight 8 check */
+ 
+ 	struct device	gendev;
+ 	struct completion gendev_rel_comp; /* To deal with device release() */
+@@ -806,15 +617,16 @@ typedef struct hwif_s {
  /*
   *  internal ide interrupt handler type
   */
@@ -855844,6 +863002,9 @@
  typedef ide_startstop_t (ide_handler_t)(ide_drive_t *);
  typedef int (ide_expiry_t)(ide_drive_t *);
  
++/* used by ide-cd, ide-floppy, etc. */
++typedef void (xfer_func_t)(ide_drive_t *, void *, u32);
++
  typedef struct hwgroup_s {
  		/* irq handler, if active */
  	ide_startstop_t	(*handler)(ide_drive_t *);
@@ -855853,7 +863014,7 @@
  		/* BOOL: protects all fields below */
  	volatile int busy;
  		/* BOOL: wake us up on timer expiry */
-@@ -829,25 +643,18 @@ typedef struct hwgroup_s {
+@@ -829,25 +641,18 @@ typedef struct hwgroup_s {
  		/* ptr to current hwif in linked-list */
  	ide_hwif_t *hwif;
  
@@ -855881,6 +863042,22 @@
  } ide_hwgroup_t;
  
  typedef struct ide_driver_s ide_driver_t;
+@@ -901,6 +706,7 @@ typedef struct {
+ void proc_ide_create(void);
+ void proc_ide_destroy(void);
+ void ide_proc_register_port(ide_hwif_t *);
++void ide_proc_port_register_devices(ide_hwif_t *);
+ void ide_proc_unregister_port(ide_hwif_t *);
+ void ide_proc_register_driver(ide_drive_t *, ide_driver_t *);
+ void ide_proc_unregister_driver(ide_drive_t *, ide_driver_t *);
+@@ -933,6 +739,7 @@ void ide_pci_create_host_proc(const char *, get_info_t *);
+ static inline void proc_ide_create(void) { ; }
+ static inline void proc_ide_destroy(void) { ; }
+ static inline void ide_proc_register_port(ide_hwif_t *hwif) { ; }
++static inline void ide_proc_port_register_devices(ide_hwif_t *hwif) { ; }
+ static inline void ide_proc_unregister_port(ide_hwif_t *hwif) { ; }
+ static inline void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) { ; }
+ static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { ; }
 @@ -1020,7 +827,8 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
  
  extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry);
@@ -856054,7 +863231,18 @@
  
  int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long);
  int ide_cmd_ioctl(ide_drive_t *, unsigned int, unsigned long);
-@@ -1133,10 +1005,8 @@ extern void do_ide_request(struct request_queue *);
+@@ -1116,10 +988,8 @@ int ide_task_ioctl(ide_drive_t *, unsigned int, unsigned long);
+ extern int system_bus_clock(void);
+ 
+ extern int ide_driveid_update(ide_drive_t *);
+-extern int ide_ata66_check(ide_drive_t *, ide_task_t *);
+ extern int ide_config_drive_speed(ide_drive_t *, u8);
+ extern u8 eighty_ninty_three (ide_drive_t *);
+-extern int set_transfer(ide_drive_t *, ide_task_t *);
+ extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);
+ 
+ extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout);
+@@ -1133,10 +1003,8 @@ extern void do_ide_request(struct request_queue *);
  
  void ide_init_disk(struct gendisk *, ide_drive_t *);
  
@@ -856066,7 +863254,42 @@
  extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name);
  #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME)
  #else
-@@ -1212,6 +1082,13 @@ enum {
+@@ -1146,6 +1014,13 @@ extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *o
+ void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *);
+ void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *);
+ 
++#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
++void ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *);
++#else
++static inline void ide_hwif_setup_dma(ide_hwif_t *hwif,
++				      const struct ide_port_info *d) { }
++#endif
++
+ extern void default_hwif_iops(ide_hwif_t *);
+ extern void default_hwif_mmiops(ide_hwif_t *);
+ extern void default_hwif_transport(ide_hwif_t *);
+@@ -1182,7 +1057,7 @@ enum {
+ 	IDE_HFLAG_NO_SET_MODE		= (1 << 9),
+ 	/* trust BIOS for programming chipset/device for DMA */
+ 	IDE_HFLAG_TRUST_BIOS_FOR_DMA	= (1 << 10),
+-	/* host uses VDMA */
++	/* host uses VDMA (tied with IDE_HFLAG_CS5520 for now) */
+ 	IDE_HFLAG_VDMA			= (1 << 11),
+ 	/* ATAPI DMA is unsupported */
+ 	IDE_HFLAG_NO_ATAPI_DMA		= (1 << 12),
+@@ -1192,8 +1067,10 @@ enum {
+ 	IDE_HFLAG_NO_DMA		= (1 << 14),
+ 	/* check if host is PCI IDE device before allowing DMA */
+ 	IDE_HFLAG_NO_AUTODMA		= (1 << 15),
++	/* don't autotune PIO */
++	IDE_HFLAG_NO_AUTOTUNE		= (1 << 16),
+ 	/* host is CS5510/CS5520 */
+-	IDE_HFLAG_CS5520		= (1 << 16),
++	IDE_HFLAG_CS5520		= IDE_HFLAG_VDMA,
+ 	/* no LBA48 */
+ 	IDE_HFLAG_NO_LBA48		= (1 << 17),
+ 	/* no LBA48 DMA */
+@@ -1212,6 +1089,17 @@ enum {
  	IDE_HFLAG_IO_32BIT		= (1 << 24),
  	/* unmask IRQs */
  	IDE_HFLAG_UNMASK_IRQS		= (1 << 25),
@@ -856077,10 +863300,14 @@
 +	IDE_HFLAG_CLEAR_SIMPLEX		= (1 << 28),
 +	/* DSC overlap is unsupported */
 +	IDE_HFLAG_NO_DSC		= (1 << 29),
++	/* never use 32-bit I/O ops */
++	IDE_HFLAG_NO_IO_32BIT		= (1 << 30),
++	/* never unmask IRQs */
++	IDE_HFLAG_NO_UNMASK_IRQS	= (1 << 31),
  };
  
  #ifdef CONFIG_BLK_DEV_OFFBOARD
-@@ -1226,10 +1103,9 @@ struct ide_port_info {
+@@ -1226,10 +1114,9 @@ struct ide_port_info {
  	void			(*init_iops)(ide_hwif_t *);
  	void                    (*init_hwif)(ide_hwif_t *);
  	void			(*init_dma)(ide_hwif_t *, unsigned long);
@@ -856092,7 +863319,7 @@
  	u32			host_flags;
  	u8			pio_mask;
  	u8			swdma_mask;
-@@ -1264,21 +1140,21 @@ static inline u8 ide_max_dma_mode(ide_drive_t *drive)
+@@ -1264,21 +1151,22 @@ static inline u8 ide_max_dma_mode(ide_drive_t *drive)
  	return ide_find_dma_mode(drive, XFER_UDMA_6);
  }
  
@@ -856100,6 +863327,7 @@
  void ide_dma_off(ide_drive_t *);
 +void ide_dma_on(ide_drive_t *);
  int ide_set_dma(ide_drive_t *);
++void ide_check_dma_crc(ide_drive_t *);
  ide_startstop_t ide_dma_intr(ide_drive_t *);
  
 +int ide_build_sglist(ide_drive_t *, struct request *);
@@ -856121,7 +863349,7 @@
  extern int ide_dma_setup(ide_drive_t *);
  extern void ide_dma_start(ide_drive_t *);
  extern int __ide_dma_end(ide_drive_t *);
-@@ -1290,7 +1166,9 @@ extern void ide_dma_timeout(ide_drive_t *);
+@@ -1290,9 +1178,12 @@ extern void ide_dma_timeout(ide_drive_t *);
  static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; }
  static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
  static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
@@ -856130,27 +863358,44 @@
 +static inline void ide_dma_on(ide_drive_t *drive) { ; }
  static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
  static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
++static inline void ide_check_dma_crc(ide_drive_t *drive) { ; }
  #endif /* CONFIG_BLK_DEV_IDEDMA */
-@@ -1313,6 +1191,7 @@ static inline void ide_acpi_init(ide_hwif_t *hwif) { ; }
+ 
+ #ifndef CONFIG_BLK_DEV_IDEDMA_PCI
+@@ -1304,25 +1195,29 @@ extern int ide_acpi_exec_tfs(ide_drive_t *drive);
+ extern void ide_acpi_get_timing(ide_hwif_t *hwif);
+ extern void ide_acpi_push_timing(ide_hwif_t *hwif);
+ extern void ide_acpi_init(ide_hwif_t *hwif);
++void ide_acpi_port_init_devices(ide_hwif_t *);
+ extern void ide_acpi_set_state(ide_hwif_t *hwif, int on);
+ #else
+ static inline int ide_acpi_exec_tfs(ide_drive_t *drive) { return 0; }
+ static inline void ide_acpi_get_timing(ide_hwif_t *hwif) { ; }
+ static inline void ide_acpi_push_timing(ide_hwif_t *hwif) { ; }
+ static inline void ide_acpi_init(ide_hwif_t *hwif) { ; }
++static inline void ide_acpi_port_init_devices(ide_hwif_t *hwif) { ; }
  static inline void ide_acpi_set_state(ide_hwif_t *hwif, int on) {}
  #endif
  
 +void ide_remove_port_from_hwgroup(ide_hwif_t *);
  extern int ide_hwif_request_regions(ide_hwif_t *hwif);
  extern void ide_hwif_release_regions(ide_hwif_t* hwif);
- extern void ide_unregister (unsigned int index);
-@@ -1320,8 +1199,9 @@ extern void ide_unregister (unsigned int index);
+-extern void ide_unregister (unsigned int index);
++void ide_unregister(unsigned int, int, int);
+ 
  void ide_register_region(struct gendisk *);
  void ide_unregister_region(struct gendisk *);
  
 -void ide_undecoded_slave(ide_hwif_t *);
 +void ide_undecoded_slave(ide_drive_t *);
  
-+int ide_device_add_all(u8 *idx);
- int ide_device_add(u8 idx[4]);
+-int ide_device_add(u8 idx[4]);
++int ide_device_add_all(u8 *idx, const struct ide_port_info *);
++int ide_device_add(u8 idx[4], const struct ide_port_info *);
  
  static inline void *ide_get_hwifdata (ide_hwif_t * hwif)
-@@ -1356,6 +1236,7 @@ static inline int ide_dev_is_sata(struct hd_driveid *id)
+ {
+@@ -1356,6 +1251,7 @@ static inline int ide_dev_is_sata(struct hd_driveid *id)
  	return 0;
  }
  
@@ -856158,7 +863403,7 @@
  u8 ide_dump_status(ide_drive_t *, const char *, u8);
  
  typedef struct ide_pio_timings_s {
-@@ -1405,9 +1286,14 @@ extern struct bus_type ide_bus_type;
+@@ -1405,9 +1301,14 @@ extern struct bus_type ide_bus_type;
  #define ide_id_has_flush_cache_ext(id)	\
  	(((id)->cfs_enable_2 & 0x2400) == 0x2400)
  
@@ -856174,7 +863419,7 @@
  	return dev ? pcibus_to_node(dev->bus) : -1;
  }
  
-@@ -1418,4 +1304,9 @@ static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive)
+@@ -1418,4 +1319,9 @@ static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive)
  	return &hwif->drives[(drive->dn ^ 1) & 1];
  }
  
@@ -896384,7 +903629,7 @@
  
  config VIRT_TO_BUS
 diff --git a/mm/filemap.c b/mm/filemap.c
-index f4d0cde..89ce6fe 100644
+index f4d0cde..76bea88 100644
 --- a/mm/filemap.c
 +++ b/mm/filemap.c
 @@ -185,6 +185,12 @@ static int sync_page(void *word)
@@ -896454,6 +903699,35 @@
  readpage_error:
  		/* UHHUH! A synchronous read error occurred. Report it */
  		desc->error = error;
+@@ -1733,7 +1750,11 @@ static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes)
+ 		const struct iovec *iov = i->iov;
+ 		size_t base = i->iov_offset;
+ 
+-		while (bytes) {
++		/*
++		 * The !iov->iov_len check ensures we skip over unlikely
++		 * zero-length segments.
++		 */
++		while (bytes || !iov->iov_len) {
+ 			int copy = min(bytes, iov->iov_len - base);
+ 
+ 			bytes -= copy;
+@@ -2251,6 +2272,7 @@ again:
+ 
+ 		cond_resched();
+ 
++		iov_iter_advance(i, copied);
+ 		if (unlikely(copied == 0)) {
+ 			/*
+ 			 * If we were unable to copy any data at all, we must
+@@ -2264,7 +2286,6 @@ again:
+ 						iov_iter_single_seg_count(i));
+ 			goto again;
+ 		}
+-		iov_iter_advance(i, copied);
+ 		pos += copied;
+ 		written += copied;
+ 
 diff --git a/mm/memory.c b/mm/memory.c
 index 4b0144b..d902d0e 100644
 --- a/mm/memory.c

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	(original)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	Sun Feb  3 21:56:41 2008
@@ -1,4 +1,4 @@
-+ bugfix/all/patch-2.6.24-git12
++ bugfix/all/patch-2.6.24-git13
 + debian/version.patch
 + debian/kernelvariables.patch
 + debian/doc-build-parallel.patch



More information about the Kernel-svn-changes mailing list