linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Linux 2.5.7
@ 2002-03-18 20:47 Linus Torvalds
  2002-03-18 21:57 ` Xavier Bestel
                   ` (17 more replies)
  0 siblings, 18 replies; 39+ messages in thread
From: Linus Torvalds @ 2002-03-18 20:47 UTC (permalink / raw)
  To: Kernel Mailing List


Ok, there's a 2.5.7 out there now, full changelog appended.

NOTE! I'll be gone for a vacation for two weeks, and will not be reading 
email during the time. So please discuss problems on linux-kernel, with 
Dave Jones, Jeff Garzik etc handling patches while I'm away. 

			Linus

-----

	Release notes for v2.5.7



Summary of changes from v2.5.7-pre2 to v2.5.7
============================================

<kai@vaio.(none)> (02/02/10 1.248.8.1)
	Remove duplicate CONFIG_SOUND help entries and put one 
	into drivers/sound/Config.help

<kai@tp1.ruhr-uni-bochum.de> (02/03/16 1.522.1.1)
	Link drivers/fc4/fc4.a only once.

<kai@tp1.ruhr-uni-bochum.de> (02/03/16 1.522.1.2)
	Descend into drivers/parport only if CONFIG_PARPORT is set.

<kai@tp1.ruhr-uni-bochum.de> (02/03/16 1.522.1.3)
	Descend into drivers/hotplug only if CONFIG_HOTPLUG_PCI is set.

<torvalds@home.transmeta.com> (02/03/16 1.522.2.1)
	Fix up ACPI so that it seems to work in the new world order:
	make driverfs initialize early, so that ACPI can come alive
	in a world where you can register devices. 

<dwmw2@infradead.org> (02/03/17 1.525)
	Remove jffs2_sb from struct super_block union.
	Remove FS_REQUIRES_DEV from JFFS2. We never really used the block device anyway.

<paschal@rcsis.com> (02/03/17 1.524.1.1)
	USB printer update
	
	- bind to 7/1/2 alternate setting by default, to fix printing with HP
	  LaserJet 1200 and 2200
	- ioctls needed by the GPL user-mode IEEE 1284.4 driver which is part of
	  the HP OfficeJet Linux driver (http://hpoj.sourceforge.net):
	  - dynamic switching between 7/1/[123] alternate settings
	  - sending HP vendor-specific channel-change-request to support
	    memory card readers on HP PhotoSmart printers
	  - inquire more information about the peripheral, including
	    /proc/bus/usb/xx/yy linkage to get even more information
	- fix apparent array overflow (by 1 entry) in usblp_probe when more than
	  the maximum number of USB printers are connected
	- for the 2.2 version, added MODULE_{INC,DEC}_USE_COUNT to prevent rmmoding
	  of printer.o (and subsequent OOPSes) while a USB printer device is open
	- cleaned up the code in a few places by consolidating duplicated code

<stewart@inverse.wetlogic.net> (02/03/17 1.524.1.2)
	USB Urefs for hid-core/hiddev
	
	  I've written a patch Vojtech and I discussed for enhancing the
	hiddev code to optionally provide more detailed output on read().
	The old functionality is still supported by default, and in
	situations where HID usage codes are unique across reports, the
	old method is still preferable due to its terseness.
	    
	  The new method provides the ability to determine exactly which
	value has changed, in cases where the HID usage codes are not  
	unique.  It also provides a means to optionally receive notification
	when input reports are received from the device, whether or not
	any of the values in the report have changed.
	
	  The details of the changes are as follows:
	  
	  - All current code behaves identically
	
	  - A new ioctl pair HIDIOCGFLAG/HIDIOCSFLAG gets and clears
	    flags on the hiddev device.                             
	
	  - If you set the flag HIDDEV_FLAG_UREF, the read() call switches
	    from reading hiddev_event structures to hiddev_usage_ref
	    structures.  The change takes effect immediately, even to
	    already queued events that haven't been read() yet.  Here's
	    an example of enabling FLAG_UREF:                          
	
	    {
	        int flag = HIDDEV_FLAG_UREF;
	        if (ioctl(fd, HIDIOCSFLAG, &flag) != 0) {
	                perror("ioctl");
	                exit(1);
	        }
	    }
	  
	  - With the HIDDEV_FLAG_REPORT set (which is only allowed if
	    HIDDEV_FLAG_UREF is also set), there is a special uref that
	    will be read() in addition to the ones corresponding to
	    changes in the device state: when uref.field_index is set to
	    HID_FIELD_INDEX_NONE, this uref is a notification that the
	    report referred to by report_type and report_id has been
	    received from the device.  This can be useful in situations
	    when the notification of the arrival of a report is useful
	    even if there is no change in state.

<spse@secret.org.uk> (02/03/17 1.524.1.3)
	USB catc driver
	  
	Here is a patch to add support for F5U011 to catc.c driver. The
	patch has been compile tested against 2.5.6 and 2.5.7pre1
	(and tested against 2.5.5-dj1) and should apply cleanly.

<ganesh@tuxtop.vxindia.veritas.com> (02/03/17 1.524.1.4)
	USB serial drivers
	
	Several functions in the serial drivers can be called from bottom
	half or interrupt context. They must use the GFP_ATOMIC flag for
	calls to kmalloc() and usb_submit_urb().
	  
	Functions which must use GFP_ATOMIC:
	1. All *_callback() functions.
	2. Any code which is inside a spinlock.
	3. write(), throttle(), unthrottle(), which may be called by
	   the line discipline in bottom half context.
	  
	Functions which can use GFP_KERNEL:
	1. open(), close(), startup(), shutdown(), set_termios().

<vojtech@suse.cz> (02/03/17 1.524.1.5)
	USB HID driver
	  
	Workaround for the ATEN switches

<tai@imasy.or.jp> (02/03/17 1.524.1.6)
	USB printer patch
	
	added NEC printer to quirks list

<dwmw2@infradead.org> (02/03/17 1.526)
	Switch cramfs and zisofs from zlib_fs to common zlib.
	Remove remnants of zlib_fs.

<davem@nuts.ninka.net> (02/03/17 1.384.4.15)
	Fix netfilter IPv4 conntrack build.

<davem@nuts.ninka.net> (02/03/17 1.384.4.16)
	Make wanpipe build again after struct sock cleanups.
	From Arnaldo Carvalho de Melo.

<paulus@samba.org> (02/03/18 1.524.2.1)
	PPC update - add preempt_count to the ppc thread_info, add
	SI_DETHREAD, plus a couple of minor fixes.

<paulus@samba.org> (02/03/18 1.524.2.2)
	Fix a lockup on some PPC machines running an SMP kernel - we were
	exiting heathrow_modem_enable() with a lock held.

<david-b@pacbell.net> (02/03/18 1.524.2.4)
	[PATCH] PATCH -- pci_pool and CONFIG_DEBUG_SLAB
	
	I got burnt one too many time by mismatches between
	the pci_pool and "real" slabs... something changed in
	mm/slab.c and broke a driver, so I'm going for the real
	fix this time.  Having poisoning that _works_ is a huge
	help in the innards of the USB host controller drivers.
	
	This patch gets rid of some #ifdefs and makes the pci_pool
	code poison memory if CONFIG_DEBUG_SLAB is set.
	The functionality has always been there, but this makes
	it simpler to get at.

<bgerst@didntduck.org> (02/03/18 1.524.2.5)
	[PATCH] struct super_block cleanup - isofs
	
	Seperates isofs_sb_info from struct super_block.

<bgerst@didntduck.org> (02/03/18 1.524.2.6)
	[PATCH] struct super_block cleanup - udf
	
	Seperates udf_sb_info from struct super_block.

<viro@math.psu.edu> (02/03/18 1.525.1.3)
	[PATCH] moving stuff to fs/filesystems.c
	
		file_system_typer-related code moved from fs/super.c to
	fs/filesystems.c

<bgerst@didntduck.org> (02/03/18 1.528)
	[PATCH] struct super_block cleanup - shmem
	
	Seperates shmem_sb_info from struct super_block.

<bgerst@didntduck.org> (02/03/18 1.529)
	[PATCH] struct super_block cleanup - hfs
	
	Seperates hfs_sb_info from struct super_block.

<bgerst@didntduck.org> (02/03/18 1.530)
	[PATCH] struct super_block cleanup - affs
	
	Seperates affs_sb_info from struct super_block.

<pazke@orbita1.ru> (02/03/18 1.531)
	[PATCH] driverfs support for ISAPNP driver
	
	This adds initial driverfs support to ISAPNP driver.  It was approved by
	the ISAPNP maintainer (Jaroslav Kysela).

<perex@suse.cz> (02/03/18 1.532)
	[PATCH] for 2.5.7pre2
	
	- add joystick support for CS46xx driver
	- Audigy code updates
	- fix sound/core/Config.in (wrong dep_tristate usage)
	- rawmidi interface fixes (memory leak)
	- chang spinlock to rwlock in pcm_native.c (streams linking)
	- further fixes of dependencies in Makefiles
	- remove experimental time-sync support from sequencer
	- fix/update for 32-bit -> 64-bit ioctl converter code
	- wavefront driver cleanups
	- CMIPCI driver updates
	- update joystick support in CS4281
	- add detection (not support) of M Audio Delta1010LT
	- add AMD768 PCI ID to intel8x0 driver
	- add joystick code to trident driver
	- remove static variable initialization to zero

<dalecki@evision-ventures.com> (02/03/18 1.533)
	[PATCH] 2.5.7-pre2 IDE 22a
	
	- Apply more patches from Vojtech Pavlik for the handling of host chip setup.
	   Hopefully they are settled now.
	
	- Kill unused CONFIG_BLK_DEV_MODES
	
	- Push register addressing down in to task_vlb_sync.
	
	- Make the taskfile parsing stuff actually readable. This is compressing the
	   code by an incredible amount. We use just one function doing the whole
	   scanning right now. This should make sure that the IRQ handler used by a
	   particular command is always right.  I didn't introduce typos hopefully
	   here.
	
	- Don't call ide_handler_parser as argument for do_taskfile() any longer. We
	   have killed this function by coalescing it's functionality with
	   ide_cmd_type_parser() anyway.
	
	- Kill unused SLC90E66 code, which Vojtech apparently missed in his patch.
	
	- sync up with 2.5.7-pre2
	
	Once again the actual patch is rather big mostly due to the removal of
	some default configuration variables which are not used anylonger. So time for
	the next patch stage.

<hirofumi@mail.parknet.co.jp> (02/03/18 1.534)
	[PATCH] Fix linux/msdos_fs.h for userland (1/2)
	
	The following patch moves MSDOS_SB() and MSDOS_I() into #define
	__KERNEL__.

<hirofumi@mail.parknet.co.jp> (02/03/18 1.535)
	[PATCH] cleanup FAT stuff (2/2)
	
	This patch remove unused variable/function/define, and small indent
	cleanup.

<torvalds@home.transmeta.com> (02/03/18 1.536)
	Include <linux/completion.h> for completion user

<torvalds@home.transmeta.com> (02/03/18 1.537)
	Update version


Summary of changes from v2.5.7-pre1 to v2.5.7-pre2
============================================

<anton@samba.org> (02/03/11 1.384.3.1)
	pcnet32 net driver updates 1/6:
	fix leak in pci memory space on machines with IOMMUs.

<anton@samba.org> (02/03/11 1.384.3.2)
	pcnet32 net driver updates 2/6:
	irq could overflow unsigned char, change to unsigned int
	ioaddr could overflow unsigned int, change to unsigned long

<anton@samba.org> (02/03/11 1.384.3.3)
	pcnet32 net driver updates 3/6:
	protect pcnet32_tx_timeout and pcnet32_set_multicast_list with
	spinlock, fix from Dave Engebretsen

<anton@samba.org> (02/03/11 1.384.3.4)
	pcnet32 net driver updates 4/6:
	Increase device watchdog timeout, fix from Dave Engebretsen.

<anton@samba.org> (02/03/11 1.384.3.5)
	pcnet32 net driver updates 5/6:
	pcnet32_purge_tx_ring can be called from interrupt, so must use
	dev_kfree_skb_any, fix from Dave Engebretsen.

<anton@samba.org> (02/03/11 1.384.3.6)
	pcnet32 net driver updates 6/6:
	perform dwio reset after checking wio, otherwise some cards fail
	the probe, fix from Paul Mackerras

<kai@tp1.ruhr-uni-bochum.de> (02/03/11 1.384.9.1)
	Make USB core init an subsys_initcall, like the other buses.
	
	As it's linked after PCI, usb_init() will be called after pci_init(),
	which is an subsys_initcall, too. Subtle, but right.

<peter@chubb.wattle.id.au> (02/03/11 1.375.25.4)
	[PATCH] HP Sim config patch
	
	Offer loopback driver and network block device support for HP Sim.

<davidm@wailua.hpl.hp.com> (02/03/11 1.375.25.5)
	siginfo.h:
	  Define SI_DETHREAD.

<davidm@wailua.hpl.hp.com> (02/03/11 1.375.25.6)
	smp.c:
	  Remove task-migration IPI.   It's been replaced
	  by Ingo's migration threads.

<davidm@wailua.hpl.hp.com> (02/03/11 1.375.25.7)
	Sync with Linus' v2.5.6 tree.

<davidm@hpl.hp.com> (02/03/12 1.388.1.18)
	[PATCH] Compile fix for kernel/sched.c
	
	Fix init_idle() to initialize preempt_count only if CONFIG_PREEMPT is set.

<jgarzik@mandrakesoft.com> (02/03/12 1.384.10.1)
	e100 net driver updates from Intel:
	* fix zerocopy
	* add suspend/resume

<jgarzik@mandrakesoft.com> (02/03/12 1.384.10.2)
	e100 net driver cleanups from Arjan van de Ven:
	* fix PCI posting bugs
	* remove ia64-specific code, requires an arch workaround/fix instead
	* other misc cleanups and small bug fixes

<arjan@redhat.com> (02/03/12 1.388.2.2)
	Increase eepro100 net driver tx/rx ring sizes, to be more appropriate for 100mbit.

<arjan@redhat.com> (02/03/12 1.388.2.3)
	Add eepro100 rx soft reset function, for handling RX edge cases the driver
	currently does not handle well, if at all.
	
	Author: Steve Parker @ Sun

<arjan@redhat.com> (02/03/12 1.388.2.4)
	Update eepro100 net driver to issue soft rx reset for certain cases, fixing several
	reports of hangs or lockups (of the NIC, not the entire system).
	
	Author: Steve Parker @ Sun

<arjan@redhat.com> (02/03/12 1.388.2.5)
	Update eepro100 net driver to enable/disable its software timer
	at suspend/resume time.

<arjan@redhat.com> (02/03/12 1.388.2.6)
	eepro100 net driver bug fixes:
	* fix chip id test
	* add udelay(1) to "make [the workaround] stick"

<arjan@redhat.com> (02/03/12 1.388.2.7)
	Move pci_enable_device and associated code above first PCI resource info access.

<jgarzik@mandrakesoft.com> (02/03/12 1.388.2.8)
	Build fix: include linux/crc32.h in bmac net driver.
	
	Noticed by Joshua Uziel.

<torvalds@penguin.transmeta.com> (02/03/12 1.420)
	Update defconfig for VLAN and IDE changes

<trond.myklebust@fys.uio.no> (02/03/12 1.421)
	[PATCH] 2.5.6 Fix RPC credentials when coalescing NFS reads/writes...
	
	  The following fixes up a couple of bugs that resulted from the fix
	in 2.5.4 for ETXTBSY: Since the READ requests now only store RPC
	credentials and not the struct file, we need to be careful when
	deciding to coalesce requests on different pages into 1 RPC call that
	we compare the credentials instead of the struct file.

<trond.myklebust@fys.uio.no> (02/03/12 1.422)
	[PATCH] 2.5.6 Fix NFS file creation
	
	  The following patch fixes a bug in NFS file creation. Recently (not
	sure exactly when), open_namei() was changed so that it expects
	vfs_create() to always return a fully instantiated dentry for the new
	file.
	
	The following patch ensures this is done in the cases where the RPC
	CREATE call does not return valid attributes/filehandles. This is
	always the case for NFSv2, and can sometimes be the case for v3...

<trond.myklebust@fys.uio.no> (02/03/12 1.423)
	[PATCH] 2.5.6 correct NFS client handling of EJUKEBOX error...
	
	  The following patch resyncs 2.5.6 with the 2.4.x series w.r.t. the
	handling of the EJUKEBOX error. The latter is an NFS-specific error
	that is returned by servers that support hierarchical storage: it
	notifies the client that the request cannot be completed in a timely
	fashion (Imagine for instance a situation where you have a cdrom
	jukebox system, and the user has just requested a file on another cd).
	
	Under these circumstances, the RFC specifies that the request should
	be retried after suitable timeout during which the server will attempt
	to perform whatever action is required to make the file available
	again.

<jgarzik@mandrakesoft.com> (02/03/12 1.388.2.9)
	tg3 gige net driver update:
	* Merge several bug fixes from vger cvs
	* Merge h/w VLAN support, now that API is in the main tree
	* Add support for TX/RX coalescing

<jgarzik@mandrakesoft.com> (02/03/12 1.388.2.10)
	8139cp net driver updates:
	* Merge support for hardware vlan accel
	* Better wakeup behavior on TX completion
	* dev->mtu setting fixes

<jgarzik@mandrakesoft.com> (02/03/12 1.388.2.11)
	Add several new ethtool commands:
	coalescing, ring params, pause params, hw csum disable/enable,
	scatter-gather enable/disable

<bgerst@didntduck.org> (02/03/12 1.424)
	[PATCH] struct super_block cleanup - ncpfs
	
	Seperates ncp_sb_info from struct super_block.

<bgerst@didntduck.org> (02/03/12 1.425)
	[PATCH] struct super_block cleanup - ext2
	
	Abstract access to ext2_sb_info.

<bgerst@didntduck.org> (02/03/12 1.426)
	[PATCH] struct super_block cleanup - ext2
	
	Complete the ext2 superblock seperation.

<bgerst@didntduck.org> (02/03/12 1.427)
	[PATCH] correction to super_block cleanups
	
	I forgot to zero out the newly allocated memory in the previous patches
	for cramfs and minixfs.

<bgerst@didntduck.org> (02/03/12 1.428)
	[PATCH] correction to super_block cleanups
	
	I forgot to zero out the newly allocated memory in the previous patches
	for ext2 and ncpfs.

<viro@math.psu.edu> (02/03/12 1.429)
	[PATCH] (1/4) smarter nfs_get_sb()
	
	Switch NFS to use of NFS_SB(sb) instead of sb->u.nfs_sb.s_server

<viro@math.psu.edu> (02/03/12 1.430)
	[PATCH] (2/4) smarter nfs_get_sb()
	
	Export sget(9), deactivate_super(9) and set_anon_sb(9)

<viro@math.psu.edu> (02/03/12 1.431)
	[PATCH] (3/4) smarter nfs_get_sb()
	
	Switch NFS to separate allocation of private part of superblock,
	uss explicit sget() instead of get_sb_nodev()

<viro@math.psu.edu> (02/03/12 1.432)
	[PATCH] (4/4) smarter nfs_get_sb()
	
	Add nfs_compare_super() and teaches nfs_get_sb() to look for existing
	superblocks.

<viro@math.psu.edu> (02/03/12 1.433)
	[PATCH] removal of ->u.romfs_i
	

<bgerst@didntduck.org> (02/03/12 1.434)
	[PATCH] struct super_block cleanup - efs
	
	Separates efs_sb_info from struct super_block.

<jgarzik@mandrakesoft.com> (02/03/12 1.415.2.1)
	Make pdev_set_mwi static, at the request of David Miller.

<jgarzik@mandrakesoft.com> (02/03/13 1.415.1.2)
	Fix e100 net driver typo, from last change.
	
	Contributor: Eli Kupermann @ Intel

<dalecki@evision-ventures.com> (02/03/13 1.435)
	[PATCH] IDE 21
	
	If I was to give this patch a name it would be:
	
	"Vojtech Pavlik unleashed from the chains".
	
	So credit where credit is due :-).
	
	Anyway here follows the change log:
	
	Mon Mar 11 23:48:28 CET 2002 ide-clean-21
	
	- Swallow rewritten amd74xx host chip setup code from Vojtech Pavlik.  We can
	   revert it easly if it turns out to be a bad thing. However the code looks
	   quite sane to me. In esp. it doesn't containg that many magic numbers.
	
	- Clean stale white spaces in ide-timing.h tirvial fix.
	
	- Make ide_release_dma return void. It's value is never used anyway.
	
	- Swallow more timing setup code cleanup by Vojtech Pavlik. Apply some
	   cosmetics to it. Port opti621 to the new setup code.
	
	- Kill abuse of ide_do_reset() on error return paths for atapi floppy tape and
	   cd-rom devices. Just stop them. This gives better changes that defect
	   removable media will not cause suddenly broken timings on hard discs
	   containing system data! Even then comments in ide_do_reset() admit, that
	   resetting the whole channel can have adverse effects on the second interface
	   on this channel. And I have too frequently observed linux struggling on
	   defect cd-rom for a far too long time to wish it to continue.
	
	   Oh did I forget to say that the corresponding "how can I break my system fast
	   and reliable" ioctl is gone as well?
	
	   Removing it recovered the fact that the CONFIG_BLK_DEV_IDEDMA_TIMEOUT is
	   completely bogous. I have removed this option therefore as well, because it's
	   playing the same wrack havoc on the devices if enabled. This cat has been in
	   an unfinished and *unfunctional* state anyway.
	
	- Actually add physical suspend code to the power handling code.  Still the
	   resume code isn't finished just jet. This is all subject to change at the
	   point in time when we get to proper command queueing.
	   I think however that Pavel will be interrested in tidding this bit up...
	
	- Resync with 2.5.7-pre1.

<vojtech@suse.cz> (02/03/13 1.436)
	[PATCH] Re: [PATCH] IDE 21
	
	In the FIT macro in ide-timing.h the argument got swapped because of a
	typo. All timings generated for VIA and AMD chips are wrong because of
	that. Safe, though, but slow.
	
	This fixes it.

<adam@yggdrasil.com> (02/03/13 1.439)
	[PATCH] Patch: linux-2.5.7-pre1/net/ipv4/ipmr.c did not compile
	
		It looks like sk->num became inet_sk(sk)->num in 2.5.7-pre1,
	but one of these changes was missed in net/ipv4/ipmr.c.  Here is
	the patch.

<pazke@orbita1.ru> (02/03/13 1.440)
	[PATCH] i82092 PCMCIA driver cleanup
	
	This contains some minor changes to i82092.c PCMCIA driver:
		- MODULE_DEVICE_TABLE() added;
		- request_region() and pci_enable_device() return value checks added;
		- some printk() cleanups.

<kraxel@bytesex.org> (02/03/13 1.441)
	[PATCH] v4l: miro radio update
	
	The updates for the radio driver are all very similar:  The individual
	open functions are gone and replaced by the video_exclusive_open/release
	functions in videodev.c.  All userspace copying in the ioctl function is
	gone because video_generic_ioctl handles this now.  The driver source
	files all become slightly shorter because of this.

<kraxel@bytesex.org> (02/03/13 1.442)
	[PATCH] v4l: usbvideo update
	
	This patch adapts the usbvideo module to the videodev changes.  As with
	all usb drivers, the unplug race fix is present here too.

<kraxel@bytesex.org> (02/03/13 1.443)
	[PATCH] v4l: maxiradio update
	
	This patch updates the Maxi FM2000 Radio driver.

<kraxel@bytesex.org> (02/03/13 1.444)
	[PATCH] v4l: maestro radio update
	
	This patch updates the maestro radio driver.

<kraxel@bytesex.org> (02/03/13 1.445)
	[PATCH] v4l: gemtek radio update
	
	This patch updates the gemtek and gemtek pci radio drivers.

<kraxel@bytesex.org> (02/03/13 1.446)
	[PATCH] v4l: cadet radio update
	
	This is the cadet radio driver update.

<kraxel@bytesex.org> (02/03/13 1.447)
	[PATCH] v4l: aimslab radio update
	
	Here comes the aimslab radio driver update.

<kraxel@bytesex.org> (02/03/13 1.448)
	[PATCH] v4l: aztech radio update
	
	Here comes the aztech radio driver update.

<kraxel@bytesex.org> (02/03/13 1.449)
	[PATCH] v4l: radiotrack driver update
	
	This patch updates the radiotrack driver.

<kraxel@bytesex.org> (02/03/13 1.450)
	[PATCH] v4l: sf16fm radio update
	
	This patch updates the sf16fm radio driver.

<kraxel@bytesex.org> (02/03/13 1.451)
	[PATCH] v4l: terratec radio update
	
	This is the update for the terratec radio driver.

<kraxel@bytesex.org> (02/03/13 1.452)
	[PATCH] v4l: typhoon radio update
	
	This is the update for the typhoon radio driver.

<kraxel@bytesex.org> (02/03/13 1.453)
	[PATCH] v4l: cpia parport/usb update
	
	This patch updates the cpia driver.
	
	Additionally to the usual adoptions to the videodev changes done in all
	drivers this patch has a few more changes:
	
	 - some cleanups in the drivers open() function.
	 - Use file->private_data to keep a pointer to the drivers private
	   data.  This allows to unregister the device unconditionally in
	   disconnect(), which in turn fixes some small races in case the
	   device is unplugged while in use.

<kraxel@bytesex.org> (02/03/13 1.454)
	[PATCH] v4l: stv usb camera update
	
	This patch adapts the stv usb camera driver to the videodev changes and
	fixes the unplug race.

<kraxel@bytesex.org> (02/03/13 1.455)
	[PATCH] v4l: ov511 usb cam update
	
	This patch adapts the ov511 driver to the videodev changes.  As Mark
	McClelland already sent in a patch with updates this just deletes the
	now obsolete code for the most part.  The unplug-while-in-use race fix
	is also there.

<kraxel@bytesex.org> (02/03/13 1.456)
	[PATCH] v4l: pwc webcam update
	
	This patch adapts the philips webcam driver to the videodev changes.
	Also has the unplug race fix.

<kraxel@bytesex.org> (02/03/13 1.457)
	[PATCH] v4l:
	
	This patch adapts the se401 driver to the videodev changes and fixes the
	unplug race.

<kraxel@bytesex.org> (02/03/13 1.458)
	[PATCH] v4l: quickcam update
	
	This patch updates the parallel port quickcam drivers (bw+color).

<kraxel@bytesex.org> (02/03/13 1.459)
	[PATCH] v4l: saa5249 videotext driver update
	
	This patch updates the saa5249 videotext driver.

<kraxel@bytesex.org> (02/03/13 1.460)
	[PATCH] v4l: vicam usb camera update
	
	This patch updates the vicam usb camera driver.  videodev adaptions are
	there, and the unplug race fix.  I also did plenty of other small
	cleanups and fixes, lots of forgotten breaks in the big ioctl switch for
	example.  I wouldn't be surprised if the driver didn't work at all ...

<kraxel@bytesex.org> (02/03/13 1.461)
	[PATCH] v4l: trust radio update
	
	This is the update for the trust radio driver.

<kraxel@bytesex.org> (02/03/13 1.462)
	[PATCH] v4l: DSB usb radio driver update
	
	This patch adapts the DSB usb radio driver to the videodev changes.

<kraxel@bytesex.org> (02/03/13 1.463)
	[PATCH] v4l: mediavision pms update
	
	This patch updates the mediavision pms video driver.

<kraxel@bytesex.org> (02/03/13 1.464)
	[PATCH] v4l: w9966 update
	
	This patch updates the Winbond w9966cf parport webcam driver.

<kraxel@suse.de> (02/03/13 1.465)
	[PATCH] snd: btaudio update
	
	This patch updates the btaudio sound driver.  It fixes a bug in the poll
	function, makes the driver a bit more verbose at insmod time, adds a
	insmod option for the pci latency timer and does some minor cleanups.

<kraxel@suse.de> (02/03/13 1.466)
	[PATCH] v4l: bttv i2c audio update
	
	This patch updates the i2c audio chip modules.  It improves the support
	for tda9874x chips.  There are some bugfixes.  It also has alot of small
	cleanups: switch some modules to new initialization, declare lots of
	functions static, ...  which make the patch a bit large.

<kraxel@bytesex.org> (02/03/13 1.467)
	[PATCH] v4l: new videobuf helper module
	
	This patch adds a helper module to manage pci dma buffers for video
	frames.  I've recently started writing a driver for another frame
	grabber / TV card chip and tried to separate out common code to avoid
	duplicating code.  The bttv core update (next mail) depends this patch.

<kraxel@suse.de> (02/03/13 1.468)
	[PATCH] v4l: bttv tuner update
	
	This patch is a update for the tuner module which controls the tuner
	chip on TV cards.  No major changes, lots of small cleanups: make
	functions static, switch to name-based initialization for structs, ...

<kraxel@bytesex.org> (02/03/13 1.469)
	[PATCH] v4l: bttv doc update
	
	This patch updates the documentation for the bttv driver.

<kraxel@bytesex.org> (02/03/13 1.470)
	[PATCH] v4l: major bttv update
	
	This is a major update of the bttv core (0.7.x to 0.8.x).  There are way
	too many changes to list them all, the complete core code for video
	frame capture has been rewritten from scratch.

<eranian@hpl.hp.com> (02/03/13 1.388.1.19)
	[PATCH] Fix ia64 perfmon for 2.5.6
	
	Fix up earlier perfmon breakage.

<petkan@users.sourceforge.net> (02/03/13 1.415.3.2)
	email address changes.

<greg@kroah.com> (02/03/13 1.415.3.3)
	USB pegasus driver
	
	Elcon vendor/device support added.

<greg@kroah.com> (02/03/13 1.415.3.4)
	USB edgeport driver
	
	Fixed bug that prevented multiple edgeport devices from working at once.

<davem@nuts.ninka.net> (02/03/13 1.384.4.11)
	SPX updates from Arnaldo Carvalho de Melo:
	- CodingStyle cleanups
	- Adds MODULE_LICENSE
	- Fix missing release_sock calls
	- Remove leftovers from sock cleanup patches
	- Use skb_queue_purge

<tapio@iptime.fi> (02/03/13 1.415.3.5)
	USB Emagic EMI 2I6 support to kernel
	  
	Here is patch against linuxusb.bkbits.net LINUX_2.4.19-pre2 export, which
	adds Emagic EMI 2|6 usb audio interface firmware loader support to linux
	kernel.
	I also have other kernel patches and emi26 cvs export available at:
	http://www.vtoy.fi/~tapio/emi26.html

<davem@nuts.ninka.net> (02/03/13 1.384.4.12)
	Fix IPv4 multicast router build failure caused
	by struct sock cleanups.

<ganesh@tuxtop.vxindia.veritas.com> (02/03/13 1.415.3.6)
	USB ipaq driver
	
	Fixed a panic caused by the line discipline echoing characters. It
	also fixes a problem where the echoing messes up ppp chat.

<davem@nuts.ninka.net> (02/03/13 1.384.7.15)
	Sparc64 updates:
	1) Fix EBUS register probing
	2) Add some missing ioctl32 translations
	3) Add sys_futex entries for sparc/sparc64
	4) Add platform-specific pcibios_set_mwi implementation
	   for sparc64
	5) Fix set_brkpkt implementation so it works on UltraSPARC-III

<bfennema@falcon.csc.calpoly.edu> (02/03/13 1.474)
	[PATCH] udf patch for 2.5.7-pre1 (part 1/4)
	
	This patch adds some missing byte swaps needed for big endian archs.

<bfennema@falcon.csc.calpoly.edu> (02/03/13 1.475)
	[PATCH] udf patch for 2.5.7-pre1 (part 2/4)
	
	This patch fixes writing the descriptor version for udf revisions >= 2.0

<bfennema@falcon.csc.calpoly.edu> (02/03/13 1.476)
	[PATCH] udf patch for 2.5.7-pre1 (part 3/4)
	
	This patch fixes an extent preallocation bug and adds missing sb_bread == NULL
	checks.

<bfennema@falcon.csc.calpoly.edu> (02/03/13 1.477)
	[PATCH] udf patch for 2.5.7-pre1 (part 4/4)
	
	This patch moves the udf spec header files into the fs/udf directory and
	removes all the non-standard sized typedefs.

<davidm@wailua.hpl.hp.com> (02/03/13 1.388.1.20)
	offsets.h:
	  Update offsets.h
	defconfig:
	  Update defconfig.

<davidm@hpl.hp.com> (02/03/13 1.388.1.21)
	[PATCH] More 2.5.6 sync up.
	
	Take advantage of new per-CPU scheme.

<davem@nuts.ninka.net> (02/03/13 1.384.7.16)
	Sparc64 build fix:
	Kill references to obsolete BLK{F}RA{SET,GET} ioctls.

<davem@nuts.ninka.net> (02/03/13 1.384.4.13)
	Integrate NAPI work done by Jamal Hadi Salim,
	Robert Olsson, and Alexey Kuznetsov.  This changeset adds
	the framework and implementation, but drivers need to be
	ported to NAPI in order to take advantage of the new
	facilities.  NAPI is fully backwards compatible, current
	drivers will continue to work as they always have.
	
	NAPI is a way for dealing with high packet load.  It allows
	the driver to disable the RX interrupts on the card and enter
	a polling mode.  Another way to describe NAPI would be as
	implicit mitigation.  Once the device enters this polling
	mode, it will exit back to interrupt based processing when
	the receive packet queue is purged.
	
	A full porting and description document is found at:
	Documentation/networking/NAPI_HOWTO.txt
	and this also makes reference to Usenix papers on the
	web and other such resources available on NAPI.
	
	NAPI has been found to not only increase packet processing
	rates, it also gives greater fairness to the other interfaces
	in the system which are not experiencing high packet load.

<davidm@hpl.hp.com> (02/03/13 1.388.4.1)
	[PATCH] More 2.5.6 sync up.
	
	Take advantage of new per-CPU scheme.

<davem@nuts.ninka.net> (02/03/13 1.384.7.17)
	Stack overflow debugging support.
	From Kanoj Sarcar.

<davem@nuts.ninka.net> (02/03/13 1.384.7.18)
	Verify stack more accurately in sparc64 stack overflow
	debugger by taking the FPU save area depth into
	consideration.

<jgarzik@mandrakesoft.com> (02/03/13 1.473.2.1)
	Small cleanups for the PCI MWI feature:
	* Generic helper function name change, s/pdev_set_mwi/pci_generic_prep_mwi/
	* Fix: Generic helper function ifdef'd out if arch function present
	* PCI MWI arch handler name change, s/pcibios_set_mwi/pcibios_prep_mwi/
	* Fix typos and speling errors in comments.
	* Cleanup printk message a bit.

<davem@nuts.ninka.net> (02/03/13 1.384.7.19)
	On sparc64, do not put PAGE_OFFSET in g4 anymore,
	put current task there instead.

<davidm@wailua.hpl.hp.com> (02/03/14 1.473.1.2)
	Make main-title more concise.
	Rename "General setup" to "Processor type and features".
	Move ACPI types after the point where HP_SIM gets defined.
	Pick up HP Ski configuration options from arch/ia64/hp/Config.in.

<stelian@popies.net> (02/03/14 1.473.3.1)
	Port the MotionEye driver to the new video4linux API.

<sawa@yamamoto.gr.jp> (02/03/15 1.473.4.1)
	Fix bug in at1700 net driver:
	RX_MODE was not set for the multicast case.  Set it.  Fixes multicast.

<bcrl@redhat.com> (02/03/15 1.473.4.2)
	Updates to ns83820 gige net driver:
	* Use likely() and unlikely() for better branch prediction
	* Various small cleanups
	* Much improved interrupt mitigation
	* Much improved throughput

<eli.kupermann@intel.com> (02/03/15 1.473.4.3)
	e100 net driver update 1/4:
	- minor changes to the license from our technical writer [still GPL ;-)]

<eli.kupermann@intel.com> (02/03/15 1.473.4.4)
	e100 net driver update 2/4:
	- remove dummy defines and also ia64 specific [Arjan's notes  [:-)] ]
	- fixed problem in e100_check_options function reported by our Q/A

<eli.kupermann@intel.com> (02/03/15 1.473.4.5)
	e100 net driver update 3/4:
	- added pci flushing in the e100_set_intr_mask function (pci posting bug)
	- better logic in the prepare_xmit_buff function moving some tx
	buffer initialization code to the start of the function.

<eli.kupermann@intel.com> (02/03/15 1.473.4.6)
	e100 net driver update 4/4:
	- switch to yield function as suggested by you, Arjan and Andrew.
	- fixed broken logic in the use of time_before/time_after - possible
	bug cause in previous design - in most of the places we were going to sleep
	and than check if time expires before checking if condition is satisfied.
	If, for example, we needed to wait up to 3 jiffies we could do
	schedule_timeout(1) and get up after 4 ticks check that time expired and go
	away crying about failure without checking that condition is OK.(in fact I
	saw it happen on one SMP platform here).

<jes@wildopensource.com> (02/03/15 1.473.4.8)
	acenic gige net driver updates:
	* various small cleanups
	* ETHTOOL_GDRVINFO support

<jes@wildopensource.com> (02/03/15 1.473.4.9)
	acenic gige net driver fixes:
	* fix Tigon I support
	* fix memory leak

<jgarzik@mandrakesoft.com> (02/03/15 1.473.4.10)
	acenic gige net driver update: merge VLAN support from 2.4.x kernel

<linux-m68k.org@mandrakesoft.com> (02/03/15 1.473.2.2)
	clgenfb fixes for zorro bus.  clgenfb should work again on m68k.

<wstinson@infonie.fr> (02/03/15 1.473.2.3)
	Fix rocketport serial driver for kdev_t changes in early 2.5.x series.

<wstinson@infonie.fr> (02/03/15 1.473.2.4)
	Janitor: request_region cleanups for stallion serial driver

<p_gortmaker@yahoo.com> (02/03/15 1.473.4.11)
	lance net driver update:  mark lance_probe as __init

<nahshon@actcom.co.il> (02/03/15 1.473.2.5)
	Fix via audio recording, when frag size < page size.

<silicon@falcon.sch.bme.hu> (02/03/15 1.473.2.6)
	Add new slicecom/munish WAN driver.

<jt@bougret.hpl.hp.com> (02/03/15 1.473.4.12)
	Convert hp100 net driver to PCI DMA mapping API.  (fixes build)

<jgarzik@mandrakesoft.com> (02/03/15 1.473.4.13)
	Don't include linux/delay.h twice in eepro100 net driver.
	
	Noticed by Alan Cox.

<jgarzik@mandrakesoft.com> (02/03/15 1.473.4.14)
	Fix e1000 net driver build with newer binutils.

<davem@nuts.ninka.net> (02/03/15 1.384.4.14)
	Netfilter updates from Harald Welte and myself:
	1) implement missing ip_conntrack_protocol_unregister function
	2) export ip_conntrack_unexpect_related symbol
	3) add support for destination nat on locally initiated connections
	4) add hooks for the filtering of ARP packets

<jgarzik@mandrakesoft.com> (02/03/15 1.473.2.7)
	Add BK kernel howto text and some helper scripts to
	new subdirectory linux/Documentation/BK-usage.

<j-nomura@ce.jp.nec.com> (02/03/15 1.473.1.4)
	[PATCH] Fix IA-32 Intercept code.
	
	(ia32_intercept): The code for Locked data reference fault is 4, not 3.

<kai@tp1.ruhr-uni-bochum.de> (02/03/15 1.473.6.1)
	Fix drivers/pnp/Makefile to correctly list multi-part
	objects in $(list-multi), instead of $(multi-objs)

<kai@tp1.ruhr-uni-bochum.de> (02/03/15 1.473.6.2)
	Improve Rules.make to automatically generate link rules for composite
	objects.
	
	Current behavior is not changed at all, but see the next cset for what
	it's good for.
	

<kai@tp1.ruhr-uni-bochum.de> (02/03/15 1.473.6.3)
	Remove link rules for multi-part drivers in drivers/isdn/*/Makefile.

<dhowells@redhat.com> (02/03/15 1.483)
	[PATCH] wait4() WIFSTOPPED starvation fix #1/2
	
	This patch (#1) just converts the task_struct to use struct list_head rather
	than direct pointers for maintaining the children list.

<torvalds@home.transmeta.com> (02/03/15 1.484)
	Cleanup: use list macros for task list

<dhowells@redhat.com> (02/03/15 1.485)
	[PATCH] wait4() WIFSTOPPED starvation fix #2/2
	
	This patch actually fixes the starvation bug in sys_wait4() by moving any
	process which is serviced for stoppage to the end of the child list.

<rmk@arm.linux.org.uk> (02/03/15 1.486)
	[PATCH] 2.5 and 2.4: fix PCI IO BAR flags
	
	There is a problem where the resource flags sometimes contain bits from
	the address part of the PCI BAR, especially when you have the low address
	bit set for an IO BAR.
	
	(bit 3 of a PCI IO BAR is an address bit, and (bar & 0xf) propagates this
	to res->flags).
	
	This exists in Ivan Kokshaysky PCI patches, and so far hasn't made it into
	the kernel.  It's required for IDE on certain ARM machines to even work.

<rmk@arm.linux.org.uk> (02/03/15 1.487)
	[PATCH] 2.4 and 2.5: remove Alt-Sysrq-L
	
	The following patch removes Alt-Sysrq-L and its associated hack to kill
	of PID1, the init process.  This is a mis-feature.
	
	If PID1 is killed, the kernel immediately enters an infinite loop in the
	depths of do_exit() with interrupts disabled, completely locking the
	machine.  Obviously you can only reach for the reset button or power
	switch after this, leaving you with dirty filesystems.

<rmk@arm.linux.org.uk> (02/03/15 1.488)
	[PATCH] 2.4 and 2.5: fix /proc/kcore
	
	As mentioned on May 11 on LKML, here is a patch to fix /proc/kcore for
	architectures which do not have RAM located at physical address 0.

<viro@math.psu.edu> (02/03/15 1.490)
	[PATCH] fs/libfs.c
	
		Linus, I've taken a bunch of common methods into fs/libfs.c and
	killed the (duplicated) instances in filesystems.  There will be more -
	ideally I'd like to get a library that would make writing small filesystems
	trivial.

<viro@math.psu.edu> (02/03/15 1.491)
	[PATCH] fix for leaks in nfsd
	
	Several exits in exp_export() forget to call path_release().  Fixed.

<viro@math.psu.edu> (02/03/15 1.492)
	[PATCH] nfsd as filesystem
	
	* introduces a new filesystem - nfsd.  No, it's not a typo.  It's a small
	  tree with fixed topology defined by nfsd and IO on its files does what
	  we used to do by hand in nfsctl.c.
	* turns sys_nfsservctl() into a sequence of open()/write()/read()/close()
	  It works as it used to - we don't need nfsd to be mounted anywhere, etc.
	* nfsd_linkage ugliness is gone.
	* getfs and getfh demonstrate (rather trivial) example of "descriptor as
	  transaction descriptor" behaviour.
	* we are fairly close to the situation when driver-defined filesystems can
	  be done with practically zero code overhead.  We are still not there, but
	  it's a matter of adding a couple of helpers for populating the tree.
	
		One thing we get immediately is a cleanup of sys_nfsservctl() -
	it got _much_ better.  Moreover, we get an alternative interface that
	uses normal file IO and can be used without magic syscalls.

<viro@math.psu.edu> (02/03/15 1.493)
	[PATCH] proc_pid_make_inode() fix
	
		In case if proc_pid_make_inode() steps on exiting task we do
	iput() and return NULL.  Unfortunately, in that case inode->i_ino
	doesn't look like inumber of a per-process inode and we take the
	wrong path in proc_delete_inode().  I.e. do dput(PDE(inode)).  Which
	is left uninitialized...
	
		We used to get out with that almost by accident - that code
	worked only because we had zeroed out one field of union and that
	guaranteed that another field would be NULL.  It worked, but broke
	at the first occasion.

<viro@math.psu.edu> (02/03/15 1.494)
	[PATCH] nfsd-as-fs NULL ptr fix
	
	It needs the following patch

<torvalds@home.transmeta.com> (02/03/15 1.495)
	Fix up architectures for task list changes

<bgerst@didntduck.org> (02/03/15 1.496)
	[PATCH] Cleanup F00F bug code
	
	This changes the F00F bug workaround code to use the fixmap facilities
	instead of touching the page tables directly.  It also removes the
	assumption that only 686's don't have the bug.  I have confirmation that
	the patch works on buggy pentiums. 

<bgerst@didntduck.org> (02/03/15 1.497)
	[PATCH] Fix NR_IRQS when no IO apic
	
	NR_IRQS should be 16 when the IO apic is not configured, as the 8259 PIC
	cannot generate any more interrupts.  It also fixes a bug where the IDT
	gets populated with random addresses, since only 16 entry stubs are
	created. 

<bgerst@didntduck.org> (02/03/15 1.498)
	[PATCH] struct super_block cleanup - msdos/vfat
	
	Seperates msdos_sb_info from struct super_block for msdos and vfat.
	Umsdos is terminally broken and is not included.

<bgerst@didntduck.org> (02/03/15 1.499)
	[PATCH] struct super_block cleanup - smbfs
	
	Seperates smb_sb_info from struct super_block.

<bgerst@didntduck.org> (02/03/15 1.500)
	[PATCH] struct super_block cleanup - qnx4
	
	Seperates qnx4_sb_info from struct super_block.

<bgerst@didntduck.org> (02/03/15 1.501)
	[PATCH] struct super_block cleanup - msdos/vfat
	
	Don't print out FAT superblock warnings if the IO failed.

<mikpe@csd.uu.se> (02/03/15 1.503)
	[PATCH] boot_cpu_data corruption on SMP x86
	
	The patch below eliminates a case of boot_cpu_data corruption
	on SMP x86 machines. This was first observed on SMP Athlons,
	but it also affects SMP Intel boxes in a less serious way.
	
	When the secondary processors boot and execute head.S:checkCPUtype,
	the code performs a 32-bit write of a small constant to the
	byte-sized variable boot_cpu_data.x86 (X86 in head.S). Since the
	write is 32-bit, it also writes zeros to the following 3 bytes,
	which clobbers the x86_vendor, x86_model, and x86_mask fields
	previously set up by check_bugs()'s call to identify_cpu().
	Thus, after smp_init(), boot_cpu_data will _always_ identify
	the CPU as an Intel (X86_VENDOR_INTEL == 0 in processor.h) with
	model 0 and stepping 0.
	
	The effect in standard kernels is not catastrophic, since:
	(a) most SMP x86 boxes are Intel
	(b) most uses of x86_vendor occur before smp_init() or reference
	    the SMP cpu_data[] array
	(c) most post-boot references to boot_cpu_data occur in the
	    cpu_has_XXX macros which only read the x86_capability[] array
	However, third-party extensions (like my x86 performance-monitoring
	conters driver) can get seriously confused by this mis-identification.

<agrover@groveronline.com> (02/03/15 1.504)
	[PATCH] ACPI patch 1/9
	
	This is the first of 9 patches. We did a complete rewrite of the
	Linux-specific code, so we wait for things to stabilize before submitting.
	There will be more updates, but *much* smaller.
	
	#1 - this updates the header file.

<agrover@groveronline.com> (02/03/15 1.505)
	[PATCH] ACPI patch 2/9
	
	This patch adds in the new drivers.
	
	- Support for driverfs
	- File/code layout more in the Linux style
	- improvements to battery, processor, and thermal support

<agrover@groveronline.com> (02/03/15 1.506)
	[PATCH] ACPI patch 3/9
	
	This patch updates the acpi IA32 arch-specific files. Part of this is
	taking what was acpitable.c and implementing it with better integration
	with the rest of the ACPI code.

<agrover@groveronline.com> (02/03/15 1.507)
	[PATCH] ACPI patch 4/9
	
	This is the config.in and makefile changes for the latest code. The most
	(only) interesting thing probably is ACPI is no longer flagged experimental.

<agrover@groveronline.com> (02/03/15 1.508)
	[PATCH] ACPI patch 5/9
	
	This is the update to the core interpreter code.

<agrover@groveronline.com> (02/03/15 1.509)
	[PATCH] ACPI patch 6/9
	
	This removes the old OSPM code. It lived under drivers/acpi/ospm/*, but
	the new code just lives in drivers/acpi, and removes some unnecessary
	abstraction that this old code had.

<agrover@groveronline.com> (02/03/15 1.510)
	[PATCH] ACPI patch 7/9
	
	This updates the Configure.help, both in arch/i386, and in drivers/acpi.

<agrover@groveronline.com> (02/03/15 1.511)
	[PATCH] ACPI patch 8/9
	
	This patch removes arch/i386/kernel/acpitable.c. As mentioned previously,
	the new ACPI code integrates this, so it's no longer needed.

<agrover@groveronline.com> (02/03/15 1.512)
	[PATCH] ACPI patch 9/9
	
	If you could only review one of the 9 patches, this would be the one.
	
	- removes acpitable.c vestiges
	- adds ACPI IRQ routing support to PCI (disableable via pci=noacpi option)
	- adds code to get a <1MB page for sleep, and ACPI boot to setup.c
	- allocates another page in the fixmap for ACPI
	- changes driverfs a little to work better with ACPI.

<torvalds@home.transmeta.com> (02/03/15 1.514)
	Fix overenthusiastic ia64 merge.
	
	That preempt_count really is supposed to be unconditional,
	architectures please take note and add to your thread info.

<davidm@napali.hpl.hp.com> (02/03/15 1.515)
	[PATCH] binfmt_elf.c: do SET_PERSONALITY() for static binaries
	
	Pick up binfmt_elf.c SET_PERSONALITY() fix from 2.4.18.

<cr@sap.com> (02/03/15 1.516)
	[PATCH] sync shmem.c in 2.5 to 2.4
	
	The appended patch brings the fixes applied in 2.4 to shmem.c to 2.5.
	
	In Detail:
	- Add needed checks for shmem_file_write and shmem_symlink
	- Add Documentation/filesystems/tmpfs.txt and adjust Config.help
	- Add uid and gid mount options
	- Make the error messages more user friendly

<torvalds@home.transmeta.com> (02/03/15 1.517)
	Trivial compile fix

<rem@osdl.org> (02/03/15 1.518)
	[PATCH] 2.5.7-pre1 Code cleanup for BSD accounting.
	
	Clean up BSD accounting locking code..

<torvalds@home.transmeta.com> (02/03/15 1.519)
	Fix up ACPI device breakage.
	
	For some reason the ACPI people continue to make the mistake
	of thinking that they are the root of the system.  Disabuse
	them of that notion.

<torvalds@home.transmeta.com> (02/03/15 1.520)
	Make sk_flags unsigned long, since we do bit operations on it

<torvalds@home.transmeta.com> (02/03/15 1.521)
	Update kernel version

<torvalds@penguin.transmeta.com> (02/03/15 1.522)
	update


Summary of changes from v2.5.6 to v2.5.7-pre1
============================================

<torvalds@penguin.transmeta.com> (02/03/08 1.385)
	Fix parport_cs compile troubles

<torvalds@penguin.transmeta.com> (02/03/08 1.386)
	Split out "msync" logic into a file of its own. No actual code
	changes.

<torvalds@penguin.transmeta.com> (02/03/08 1.387)
	msync cleanups

<torvalds@penguin.transmeta.com> (02/03/08 1.388)
	mm cleanup: split out mincore() system call from filemap.c

<torvalds@home.transmeta.com> (02/03/08 1.389)
	Fix missing '!' in set_fs_altroot() 

<davidm@wailua.hpl.hp.com> (02/03/09 1.369.15.1)
	ia64-patches

<davidm@wailua.hpl.hp.com> (02/03/09 1.369.15.2)
	This patch got dropped from the VM_DATA_DEFAULT_FLAGS patch sent earlier.

<davidm@wailua.hpl.hp.com> (02/03/09 1.369.15.3)
	Update EFI RTC driver to version 0.3.

<davidm@wailua.hpl.hp.com> (02/03/09 1.369.15.4)
	Fix two typos in comments.

<ch@hpl.hp.com> (02/03/09 1.375.2.18)
	[PATCH] 1033/1: latest 2.5.x badge4 def-config

<davidm@wailua.hpl.hp.com> (02/03/09 1.369.15.5)
	p4

<davidm@wailua.hpl.hp.com> (02/03/09 1.369.15.6)
	pci.c:
	  Print values of type dma_addr_t by casting to unsigned long and using the %lx format.

<davidm@wailua.hpl.hp.com> (02/03/09 1.369.15.7)
	as-flags.diff

<stefan.eletzhofer@eletztrick.de> (02/03/09 1.375.2.19)
	[PATCH] 1008/1: PCMCIA MECR handling
	This patch changes PCMCIA MECR handling such that:
		- MECR is changed in one function only and atomically
		- a additional callback for boards to allow them to
		  tweak BS values on a per-socket basis
	
	Note: I don't know wether or not tish changes are WIP or done
	already. If so, please drop it and send me a note.
	
	Changes files:
	linux/drivers/pcmcia/sa1100_generic.h
	linux/drivers/pcmcia/sa1100_generic.c
	

<xkaspa06@stud.fee.vutbr.cz> (02/03/09 1.375.2.20)
	[PATCH] 1039/1: EXPORT_SYMBOL(dma_spin_lock) for ALSA
	
	Even I do not realy use any ISA code of ALSA on my iPAQ I need it for compilation. As I build ALSA as modules, the dma_spin_lock symbol is missing.
	
	I have seen both definitions of dma_spin_lock (in kernel/dma.c and arch/arm/kernel/dma.c) same as EXPORT_SYMBOL in kernel/ksyms.c, but I think, exporting it in arch/arm/kernel/dma.c should be better then making confusion in kernel/ksyms.c
	
	2Russel: If you don't think this is good solution, we should discuss this in linux-arm-kernel mailing list
	

<src@flint.arm.linux.org.uk> (02/03/09 1.384.1.1)
	Update Makefile, sa1110 cpufreq code.  Drop static flash mapping from
	system3.c

<davidm@wailua.hpl.hp.com> (02/03/09 1.375.25.2)
	Fixup bad merge.

<xkaspa06@stud.fee.vutbr.cz> (02/03/09 1.384.1.3)
	[PATCH] 1036/1: allow APM to be build as module (for 2.5.5) (modified)
	
	This is updated version of patch 1002/1 . As build system in 2.5.5 kernel allows same name of .c files in different directories when computing dependencies and versioning information, the patch becomes simple. Now it just modify appropriate Makefile (in arch/arm/mach-sa1100) and exports one symbol in arch/arm/mach-sa10/pm.c)
	
	This patch replace 1002/1.
	
	(Hope, this is what you want Russel :)

<davidm@wailua.hpl.hp.com> (02/03/09 1.375.25.3)
	Fix formatting in Makefile.

<rmk@flint.arm.linux.org.uk> (02/03/10 1.375.12.3)
	Re-jig ARMv3 and up page table handing for better correctness with
	Ingo's highmem code.  This also helps with Riel's rmap VM, and
	eliminates the slab overhead for these processors.
	
	For more information, see:
	http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2002-March/008089.html

<jamey@crl.dec.com> (02/03/10 1.384.1.4)
	[PATCH] 889/1: updated jornada720 config file
	
	Updates the jornada720 config file to build with 2.4.17-rmk4

<rmk@flint.arm.linux.org.uk> (02/03/10 1.384.2.1)
	Make iq80310_gettimeoffset() return the currect time delta.
	Remove redundant irq_enter/irq_exit calls.

<rmk@flint.arm.linux.org.uk> (02/03/10 1.384.2.2)
	Fix up couple of bugs in Integrator PCI code.

<nico@cam.org> (02/03/10 1.384.1.5)
	[PATCH] 995/1: better EBSA110 idle
	
	This should bring better performances as all interrupts are always run with 
	clock switching enabled and the idle spinning always with the lower clock.
	
	This also keeps the brokenness of that architecture localized while 
	preserving the sanity of the common SA idle function.
	

<rmk@flint.arm.linux.org.uk> (02/03/10 1.384.2.3)
	Tidy up abort handler selection.  Use new glue.h to select relevant
	handler to allow for better optimisation.

<rmk@flint.arm.linux.org.uk> (02/03/10 1.384.2.4)
	Split out copy_user_page/clear_user_page to allow more efficient
	selection depending on processor features.

<rusty@rustcorp.com.au> (02/03/10 1.390)
	[PATCH] Futexes IV (Fast Lightweight Userspace Semaphores)
	
	Fast user-space mutex implementation, allowing user space to do all
	of the normal handling, with a minimal fallback to kernel space for
	when there is lock contention.
	
	The kernel space implementation does not keep any per-lock data
	structures, but instead does a fast hash on the physical page and offset
	of the user-space lock when contended.  Thus no build/teardown costs, or
	any scalability costs wrt metadata.
	
	Updated syscall numbers for 2.5.6, and changed FUTEX_UP/DOWN definitions
	to be more logical for future expansions (eg.  r/w).

<davem@nuts.ninka.net> (02/03/11 1.384.4.1)
	Move IP-specific identity information
	out of struct sock.
	Fix -EFAULT handling in TCP direct user copy handling.
	Use struct initializers in IPV6 ndisc code.

<davem@nuts.ninka.net> (02/03/11 1.384.4.2)
	Remove bogus tw->tb NULL check in
	tcp_timewait_kill.  This is what made the following
	bug harder to find:
	Put new timewait buckets into the bind hash _FIRST_
	before they appear into the established hash to
	kill some races with socket creation/lookup.

<davem@nuts.ninka.net> (02/03/11 1.384.4.3)
	Avoid using read/modify/write cycles to
	set frag_off field of IPv4 header in hot paths.
	Use __constant_htons as appropriate.

<davem@nuts.ninka.net> (02/03/11 1.384.4.4)
	Do not report inode numbers as negative
	in networking procfs nodes

<davem@nuts.ninka.net> (02/03/11 1.384.4.5)
	Export ip_net_protocol_{register,unregister}
	and ip_nat_used_tuple.
	Minor cleanups to conntrack/irc modules/configuration.
	From Harald Welte and the netfilter team.

<davem@nuts.ninka.net> (02/03/11 1.384.4.6)
	Never set IP_DF for ICMP packets.

<davem@nuts.ninka.net> (02/03/11 1.384.4.7)
	RED packet scheduler bug fixes from
	Jamal Hadi Salim.

<davem@nuts.ninka.net> (02/03/11 1.384.4.8)
	Make sock_writeable (used mostly by datagram
	protocols) more reasonable.  Kill all references
	to SOCK_MIN_WRITE_SPACE and kill its definition.
	Replace with appropriate sock_writeable calls.

<davem@nuts.ninka.net> (02/03/11 1.384.4.9)
	sock_register inet6_family_ops before we do init
	calls which might try to create ipv6 sockets.

<davem@nuts.ninka.net> (02/03/11 1.384.4.10)
	Major revamp of VLAN layer:
	1) Add hw acceleration hooks for device drivers.
	2) Move private declarations out of public includes.
	3) Mark file local functions and data as static.
	4) Use a small hash table for VLAN group lookups.
	5) Correct all the locking and device ref counting.
	6) No longer mark it as CONFIG_EXPERIMENTAL.

<davem@nuts.ninka.net> (02/03/11 1.384.5.1)
	Fix scheduler deadlock on some platforms.
	
	Some platforms need to grab mm->page_table_lock during switch_mm().
	On the other hand code like swap_out() in mm/vmscan.c needs to hold
	mm->page_table_lock during wakeups which needs to grab the runqueue
	lock.  This creates a conflict and the resolution chosen here is to
	not hold the runqueue lock during context_switch().
	
	The implementation is specifically a "frozen" state implemented as a
	spinlock, which is held around the context_switch() call.  This allows
	the runqueue lock to be dropped during this time yet prevent another cpu
	from running the "not switched away from yet" task.

<davem@nuts.ninka.net> (02/03/11 1.384.5.2)
	Fix CAN_MIGRATE_TASK macro to use p arg it gets
	instead of tmp explicitly.

<davem@nuts.ninka.net> (02/03/11 1.384.5.3)
	Use cpu_logical_map as appropriate.

<davem@nuts.ninka.net> (02/03/11 1.384.5.4)
	If cache_decay_ticks is large enough, the migration
	thread startup at boot time can fail.
	Fix this by temporarily setting cache_decay_ticks
	to zero around migration thread startup.

<davem@nuts.ninka.net> (02/03/11 1.384.6.1)
	Add back check_pgt_cache call.
	Add nop definition for x86.

<davem@nuts.ninka.net> (02/03/11 1.384.6.2)
	Fix typos.

<rmk@flint.arm.linux.org.uk> (02/03/11 1.384.1.8)
	Fix up spinlocking/IRQ handling in SCSI drivers for Acorn machines.

<rmk@flint.arm.linux.org.uk> (02/03/11 1.384.1.9)
	Bug fixes for Acorn network drivers.

<rmk@flint.arm.linux.org.uk> (02/03/11 1.384.1.10)
	Update Acorn serial drivers.

<davem@nuts.ninka.net> (02/03/11 1.384.7.1)
	Sparc64 updates mostly build fixes:
	1) Update for schedule_tail and switch_to arg changes.
	2) Update for PTE highmem.
	3) Add random ioctls to ioctl32 translations.
	4) Kill migration IPI.
	5) Fixup scheduler bitmap function and move into bitops.h

<davem@nuts.ninka.net> (02/03/11 1.384.7.2)
	Do not expand stack for non-faulting loads

<davem@nuts.ninka.net> (02/03/11 1.384.7.3)
	Fix PCI IRQ probing for some bridging situations.
	Use PCI_SLOT instead of hard-coded shift.

<davem@nuts.ninka.net> (02/03/11 1.384.7.4)
	Use pci_memspace_mask instead of hard-coded
	value 0xffffffff.

<davem@nuts.ninka.net> (02/03/11 1.384.7.5)
	Work around some hw bugs in Schizo PCI controllers.

<davem@nuts.ninka.net> (02/03/11 1.384.7.6)
	Use dma_addr_t for hblock_dvma.
	Make device probe failure more robust.

<davem@nuts.ninka.net> (02/03/11 1.384.7.7)
	Init FHC controller registers earlier so that
	Zilog interrupt mappings are not clobbered on
	Sun Enterprise servers.
	Fix some FHC register offsets.
	Sometimes IPIs can allow BHs to run with interrupts
	disabled, fix that by rescheduling them to normal
	PIL based interrupts.

<davem@nuts.ninka.net> (02/03/11 1.384.7.8)
	Read lock around files->fd[] accesses.

<davem@nuts.ninka.net> (02/03/11 1.384.7.9)
	Add SI_DETHREAD

<davem@nuts.ninka.net> (02/03/11 1.384.7.10)
	Add per_cpu linker script bits for Sparc.

<bcrl@toomuch.toronto.redhat.com> (02/03/11 1.384.8.1)
	Avoid looping in write_inode_now since the sync_one changes now ensure __sync_one 
	is called once the inode is unlocked.

<dalecki@evision-ventures.com> (02/03/11 1.388.1.1)
	[PATCH] 2.5.6 IDE 18
	
	No fixes for new problems which occured since today, just syncup.
	
	 - Remove help text about suitable compiler versions, which is obsoleted
	   by the overall kernel reality.
	
	 - Remove traces of not progressing work in progress code for the
	   CONFIG_BLK_DEV_ADMA option as well as the empty ide-adma.c file as
	   well as CONFIG_BLK_DEV_IDEDMA_TCQ.
	
	 - Remove redundant CONFIG_BLK_DEV_IDE != n check in ide/Config.in. Hugh,
	   this is a tricky one...
	
	 - Add EXPORT_SYMBOL(ide_fops) again, since it's used in ide-cd.c add a
	   note there that this is actually possibly adding the same device twice
	   to the devfs stuff.
	
	 - Finally change the MAINTAINER entry. Just too many persons bogged me
	   about it and it doesn't take me too much time apparently.
	
	 - Apply sis.patch.20020304_1.
	
	 - Don't call ide_release_dma twice in cleanup_ata, since ide_unregister
	   is already calling it for us. Change prototype of ide_unregister to
	   take a hwif as parameter and disable an ioctl for removing/scanning
	   hwif from the list of handled interfaces. I see no reasons for having
	   it and doing it is the fastest DOS attack on my home system I know
	   about it. Contrary to the comments found here and there, hdparm
	   doesn't use it. There are better hot plugging interfaces coming to the
	   kernel right now anyway.
	
	 - Wrap invalidate_drives in ide_unregister under the ide_lock instead of
	   disabling and enabling interrupts during this operation. There are
	   plenty of other places where the IDE drivers are enabling and
	   disabling interrupts just to protect some data structures.
	
	 - Don't call destroy_proc_ide_drives(hwif) for every single drive out
	   there.This routine takes a hwif as a parameter.
	
	 - Resync with the instable 2.5.6...

<dalecki@evision-ventures.com> (02/03/11 1.388.1.2)
	[PATCH] 2.5.6 IDE 19
	
	 - Fix oversight in replacement of sti() cli() pairs for data structure
	   access protection.  This finally resolvs my problems with the 2.5.6
	   kernel series.  Now I'm in fact quite puzzled how it was even possible
	   for the system to get into the init stage without this fix..
	
	 - Fix usage of CONFIG_BLK_DEV_IDE_MODULES instead of
	   CONFIG_BLK_DEV_IDE_MODULE.
	
	 - Make idescsi_init global for usage in systems without module support
	   enabled.
	
	 - Apply Pavels Macheks patch for suspend support.  Whatever some persons
	   argue that it's not fully implemented, I think that we are in
	   development series right now.  I don't buy the mock-up examples for
	   problems with either outdated or broken hardware.  Micro Drives are
	   for example expected to be drop in replacements for CF cards in
	   digital cameras and I would rather expect them to be very tolerant
	   about the driver in front of them.  And then the WB caches of IDE
	   devices are not caches in the sense of a MESI cache, they are more
	   like buffer caches and should therefore flush them self after s short
	   period of inactivity without the application of any special flush
	   command.  The upcoming explicit flushing commands in the ATA standard
	   are about data integrity guarantees in high reliability systems, like
	   DB servers for example, and not about simple cache validity.
	
	 - Apply Vojtech Pavliks fix to the VIA host chip initialization code.
	
	 - Add missing if-defs around PIO timing tables.
	
	 - Fix max() min() related compile warnings in IDE-scsi.

<jt@bougret.hpl.hp.com> (02/03/11 1.388.1.3)
	[PATCH] New wireless driver API part 2
	
		Quick summary : this patch build on the first part to offer
	two important new features :
			o Wireless Events
			o Wireless Cell Scanning
		Wireless Events are events generated by device, driver or the
	wireless subsystem. It allows for example a device to notify user
	space when it register to a new cell (roaming) or loose contact with
	the current Access Points. Currently, the other defined events include
	some configuration changes and packet drop due to excessive retries,
	more may come in the future. All those events are useful for MobileIP,
	V-Handoff and Ad-Hoc routing.
		Wireless Cell Scanning is a generic API to allow device/drive
	to report Wireless Cells discovered (including ESSID, frequency and
	QoS). This is similar to what is available in WindowsXP (except that
	it's compliant to Wireless Extensions).
	
		This patch has been submitted for review on this list a couple
	of time in January, has been on my web page since and used intensively
	by other people. It was rediffed to 2.5.6. Driver patches have been
	submitted to maintainers.

<vojtech@suse.cz> (02/03/11 1.388.1.5)
	[PATCH] My AMD IDE driver, v2.7
	
	This patch replaces the current AMD IDE driver (by Andre Hedrick) by
	mine. Myself I think my implementation is much cleaner, but I'll leave
	upon others to judge that. My driver also additionally supports the
	AMD-8111 IDE.
	
	It's well tested, and I'd like to have this in the kernel instead of
	what's there now.

<rem@osdl.org> (02/03/11 1.388.1.6)
	[PATCH] 2.5.6-pre3 Fix small race in BSD accounting
	
	Below is a patch to remove a small race in kernel/acct.c.

<rem@osdl.org> (02/03/11 1.388.1.7)
	[PATCH] 2.5.6-pre3 Fix small race in BSD accounting
	
	While looking at the bug fix for part 1 I coded up this patch
	to change the BSD accounting code to use a spinlock instead
	of the BKL.

<alan@lxorguk.ukuu.org.uk> (02/03/11 1.388.1.8)
	[PATCH] 2.5.6-pre3 Fix BSD accounting rlimit
	
	Fix rlimit on accounting file.

<akpm@zip.com.au> (02/03/11 1.388.1.10)
	[PATCH] fix layout of mapped files
	
	If you create a shared mapping of a sparse file, dirty it
	and then run msync, all the file's blocks are laid out
	backwards.
	
	This is because filemap_sync puts the lowest-index page at
	mapping->dirty_pages.prev and the highest at mapping->dirty_pages.next.
	
	I think that by walking the dirty pages list in ascending file
	offset order as we instantiate their disk mappings we will generally
	get better layout.

<neilb@cse.unsw.edu.au> (02/03/11 1.388.1.11)
	[PATCH] PATCH - knfsd fixes for 2.5.6
	
	Fix a few kNFSd problems.
	
	1/ export svc_reserve which was introduced for NFS/TCP support.
	    Without this we cannot load nfsd.o as a module
	2/ the hash chain of clients was being changed (to put the found
	   entry at the top of the list) while we only had a read-lock.
	   This could corrupt the list and cause big problems.
	   For now, just disable this code.  Might add a lock later...
	3/ lockd was calling exp_getclient without getting a readlock
	   on the export table first.
	4/ Add Config.help entry for CONFIG_NFSD_TCP

<viro@math.psu.edu> (02/03/11 1.388.1.12)
	[PATCH] (1/4) ->kill_sb() switchover
	
	New method - ->kill_sb().  It will eventually replace current
	fs/super.c::shutdown_super() - i.e. it's called when fs driver
	must shut the superblock down, remove it from all lists, etc.

<viro@math.psu.edu> (02/03/11 1.388.1.13)
	[PATCH] (2/4) ->kill_sb() switchover
	
	FS_LITTER filesystems (ramfs-like) switched to use of ->kill_sb().
	FS_LITTER is gone.

<viro@math.psu.edu> (02/03/11 1.388.1.14)
	[PATCH] (3/4) ->kill_sb() switchover
	
	The rest of nodev filesystems switched.

<viro@math.psu.edu> (02/03/11 1.388.1.15)
	[PATCH] (4/4) ->kill_sb() switchover
	
	bdev filesystems switched.  Changes documented in Locking and porting.

<viro@math.psu.edu> (02/03/11 1.388.1.16)
	[PATCH] fix for get_sb_bdev() bug
	
		Grr...  When loop in get_sb_bdev() had been switched from
	global list of superblock to per-type one, we should have switched
	from sb_entry(p) (aka. list_entry(p, struct super_block, s_list)) to
	list_entry(p, struct super_block, s_instances).
	
		As it is, we end up with false negatives all the time.  I.e.
	second mount from the same block device with the same type gices
	a new superblock.  With obvious nasty results...
	
		This fixes that.

<rmk@flint.arm.linux.org.uk> (02/03/12 1.384.1.11)
	Add /dev/rtc support for Acorn machines.

<rmk@flint.arm.linux.org.uk> (02/03/12 1.384.1.12)
	Update ARM tree for 2.5.6

<davem@nuts.ninka.net> (02/03/11 1.384.7.11)
	Update sparc64 defconfig.

<davem@nuts.ninka.net> (02/03/11 1.384.7.12)
	Add sys_sendfile64 to sparc syscall tables.

<dwmw2@infradead.org> (02/03/12 1.388.3.1)
	Update to 2002-03-12 JFFS2 development tree. Main features:
	 - Preliminary version of NAND flash support.
	 - Locking documentation and fixes (including BKL removal because it's superfluous).
	 - Performance improvements - especially for mount time. 
	 - Annoying stuff like i_nlink on directories fixed.
	 - Portability cleanups.

<davem@nuts.ninka.net> (02/03/12 1.384.7.13)
	Fix sys32_sendfile64 implementation.

<neilb@cse.unsw.edu.au> (02/03/12 1.393)
	[PATCH] PATCH - knfsd in 2.5.6 - fsid= export option
	
	Support fsid=<number> export option to be device number independent
	
	This patch was largely supplied by Steven Whitehouse <steve@gw.chygwyn.com>
	
	A new export option "NFSEXP_FSID" indicates that the ex_dev passed down
	is a user specified number, not a device number.
	It should be used in fsid_type==1 filehandles to identify the
	the exportpoint rather than the devid and inode (as in fsid_type == 0).
	This allows filehandles to be device-number independent so that when Linux
	changes device numbers on you (after reboot), your filesystems wont go stale.
	
	User-space support for this is in the nfs-utils CVS and will be in
	the next release (any release > 1.0).

<sfr@canb.auug.org.au> (02/03/12 1.394)
	[PATCH] dnotify
	
	The following patch makes directory notifications per thread group instead
	of per process tree as they are now.  This means, in particular, that if
	a child closes a file descriptor that has a directory open with notifies
	enabled, the notification will not be removed.
	
	Thanks to Andrea for the push in the right direction.

<bgerst@didntduck.org> (02/03/12 1.395)
	[PATCH] struct superblock cleanup - minixfs
	
	Start of cleaning up the union of filesystem-specific structures in
	struct super_block.  The goal is to remove dependence on filesystem
	headers in fs.h. 
	
	This patch abstracts the access to the minix_sb_info structure through
	the function minix_sb(). 

<bgerst@didntduck.org> (02/03/12 1.396)
	[PATCH] struct superblock cleanup - minixfs
	
	Switch to using kmalloc to allocate the minix superblock structure.

<sfr@canb.auug.org.au> (02/03/12 1.397)
	[PATCH] DMI patch for broken Dell laptop
	
	This adds DMI recognition for anohter broken Dell laptop BIOS (BIOS
	version A12 on the Insiron 2500).
	
	Reported by Mihnea-Costin Grigore <mgc8@totalnet.ro>.

<john@deater.net> (02/03/12 1.398)
	[PATCH] pci=usepirqmask option.
	
	Last week I sent you a patch adding a config option to honor the pirq mask
	in the PCI routing table.  On your suggestion, Cory Bell made it a command
	line option using the pci= interface and we both agree with you, it's
	-much- cleaner this way.
	
	Patch against 2.5.6 (Cory's submitting for 2.4, I've tested and submitting
	towards 2.5).  All credit goes to Cory Bell, with only minor input and
	testing from myself.

<viro@math.psu.edu> (02/03/12 1.399)
	[PATCH] (1/2) fs/super.c cleanups
	
	New helper - sget().  get_sb_bdev() and get_anon_super()
	switched to using it.  Basically, it's get_anon_super()
	done right (and get_anon_super() itself will probably
	die).

<viro@math.psu.edu> (02/03/12 1.400)
	[PATCH] (2/2) fs/super.c cleanups
	
	kill_super() and deactivate_super() merged.
	
	Next step will be to export these suckers - after that we will be finally
	done with infrastructure for filesystems with nontrivial ->get_sb().

<sfr@canb.auug.org.au> (02/03/12 1.401)
	[PATCH] Trivial APM update part 1
	
	This is the first of a series of patches I have got from Thomas Hood
	that modify the apm code mainly for better self documentation.
	
	This one does:
	
	Variable "waiting_for_resume" is renamed 'ignore_sys_suspend'.
	The reason for the change is that this flag variable is
	employed in a manner analogous to that of other flag variables
	named 'ignore ...'.  When the flag is set, the driver needs to
	ignore further system suspends.  The driver does not "wait"
	in the usual sense of that word.  The only sense in which the
	driver waits is the sense in which it needs to continue to
	ignore system suspends until certain events occur.  One such
	event is a resume.  However, another such event is the vetoing
	of the suspend request by a driver.  So it would be more
	accurate to call the flag 'waiting_for_resume_or_suspend_reject'
	or something like that.  But for the reason mentioned first,
	an even better name is 'ignore_sys_suspend'.

<sfr@canb.auug.org.au> (02/03/12 1.402)
	[PATCH] Trivial apm update: eliminate 0 initializers
	
	Second in a series of patches from Thomas Hood.
	
	This patch eliminates the 0 initializers on three
	static variables inside the apm_cpu_idle function.
	These initializers are superfluous.
	
	The initializers are replaced with comments whose
	purpose is to indicate that the code relies upon the
	fact that these variables are initialized to zero
	at load time.

<sfr@canb.auug.org.au> (02/03/12 1.403)
	[PATCH] Trivial apm patch: move apm_error up
	
	Here is the third one.
	
	This patch moves the apm_error() function higher
	in the file so that it is adjacent to the error_table
	that it uses.  This makes the code easier to read.
	The beginning of the file is an appropriate place
	for "utility" functions of this kind.  This is a pure
	move, with no changes made to the function.

<sfr@canb.auug.org.au> (02/03/12 1.404)
	[PATCH] APM:  move 'ignore_normal_resume = 1'
	
	This is number four and actually fixes a bug.
	
	This patch moves the setting of the ignore_normal_resume flag
	prior to the sti(); otherwise BIOS-generated normal resume
	events slip through unignored.

<sfr@canb.auug.org.au> (02/03/12 1.405)
	[PATCH] Trivial APM patch: set_system_power_state
	
	Number 5 from Thomas Hood
	
	This patch renames the static function "apm_set_power_state"
	to 'set_system_power_state'.
	
	Generally, the prefix 'apm_' is required to prevent external
	name collisions on exported functions.  This is a static function,
	so the prefix isn't required for that purpose.  The prefix might
	also indicate that this function has something particularly
	to do with the apm subsystem; but that's not the case here.  This
	function is simply a wrapper for set_power_state(), inserting the
	argument which sets the power state for the whole system.
	My main motivation for wanting to change this name is clearly
	to indicate the difference between this function and
	set_power_state().  Also, I would like to export set_power_state()
	someday in the future, but this is a separate issue.

<sfr@canb.auug.org.au> (02/03/12 1.406)
	[PATCH] APM patch: change implementation of ALWAYS_CALL_BUSY
	
	Number 6
	
	This patch cleans up the way the ALWAYS_CALL_BUSY macro
	forces calling of the APM BIOS busy routine.  Instead
	of storing a false value in clock_slowed, we disjoin
	clock_slowed with the value of ALWAYS_CALL_BUSY.  This
	simplifies the code.

<sfr@canb.auug.org.au> (02/03/12 1.407)
	[PATCH] APM patch: apm_cpu_idle cleanups
	
	Number 7.
	
	This patch contains four cleanup changes whose aim
	is better code self-documentation (the best way to
	document IMHO).  They are sent together because they
	overlap.
	
	1. Rename the variable "sys_idle" to 'original_pm_idle'.
	This is where we store the value that we find in pm_idle before
	we substitute the address of our own apm_cpu_idle() function.
	In principle we have no idea whose address this is, so
	the variable name shouldn't imply that we know that this is
	the address of a system idle function; it should simply
	indicate that it is the original value of pm_idle.
	
	2. Variable "apm_is_idle" is renamed 'apm_idle_done'.
	This flag indicates when apm_do_idle() has been called.
	It is a premise of apm_cpu_idle()'s operation that it is
	not known whether the apm_do_idle() function really idles
	the CPU.  The name of the flag should not lead one to
	believe otherwise.
	
	3. Variable "t1" is renamed 'bucket'.  The variable is not
	a time but a countdown ("bucket"), so the variable name
	should not lead one to believe it is some sort of time
	value.
	
	4. A default: case is added to the switch in order to
	remind the reader that there is a third possible return
	value from apm_do_idle().

<bgerst@didntduck.org> (02/03/12 1.408)
	[PATCH] struct super_block cleanup - cramfs
	
	Seperates cramfs_sb_info from struct super_block.

<kraxel@bytesex.org> (02/03/12 1.410)
	[PATCH] video4linux doc fix
	
	This patch updates/fixes the video4linux API documantation.  The current
	description for mmap() based capture is unclear and somewhat misleading.

<kraxel@bytesex.org> (02/03/12 1.411)
	[PATCH] miropcm20 build fix
	
	This patch fixes the build failure of the miro radio driver due to
	the new location of the sound drivers in the tree (alsa merge).

<kraxel@bytesex.org> (02/03/12 1.412)
	[PATCH] videodev redesign
	
	This patch is a redesign for videodev.[ch].  Changes:
	
	- drop the function pointers (read/write/mmap/poll/...) from struct
	  video_device, use struct file_operations directly instead.
	  Dispatching to different drivers by minor number is done the same way
	  soundcore.o handles this: swap file->f_fops at open() time.
	
	- also drop the now obsolete video_red/write/mmap/poll/...  functions
	  from videodev.c
	
	- Stop using the BKL, use a mutex to protect open,register+unregister
	  calls against races.
	
	- provide a video_generic_ioctl() function which can (and should) be
	  used by v4l drivers to handle copying from and to userspace.
	
	- provide video_exclusive_open/release functions which can be used by
	  v4l drivers to make sure only one process at a time opens the
	  device.  They can be hooked directly into struct file_operations if
	  some driver has nothing to initialize at open time (which is true
	  for many drivers in drivers/media/radio/).
	
	The move from function pointers in struct video_device to struct
	file_operations does break all existing v4l drivers.  Thus I have a
	large number of patches for the drivers in the kernel tree.  Most of it
	is just the adoption to the videodev.[ch] changes, but I've also fixed a
	small bug there and there while walking througth the source files.

<kraxel@bytesex.org> (02/03/12 1.413)
	[PATCH] es1370 virt_to_bus fix
	
	This patch fixes the es1370 build problems due to virt_to_bus()
	being gone.

<davem@nuts.ninka.net> (02/03/12 1.384.7.14)
	Include asm/page.h in sparc64 thread_info.h

<torvalds@penguin.transmeta.com> (02/03/12 1.419)
	Update kernel version



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

* Re: Linux 2.5.7
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
@ 2002-03-18 21:57 ` Xavier Bestel
  2002-03-28  9:21 ` [PATCH] 2.5.7 IDE 23 Martin Dalecki
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Xavier Bestel @ 2002-03-18 21:57 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Linux Kernel Mailing List

le lun 18-03-2002 à 21:47, Linus Torvalds a écrit :
> 
> Ok, there's a 2.5.7 out there now, full changelog appended.

... and it's a really nice changelog !

	Xav



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

* [PATCH] 2.5.7 IDE 23
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
  2002-03-18 21:57 ` Xavier Bestel
@ 2002-03-28  9:21 ` Martin Dalecki
  2002-03-28  9:23 ` PATCH 2.5.7 IDE 24 Martin Dalecki
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-03-28  9:21 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Mon Mar 18 19:02:07 CET 2002 ide-clean-23

- Support for additional Promise controller id's (PDC20276).

- Remove code duplication between do_rw_taskfile and do_taskfile.
   This will evolve into a more reasonable ata_command() function
   finally. The ata_taskfile function has far too many arguments, but
   I favour this over having two different code paths for getting
   actual data to the drive.

[-- Attachment #2: ide-clean-23.diff --]
[-- Type: text/plain, Size: 30070 bytes --]

diff -urN linux-2.5.7-pre2/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.7-pre2/drivers/ide/ide-disk.c	Tue Mar 19 03:32:11 2002
+++ linux/drivers/ide/ide-disk.c	Tue Mar 19 03:25:58 2002
@@ -106,50 +106,6 @@
 	return 0;	/* lba_capacity value may be bad */
 }
 
-static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
-static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
-static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block);
-
-/*
- * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
- * otherwise, to address sectors.  It also takes care of issuing special
- * DRIVE_CMDs.
- */
-static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
-{
-	/*
-	 * Wait until all request have bin finished.
-	 */
-
-	while (drive->blocked) {
-		yield();
-		// panic("ide: Request while drive blocked?");
-	}
-
-	if (!(rq->flags & REQ_CMD)) {
-		blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
-		ide_end_request(drive, 0);
-		return ide_stopped;
-	}
-
-	if (IS_PDC4030_DRIVE) {
-		extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
-
-		return promise_rw_disk(drive, rq, block);
-	}
-
-	/* 48-bit LBA */
-	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
-		return lba48_do_request(drive, rq, block);
-
-	/* 28-bit LBA */
-	if (drive->select.b.lba)
-		return lba28_do_request(drive, rq, block);
-
-	/* 28-bit CHS */
-	return chs_do_request(drive, rq, block);
-}
-
 static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
 {
 	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
@@ -158,20 +114,38 @@
 	lba48bit = drive->addressing;
 #endif
 
-	if (cmd == READ) {
-		if (drive->using_dma)
-			return (lba48bit) ? WIN_READDMA_EXT : WIN_READDMA;
-		else if (drive->mult_count)
-			return (lba48bit) ? WIN_MULTREAD_EXT : WIN_MULTREAD;
-		else
-			return (lba48bit) ? WIN_READ_EXT : WIN_READ;
-	} else if (cmd == WRITE) {
-		if (drive->using_dma)
-			return (lba48bit) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
-		else if (drive->mult_count)
-			return (lba48bit) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
-		else
-			return (lba48bit) ? WIN_WRITE_EXT : WIN_WRITE;
+	if (lba48bit) {
+		if (cmd == READ) {
+			if (drive->using_dma)
+				return WIN_READDMA_EXT;
+			else if (drive->mult_count)
+				return WIN_MULTREAD_EXT;
+			else
+				return WIN_READ_EXT;
+		} else if (cmd == WRITE) {
+			if (drive->using_dma)
+				return WIN_WRITEDMA_EXT;
+			else if (drive->mult_count)
+				return WIN_MULTWRITE_EXT;
+			else
+				return WIN_WRITE_EXT;
+		}
+	} else {
+		if (cmd == READ) {
+			if (drive->using_dma)
+				return WIN_READDMA;
+			else if (drive->mult_count)
+				return WIN_MULTREAD;
+			else
+				return WIN_READ;
+		} else if (cmd == WRITE) {
+			if (drive->using_dma)
+				return WIN_WRITEDMA;
+			else if (drive->mult_count)
+				return WIN_MULTWRITE;
+			else
+				return WIN_WRITE;
+		}
 	}
 	return WIN_NOP;
 }
@@ -183,8 +157,6 @@
 	ide_task_t			args;
 	int				sectors;
 
-	task_ioreg_t command	= get_command(drive, rq_data_dir(rq));
-
 	unsigned int track	= (block / drive->sect);
 	unsigned int sect	= (block % drive->sect) + 1;
 	unsigned int head	= (track % drive->head);
@@ -203,7 +175,7 @@
 	taskfile.high_cylinder	= (cyl>>8);
 	taskfile.device_head	= head;
 	taskfile.device_head	|= drive->select.all;
-	taskfile.command	= command;
+	taskfile.command	=  get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -221,7 +193,12 @@
 	args.block = block;
 	rq->special = &args;
 
-	return do_rw_taskfile(drive, &args);
+	return ata_taskfile(drive,
+			(struct hd_drive_task_hdr *) &args.tfRegister,
+			(struct hd_drive_hob_hdr *) &args.hobRegister,
+			args.handler,
+			args.prehandler,
+			args.rq);
 }
 
 static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
@@ -231,8 +208,6 @@
 	ide_task_t			args;
 	int				sectors;
 
-	task_ioreg_t command	= get_command(drive, rq_data_dir(rq));
-
 	sectors = rq->nr_sectors;
 	if (sectors == 256)
 		sectors = 0;
@@ -246,7 +221,7 @@
 	taskfile.high_cylinder	= (block>>=8);
 	taskfile.device_head	= ((block>>8)&0x0f);
 	taskfile.device_head	|= drive->select.all;
-	taskfile.command	= command;
+	taskfile.command	= get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -264,7 +239,12 @@
 	args.block = block;
 	rq->special = &args;
 
-	return do_rw_taskfile(drive, &args);
+	return ata_taskfile(drive,
+			(struct hd_drive_task_hdr *) &args.tfRegister,
+			(struct hd_drive_hob_hdr *) &args.hobRegister,
+			args.handler,
+			args.prehandler,
+			args.rq);
 }
 
 /*
@@ -280,8 +260,6 @@
 	ide_task_t			args;
 	int				sectors;
 
-	task_ioreg_t command	= get_command(drive, rq_data_dir(rq));
-
 	memset(&taskfile, 0, sizeof(task_struct_t));
 	memset(&hobfile, 0, sizeof(hob_struct_t));
 
@@ -306,7 +284,7 @@
 	taskfile.device_head	= drive->select.all;
 	hobfile.device_head	= taskfile.device_head;
 	hobfile.control		= (drive->ctl|0x80);
-	taskfile.command	= command;
+	taskfile.command	= get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -324,7 +302,52 @@
 	args.block = block;
 	rq->special = &args;
 
-	return do_rw_taskfile(drive, &args);
+	return ata_taskfile(drive,
+			(struct hd_drive_task_hdr *) &args.tfRegister,
+			(struct hd_drive_hob_hdr *) &args.hobRegister,
+			args.handler,
+			args.prehandler,
+			args.rq);
+}
+
+/*
+ * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
+ * otherwise, to address sectors.  It also takes care of issuing special
+ * DRIVE_CMDs.
+ */
+static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
+{
+	/*
+	 * Wait until all request have bin finished.
+	 */
+
+	while (drive->blocked) {
+		yield();
+		// panic("ide: Request while drive blocked?");
+	}
+
+	if (!(rq->flags & REQ_CMD)) {
+		blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
+		ide_end_request(drive, 0);
+		return ide_stopped;
+	}
+
+	if (IS_PDC4030_DRIVE) {
+		extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
+
+		return promise_rw_disk(drive, rq, block);
+	}
+
+	/* 48-bit LBA */
+	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
+		return lba48_do_request(drive, rq, block);
+
+	/* 28-bit LBA */
+	if (drive->select.b.lba)
+		return lba28_do_request(drive, rq, block);
+
+	/* 28-bit CHS */
+	return chs_do_request(drive, rq, block);
 }
 
 static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
@@ -333,10 +356,13 @@
 	if (drive->removable && drive->usage == 1) {
 		struct hd_drive_task_hdr taskfile;
 		struct hd_drive_hob_hdr hobfile;
+
 		memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
 		memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+
 		check_disk_change(inode->i_rdev);
 		taskfile.command = WIN_DOORLOCK;
+
 		/*
 		 * Ignore the return code from door_lock,
 		 * since the open() has already succeeded,
@@ -355,11 +381,10 @@
 	struct hd_drive_hob_hdr hobfile;
 	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
 	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
-	if (drive->id->cfs_enable_2 & 0x2400) {
+	if (drive->id->cfs_enable_2 & 0x2400)
 		taskfile.command	= WIN_FLUSH_CACHE_EXT;
-	} else {
+	else
 		taskfile.command	= WIN_FLUSH_CACHE;
-	}
 	return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
 }
 
@@ -643,7 +668,7 @@
 			taskfile.command = WIN_SPECIFY;
 			handler	= set_geometry_intr;;
 		}
-		do_taskfile(drive, &taskfile, &hobfile, handler);
+		ata_taskfile(drive, &taskfile, &hobfile, handler, NULL, NULL);
 	} else if (s->b.recalibrate) {
 		s->b.recalibrate = 0;
 		if (!IS_PDC4030_DRIVE) {
@@ -653,7 +678,7 @@
 			memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 			taskfile.sector_count	= drive->sect;
 			taskfile.command	= WIN_RESTORE;
-			do_taskfile(drive, &taskfile, &hobfile, recal_intr);
+			ata_taskfile(drive, &taskfile, &hobfile, recal_intr, NULL, NULL);
 		}
 	} else if (s->b.set_multmode) {
 		s->b.set_multmode = 0;
@@ -666,7 +691,7 @@
 			memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 			taskfile.sector_count	= drive->mult_req;
 			taskfile.command	= WIN_SETMULT;
-			do_taskfile(drive, &taskfile, &hobfile, &set_multmode_intr);
+			ata_taskfile(drive, &taskfile, &hobfile, set_multmode_intr, NULL, NULL);
 		}
 	} else if (s->all) {
 		int special = s->all;
diff -urN linux-2.5.7-pre2/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- linux-2.5.7-pre2/drivers/ide/ide-pci.c	Tue Mar 19 03:32:11 2002
+++ linux/drivers/ide/ide-pci.c	Tue Mar 19 00:52:41 2002
@@ -229,6 +229,7 @@
 	{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ  | ATA_F_DMA },
 	{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
 	{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, pci_init_pdc202xx, ata66_pdc202xx,	ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
+	{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, pci_init_pdc202xx, ata66_pdc202xx,	ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
 #endif
 #ifdef CONFIG_BLK_DEV_RZ1000
 	{PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, NULL, NULL,	ide_init_rz1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
diff -urN linux-2.5.7-pre2/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.7-pre2/drivers/ide/ide-taskfile.c	Tue Mar 19 03:32:12 2002
+++ linux/drivers/ide/ide-taskfile.c	Tue Mar 19 03:26:14 2002
@@ -48,7 +48,7 @@
 	if (rq->bio)
 		return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
 	else
-		return rq->buffer + task_rq_offset(rq);
+		return rq->buffer + ((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE;
 }
 
 static inline void ide_unmap_rq(struct request *rq, char *to,
@@ -341,27 +341,37 @@
 	pBuf = ide_map_rq(rq, &flags);
 	DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
 		pBuf, nsect, rq->current_nr_sectors);
+
 	drive->io_32bit = 0;
 	taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
+
 	ide_unmap_rq(rq, pBuf, &flags);
+
 	drive->io_32bit = io_32bit;
+
 	rq->errors = 0;
 	/* Are we sure that this as all been already transfered? */
 	rq->current_nr_sectors -= nsect;
+
 	if (hwgroup->handler == NULL)
 		ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
+
 	return ide_started;
 }
 
-ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
+ide_startstop_t ata_taskfile(ide_drive_t *drive,
+		struct hd_drive_task_hdr *taskfile,
+		struct hd_drive_hob_hdr *hobfile,
+		ide_handler_t *handler,
+		ide_pre_handler_t *prehandler,
+		struct request *rq
+		)
 {
-	task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
-	hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
 	struct hd_driveid *id = drive->id;
-	byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
+	u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
 
 	/* (ks/hs): Moved to start, do not use for multiple out commands */
-	if (task->handler != task_mulout_intr && task->handler != bio_mulout_intr) {
+	if (handler != task_mulout_intr && handler != bio_mulout_intr) {
 		if (IDE_CONTROL_REG)
 			OUT_BYTE(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */
 		SELECT_MASK(HWIF(drive), drive, 0);
@@ -386,17 +396,16 @@
 	OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
 
 	OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
-	if (task->handler != NULL) {
-		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
+	if (handler != NULL) {
+		ide_set_handler(drive, handler, WAIT_CMD, NULL);
 		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
 		/*
 		 * Warning check for race between handler and prehandler for
 		 * writing first block of data.  however since we are well
 		 * inside the boundaries of the seek, we should be okay.
 		 */
-		if (task->prehandler != NULL) {
-			return task->prehandler(drive, task->rq);
-		}
+		if (prehandler != NULL)
+			return prehandler(drive, rq);
 	} else {
 		/* for dma commands we down set the handler */
 		if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
@@ -405,48 +414,6 @@
 	return ide_started;
 }
 
-void do_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile,
-		struct hd_drive_hob_hdr *hobfile,
-		ide_handler_t *handler)
-{
-	struct hd_driveid *id = drive->id;
-	byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
-
-	/* (ks/hs): Moved to start, do not use for multiple out commands */
-	if (*handler != task_mulout_intr && handler != bio_mulout_intr) {
-		if (IDE_CONTROL_REG)
-			OUT_BYTE(drive->ctl, IDE_CONTROL_REG);  /* clear nIEN */
-		SELECT_MASK(HWIF(drive), drive, 0);
-	}
-
-	if ((id->command_set_2 & 0x0400) &&
-	    (id->cfs_enable_2 & 0x0400) &&
-	    (drive->addressing == 1)) {
-		OUT_BYTE(hobfile->feature, IDE_FEATURE_REG);
-		OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG);
-		OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG);
-		OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG);
-		OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG);
-	}
-
-	OUT_BYTE(taskfile->feature, IDE_FEATURE_REG);
-	OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG);
-	/* refers to number of sectors to transfer */
-	OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG);
-	/* refers to sector offset or start sector */
-	OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG);
-	OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
-
-	OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
-	if (handler != NULL) {
-		ide_set_handler (drive, handler, WAIT_CMD, NULL);
-		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
-	} else {
-		/* for dma commands we down set the handler */
-		if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
-	}
-}
-
 /*
  * This is invoked on completion of a WIN_SETMULT cmd.
  */
@@ -1162,8 +1129,7 @@
 EXPORT_SYMBOL(atapi_output_bytes);
 EXPORT_SYMBOL(taskfile_input_data);
 EXPORT_SYMBOL(taskfile_output_data);
-EXPORT_SYMBOL(do_rw_taskfile);
-EXPORT_SYMBOL(do_taskfile);
+EXPORT_SYMBOL(ata_taskfile);
 
 EXPORT_SYMBOL(recal_intr);
 EXPORT_SYMBOL(set_geometry_intr);
diff -urN linux-2.5.7-pre2/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.7-pre2/drivers/ide/ide.c	Mon Mar 18 16:15:28 2002
+++ linux/drivers/ide/ide.c	Tue Mar 19 03:14:40 2002
@@ -978,7 +978,7 @@
  * setting a timer to wake up at half second intervals thereafter,
  * until timeout is achieved, before timing out.
  */
-int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
+int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
 	byte stat;
 	int i;
 	unsigned long flags;
@@ -1020,90 +1020,6 @@
 }
 
 /*
- * execute_drive_cmd() issues a special drive command,
- * usually initiated by ioctl() from the external hdparm program.
- */
-static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
-{
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *args = rq->special;
-
-		if (!(args))
-			goto args_error;
-
-		do_taskfile(drive,
-				(struct hd_drive_task_hdr *)&args->tfRegister,
-				(struct hd_drive_hob_hdr *)&args->hobRegister,
-				args->handler);
-
-		if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
-		     (args->command_type == IDE_DRIVE_TASK_OUT)) &&
-		      args->prehandler && args->handler)
-			return args->prehandler(drive, rq);
-		return ide_started;
-
-	} else if (rq->flags & REQ_DRIVE_TASK) {
-		byte *args = rq->buffer;
-		byte sel;
-
-		if (!(args)) goto args_error;
-#ifdef DEBUG
-			printk("%s: DRIVE_TASK_CMD ", drive->name);
-			printk("cmd=0x%02x ", args[0]);
-			printk("fr=0x%02x ", args[1]);
-			printk("ns=0x%02x ", args[2]);
-			printk("sc=0x%02x ", args[3]);
-			printk("lcyl=0x%02x ", args[4]);
-			printk("hcyl=0x%02x ", args[5]);
-			printk("sel=0x%02x\n", args[6]);
-#endif
-		OUT_BYTE(args[1], IDE_FEATURE_REG);
-		OUT_BYTE(args[3], IDE_SECTOR_REG);
-		OUT_BYTE(args[4], IDE_LCYL_REG);
-		OUT_BYTE(args[5], IDE_HCYL_REG);
-		sel = (args[6] & ~0x10);
-		if (drive->select.b.unit)
-			sel |= 0x10;
-		OUT_BYTE(sel, IDE_SELECT_REG);
-		ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
-		return ide_started;
-	} else if (rq->flags & REQ_DRIVE_CMD) {
-
-		byte *args = rq->buffer;
-		if (!(args)) goto args_error;
-#ifdef DEBUG
-		printk("%s: DRIVE_CMD ", drive->name);
-		printk("cmd=0x%02x ", args[0]);
-		printk("sc=0x%02x ", args[1]);
-		printk("fr=0x%02x ", args[2]);
-		printk("xx=0x%02x\n", args[3]);
-#endif
-		if (args[0] == WIN_SMART) {
-			OUT_BYTE(0x4f, IDE_LCYL_REG);
-			OUT_BYTE(0xc2, IDE_HCYL_REG);
-			OUT_BYTE(args[2],IDE_FEATURE_REG);
-			OUT_BYTE(args[1],IDE_SECTOR_REG);
-			ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
-			return ide_started;
-		}
-		OUT_BYTE(args[2],IDE_FEATURE_REG);
-		ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
-		return ide_started;
-	}
-
-args_error:
-	/*
-	 * NULL is actually a valid way of waiting for
-	 * all current requests to be flushed from the queue.
-	 */
-#ifdef DEBUG
-	printk("%s: DRIVE_CMD (null)\n", drive->name);
-#endif
-	ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
-	return ide_stopped;
-}
-
-/*
  * start_request() initiates handling of a new I/O request
  */
 static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
@@ -1150,9 +1066,100 @@
 		printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
 		return startstop;
 	}
+
+	/* FIXME: We can see nicely here that all commands should be submitted
+	 * through the request queue and that the special field in drive should
+	 * go as soon as possible!
+	 */
+
 	if (!drive->special.all) {
-		if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE))
-			return execute_drive_cmd(drive, rq);
+		if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+			/* This issues a special drive command, usually
+			 * initiated by ioctl() from the external hdparm
+			 * program.
+			 */
+
+			if (rq->flags & REQ_DRIVE_TASKFILE) {
+				ide_task_t *args = rq->special;
+
+				if (!(args))
+					goto args_error;
+
+				ata_taskfile(drive,
+						(struct hd_drive_task_hdr *)&args->tfRegister,
+						(struct hd_drive_hob_hdr *)&args->hobRegister,
+						args->handler, NULL, NULL);
+
+				if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
+							(args->command_type == IDE_DRIVE_TASK_OUT)) &&
+						args->prehandler && args->handler)
+					return args->prehandler(drive, rq);
+				return ide_started;
+
+			} else if (rq->flags & REQ_DRIVE_TASK) {
+				byte *args = rq->buffer;
+				byte sel;
+
+				if (!(args)) goto args_error;
+#ifdef DEBUG
+				printk("%s: DRIVE_TASK_CMD ", drive->name);
+				printk("cmd=0x%02x ", args[0]);
+				printk("fr=0x%02x ", args[1]);
+				printk("ns=0x%02x ", args[2]);
+				printk("sc=0x%02x ", args[3]);
+				printk("lcyl=0x%02x ", args[4]);
+				printk("hcyl=0x%02x ", args[5]);
+				printk("sel=0x%02x\n", args[6]);
+#endif
+				OUT_BYTE(args[1], IDE_FEATURE_REG);
+				OUT_BYTE(args[3], IDE_SECTOR_REG);
+				OUT_BYTE(args[4], IDE_LCYL_REG);
+				OUT_BYTE(args[5], IDE_HCYL_REG);
+				sel = (args[6] & ~0x10);
+				if (drive->select.b.unit)
+					sel |= 0x10;
+				OUT_BYTE(sel, IDE_SELECT_REG);
+				ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
+				return ide_started;
+			} else if (rq->flags & REQ_DRIVE_CMD) {
+				byte *args = rq->buffer;
+				if (!(args)) goto args_error;
+#ifdef DEBUG
+				printk("%s: DRIVE_CMD ", drive->name);
+				printk("cmd=0x%02x ", args[0]);
+				printk("sc=0x%02x ", args[1]);
+				printk("fr=0x%02x ", args[2]);
+				printk("xx=0x%02x\n", args[3]);
+#endif
+				if (args[0] == WIN_SMART) {
+					OUT_BYTE(0x4f, IDE_LCYL_REG);
+					OUT_BYTE(0xc2, IDE_HCYL_REG);
+					OUT_BYTE(args[2],IDE_FEATURE_REG);
+					OUT_BYTE(args[1],IDE_SECTOR_REG);
+					ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
+
+					return ide_started;
+				}
+				OUT_BYTE(args[2],IDE_FEATURE_REG);
+				ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
+				return ide_started;
+			}
+
+args_error:
+			/*
+			 * NULL is actually a valid way of waiting for all
+			 * current requests to be flushed from the queue.
+			 */
+#ifdef DEBUG
+			printk("%s: DRIVE_CMD (null)\n", drive->name);
+#endif
+			ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
+			return ide_stopped;
+		}
+
+		/* The normal way of execution is to pass execute the request
+		 * handler.
+		 */
 
 		if (ata_ops(drive)) {
 			if (ata_ops(drive)->do_request)
@@ -1699,31 +1706,29 @@
 }
 
 /*
- * This function issues a special IDE device request
- * onto the request queue.
+ * This function issues a special IDE device request onto the request queue.
  *
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
+ * If action is ide_wait, then the rq is queued at the end of the request
+ * queue, and the function sleeps until it has been processed.  This is for use
+ * when invoked from an ioctl handler.
  *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed.  This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
+ * If action is ide_preempt, then the rq is queued at the head of the request
+ * queue, displacing the currently-being-processed request and this function
+ * returns immediately without waiting for the new rq to be completed.  This is
+ * VERY DANGEROUS, and is intended for careful use by the ATAPI tape/cdrom
+ * driver code.
  *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed.  As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
+ * If action is ide_next, then the rq is queued immediately after the
+ * currently-being-processed-request (if any), and the function returns without
+ * waiting for the new rq to be completed.  As above, This is VERY DANGEROUS,
+ * and is intended for careful use by the ATAPI tape/cdrom driver code.
  *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
+ * If action is ide_end, then the rq is queued at the end of the request queue,
+ * and the function returns immediately without waiting for the new rq to be
+ * completed. This is again intended for careful use by the ATAPI tape/cdrom
+ * driver code.
  */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action)
+int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action)
 {
 	unsigned long flags;
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
@@ -2403,7 +2408,7 @@
 	ide_init_drive_cmd(&rq);
 	drive->tune_req = (byte) arg;
 	drive->special.b.set_tune = 1;
-	(void) ide_do_drive_cmd (drive, &rq, ide_wait);
+	ide_do_drive_cmd(drive, &rq, ide_wait);
 	return 0;
 }
 
diff -urN linux-2.5.7-pre2/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.5.7-pre2/drivers/ide/pdc202xx.c	Mon Mar 18 16:15:28 2002
+++ linux/drivers/ide/pdc202xx.c	Tue Mar 19 00:49:59 2002
@@ -217,6 +217,9 @@
 		case PCI_DEVICE_ID_PROMISE_20275:
 			p += sprintf(p, "\n                                PDC20275 Chipset.\n");
 			break;
+		case PCI_DEVICE_ID_PROMISE_20276:
+			p += sprintf(p, "\n                                PDC20276 Chipset.\n");
+			break;
 		case PCI_DEVICE_ID_PROMISE_20269:
 			p += sprintf(p, "\n                                PDC20269 TX2 Chipset.\n");
 			break;
@@ -236,6 +239,7 @@
 	char *p = buffer;
 	switch(bmide_dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268:
 		case PCI_DEVICE_ID_PROMISE_20268R:
@@ -732,6 +736,7 @@
 
 	switch(dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 			udma_133 = (udma_66) ? 1 : 0;
 			udma_100 = (udma_66) ? 1 : 0;
@@ -989,6 +994,7 @@
 
 	switch (dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268R:
 		case PCI_DEVICE_ID_PROMISE_20268:
@@ -1121,6 +1127,7 @@
 
 	switch (dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268R:
 		case PCI_DEVICE_ID_PROMISE_20268:
@@ -1215,6 +1222,7 @@
 
         switch(hwif->pci_dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268:
 		case PCI_DEVICE_ID_PROMISE_20268R:
@@ -1233,6 +1241,7 @@
 
         switch(hwif->pci_dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268:
 		case PCI_DEVICE_ID_PROMISE_20268R:
diff -urN linux-2.5.7-pre2/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- linux-2.5.7-pre2/drivers/pci/pci.ids	Tue Mar 19 03:32:12 2002
+++ linux/drivers/pci/pci.ids	Tue Mar 19 00:55:59 2002
@@ -1108,12 +1108,14 @@
 1059  Teknor Industrial Computers Inc
 105a  Promise Technology, Inc.
 	0d30  20265
+	1275  20275
 	4d30  20267
 	4d33  20246
 	4d38  20262
 	4d68  20268
 	6268  20268R
 	4d69  20269
+	5275  20276
 	5300  DC5300
 105b  Foxconn International, Inc.
 105c  Wipro Infotech Limited
diff -urN linux-2.5.7-pre2/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.7-pre2/include/linux/ide.h	Tue Mar 19 03:32:12 2002
+++ linux/include/linux/ide.h	Tue Mar 19 03:21:55 2002
@@ -771,35 +771,7 @@
  */
 #define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
 
-#define task_rq_offset(rq) \
-	(((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE)
-
-/*
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
- *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed.  This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
- *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed.  As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
- */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action);
+extern int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action);
 
 /*
  * Clean up after success/failure of an explicit drive cmd.
@@ -827,15 +799,12 @@
 void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
 void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
 
-/*
- * taskfile io for disks for now...
- */
-ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task);
-
-/*
- * Builds request from ide_ioctl
- */
-void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, ide_handler_t *handler);
+extern ide_startstop_t ata_taskfile(ide_drive_t *drive,
+		struct hd_drive_task_hdr *taskfile,
+		struct hd_drive_hob_hdr *hobfile,
+		ide_handler_t *handler,
+		ide_pre_handler_t *prehandler,
+		struct request *rq);
 
 /*
  * Special Flagged Register Validation Caller
@@ -871,7 +840,7 @@
  * idedisk_input_data() is a wrapper around ide_input_data() which copes
  * with byte-swapping the input data if required.
  */
-inline void idedisk_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
+extern void idedisk_input_data(ide_drive_t *drive, void *buffer, unsigned int wcount);
 
 /*
  * ide_stall_queue() can be used by a drive to give excess bandwidth back
diff -urN linux-2.5.7-pre2/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- linux-2.5.7-pre2/include/linux/pci_ids.h	Tue Mar 19 03:32:12 2002
+++ linux/include/linux/pci_ids.h	Tue Mar 19 00:44:14 2002
@@ -608,6 +608,7 @@
 #define PCI_DEVICE_ID_PROMISE_20268R	0x6268
 #define PCI_DEVICE_ID_PROMISE_20269	0x4d69
 #define PCI_DEVICE_ID_PROMISE_20275	0x1275
+#define PCI_DEVICE_ID_PROMISE_20276	0x5275
 #define PCI_DEVICE_ID_PROMISE_5300	0x5300
 
 #define PCI_VENDOR_ID_N9		0x105d

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

* PATCH 2.5.7 IDE 24
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
  2002-03-18 21:57 ` Xavier Bestel
  2002-03-28  9:21 ` [PATCH] 2.5.7 IDE 23 Martin Dalecki
@ 2002-03-28  9:23 ` Martin Dalecki
  2002-03-28  9:29   ` Zwane Mwaikambo
  2002-03-28  9:25 ` [PATCH] 2.5.7 IDE 25 Martin Dalecki
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-03-28  9:23 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Tue Mar 19 22:39:10 CET 2002 ide-clean-24

- Push BAD_DMA_DRIVE and GOOD_DMA_DRIVE to the ide-pmac.c file, since this is
   the only place where those get used.

- Kill unused fields from the ide_task_s structure. In esp. we pass a task
   attached to a request and not the other way around!

- Rename hwif field to channel in struct ide_drive_s.

- Move the request queue to the level where proper serialization has to happen
   anyway - the channel structure.

[-- Attachment #2: ide-clean-24.diff --]
[-- Type: text/plain, Size: 11795 bytes --]

diff -urN linux-2.5.7/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.7/drivers/ide/ide-disk.c	Wed Mar 20 01:32:05 2002
+++ linux/drivers/ide/ide-disk.c	Wed Mar 20 00:20:27 2002
@@ -189,8 +189,6 @@
 	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
 	memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
 	ide_cmd_type_parser(&args);
-	args.rq	= rq;
-	args.block = block;
 	rq->special = &args;
 
 	return ata_taskfile(drive,
@@ -198,7 +196,7 @@
 			(struct hd_drive_hob_hdr *) &args.hobRegister,
 			args.handler,
 			args.prehandler,
-			args.rq);
+			rq);
 }
 
 static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
@@ -235,8 +233,6 @@
 	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
 	memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
 	ide_cmd_type_parser(&args);
-	args.rq = rq;
-	args.block = block;
 	rq->special = &args;
 
 	return ata_taskfile(drive,
@@ -244,7 +240,7 @@
 			(struct hd_drive_hob_hdr *) &args.hobRegister,
 			args.handler,
 			args.prehandler,
-			args.rq);
+			rq);
 }
 
 /*
@@ -298,8 +294,6 @@
 	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
 	memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
 	ide_cmd_type_parser(&args);
-	args.rq = rq;
-	args.block = block;
 	rq->special = &args;
 
 	return ata_taskfile(drive,
@@ -307,7 +301,7 @@
 			(struct hd_drive_hob_hdr *) &args.hobRegister,
 			args.handler,
 			args.prehandler,
-			args.rq);
+			rq);
 }
 
 /*
diff -urN linux-2.5.7/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.7/drivers/ide/ide-pmac.c	Mon Mar 18 21:37:17 2002
+++ linux/drivers/ide/ide-pmac.c	Tue Mar 19 22:38:11 2002
@@ -71,6 +71,9 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 
+# define BAD_DMA_DRIVE		0
+# define GOOD_DMA_DRIVE		1
+
 typedef struct {
 	int	accessTime;
 	int	cycleTime;
diff -urN linux-2.5.7/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.7/drivers/ide/ide-taskfile.c	Wed Mar 20 01:32:05 2002
+++ linux/drivers/ide/ide-taskfile.c	Tue Mar 19 23:59:50 2002
@@ -927,7 +927,7 @@
 /*
  * This function is intended to be used prior to invoking ide_do_drive_cmd().
  */
-static void ide_init_drive_taskfile (struct request *rq)
+static void init_taskfile_request(struct request *rq)
 {
 	memset(rq, 0, sizeof(*rq));
 	rq->flags = REQ_DRIVE_TASKFILE;
@@ -935,11 +935,12 @@
 
 /*
  * This is kept for internal use only !!!
- * This is an internal call and nobody in user-space has a damn
+ * This is an internal call and nobody in user-space has a
  * reason to call this taskfile.
  *
  * ide_raw_taskfile is the one that user-space executes.
  */
+
 int ide_wait_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf)
 {
 	struct request rq;
@@ -965,7 +966,8 @@
 	args.hobRegister[IDE_SELECT_OFFSET_HOB]  = hobfile->device_head;
 	args.hobRegister[IDE_CONTROL_OFFSET_HOB] = hobfile->control;
 
-	ide_init_drive_taskfile(&rq);
+	init_taskfile_request(&rq);
+
 	/* This is kept for internal use only !!! */
 	ide_cmd_type_parser(&args);
 	if (args.command_type != IDE_DRIVE_TASK_NO_DATA)
@@ -973,59 +975,26 @@
 
 	rq.buffer = buf;
 	rq.special = &args;
+
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
 int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *args, byte *buf)
 {
 	struct request rq;
-	ide_init_drive_taskfile(&rq);
+	init_taskfile_request(&rq);
 	rq.buffer = buf;
 
 	if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
 		rq.current_nr_sectors = rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET_HOB] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET];
 
 	rq.special = args;
+
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
 /*
- *  The taskfile glue table
- *
- *  reqtask.data_phase	reqtask.req_cmd
- *			args.command_type		args.handler
- *
- *  TASKFILE_P_OUT_DMAQ	??				??
- *  TASKFILE_P_IN_DMAQ	??				??
- *  TASKFILE_P_OUT_DMA	??				??
- *  TASKFILE_P_IN_DMA	??				??
- *  TASKFILE_P_OUT	??				??
- *  TASKFILE_P_IN	??				??
- *
- *  TASKFILE_OUT_DMAQ	IDE_DRIVE_TASK_RAW_WRITE	NULL
- *  TASKFILE_IN_DMAQ	IDE_DRIVE_TASK_IN		NULL
- *
- *  TASKFILE_OUT_DMA	IDE_DRIVE_TASK_RAW_WRITE	NULL
- *  TASKFILE_IN_DMA	IDE_DRIVE_TASK_IN		NULL
- *
- *  TASKFILE_IN_OUT	??				??
- *
- *  TASKFILE_MULTI_OUT	IDE_DRIVE_TASK_RAW_WRITE	task_mulout_intr
- *  TASKFILE_MULTI_IN	IDE_DRIVE_TASK_IN		task_mulin_intr
- *
- *  TASKFILE_OUT	IDE_DRIVE_TASK_RAW_WRITE	task_out_intr
- *  TASKFILE_OUT	IDE_DRIVE_TASK_OUT		task_out_intr
- *
- *  TASKFILE_IN		IDE_DRIVE_TASK_IN		task_in_intr
- *  TASKFILE_NO_DATA	IDE_DRIVE_TASK_NO_DATA		task_no_data_intr
- *
- *			IDE_DRIVE_TASK_SET_XFER		task_no_data_intr
- *			IDE_DRIVE_TASK_INVALID
- *
- */
-
-/*
- * Issue ATA command and wait for completion. use for implementing commands in
+ * Issue ATA command and wait for completion. Use for implementing commands in
  * kernel.
  *
  * The caller has to make sure buf is never NULL!
diff -urN linux-2.5.7/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.7/drivers/ide/ide.c	Wed Mar 20 01:32:05 2002
+++ linux/drivers/ide/ide.c	Wed Mar 20 01:19:21 2002
@@ -288,7 +288,7 @@
 
 		drive->type			= ATA_DISK;
 		drive->select.all		= (unit<<4)|0xa0;
-		drive->hwif			= hwif;
+		drive->channel			= hwif;
 		drive->ctl			= 0x08;
 		drive->ready_stat		= READY_STAT;
 		drive->bad_wstat		= BAD_W_STAT;
@@ -737,11 +737,6 @@
 		ide_task_t *args = (ide_task_t *) rq->special;
 		rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
 		if (args) {
-			if (args->tf_in_flags.b.data) {
-				unsigned short data			= IN_WORD(IDE_DATA_REG);
-				args->tfRegister[IDE_DATA_OFFSET]	= (data) & 0xFF;
-				args->hobRegister[IDE_DATA_OFFSET_HOB]	= (data >> 8) & 0xFF;
-			}
 			args->tfRegister[IDE_ERROR_OFFSET]   = err;
 			args->tfRegister[IDE_NSECTOR_OFFSET] = IN_BYTE(IDE_NSECTOR_REG);
 			args->tfRegister[IDE_SECTOR_OFFSET]  = IN_BYTE(IDE_SECTOR_REG);
diff -urN linux-2.5.7/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.5.7/drivers/ide/pdc202xx.c	Wed Mar 20 01:32:05 2002
+++ linux/drivers/ide/pdc202xx.c	Wed Mar 20 00:08:25 2002
@@ -664,6 +664,7 @@
 			OUT_BYTE(0xac, datareg);
 			break;
 		default:
+			;
 	}
 
 	if (!drive->init_speed)
diff -urN linux-2.5.7/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c
--- linux-2.5.7/drivers/ide/pdc4030.c	Mon Mar 18 21:37:08 2002
+++ linux/drivers/ide/pdc4030.c	Wed Mar 20 00:17:41 2002
@@ -658,9 +658,6 @@
 	/* We don't use the generic inerrupt handlers here? */
 	args.prehandler		= NULL;
 	args.handler		= NULL;
-	args.rq			= rq;
-	args.block		= block;
-	rq->special		= NULL;
 	rq->special		= &args;
 
 	return do_pdc4030_io(drive, &args);
diff -urN linux-2.5.7/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.7/include/linux/ide.h	Wed Mar 20 01:32:05 2002
+++ linux/include/linux/ide.h	Wed Mar 20 01:19:34 2002
@@ -68,7 +68,7 @@
  */
 #define DMA_PIO_RETRY	1	/* retrying in PIO */
 
-#define HWIF(drive)		((drive)->hwif)
+#define HWIF(drive)		((drive)->channel)
 #define HWGROUP(drive)		(HWIF(drive)->hwgroup)
 
 /*
@@ -175,17 +175,17 @@
 #define WAIT_CMD	(10*HZ)		/* 10sec  - maximum wait for an IRQ to happen */
 #define WAIT_MIN_SLEEP	(2*HZ/100)	/* 20msec - minimum sleep time */
 
-#define SELECT_DRIVE(hwif,drive)				\
+#define SELECT_DRIVE(channel, drive)				\
 {								\
-	if (hwif->selectproc)					\
-		hwif->selectproc(drive);			\
-	OUT_BYTE((drive)->select.all, hwif->io_ports[IDE_SELECT_OFFSET]); \
+	if (channel->selectproc)				\
+		channel->selectproc(drive);			\
+	OUT_BYTE((drive)->select.all, channel->io_ports[IDE_SELECT_OFFSET]); \
 }
 
-#define SELECT_MASK(hwif,drive,mask)				\
+#define SELECT_MASK(channel, drive, mask)			\
 {								\
-	if (hwif->maskproc)					\
-		hwif->maskproc(drive,mask);			\
+	if (channel->maskproc)					\
+		channel->maskproc(drive,mask);			\
 }
 
 /*
@@ -235,7 +235,6 @@
 	int		irq;			/* our irq number */
 	int		dma;			/* our dma entry */
 	ide_ack_intr_t	*ack_intr;		/* acknowledge interrupt */
-	void		*priv;			/* interface specific data */
 	hwif_chipset_t  chipset;
 } hw_regs_t;
 
@@ -291,6 +290,8 @@
 struct ide_settings_s;
 
 typedef struct ide_drive_s {
+	struct hwif_s   *channel;	/* parent pointer to the channel we are attached to  */
+
 	unsigned int	usage;		/* current "open()" count for drive */
 	char type; /* distingiush different devices: disk, cdrom, tape, floppy, ... */
 
@@ -339,8 +340,8 @@
 	byte		ctl;		/* "normal" value for IDE_CONTROL_REG */
 	byte		ready_stat;	/* min status value for drive ready */
 	byte		mult_count;	/* current multiple sector setting */
-	byte 		mult_req;	/* requested multiple sector setting */
-	byte 		tune_req;	/* requested drive tuning setting */
+	byte		mult_req;	/* requested multiple sector setting */
+	byte		tune_req;	/* requested drive tuning setting */
 	byte		io_32bit;	/* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
 	byte		bad_wstat;	/* used for ignoring WRERR_STAT */
 	byte		nowerr;		/* used for ignoring WRERR_STAT */
@@ -354,20 +355,25 @@
 	unsigned long	capacity;	/* total number of sectors */
 	unsigned long long capacity48;	/* total number of sectors */
 	unsigned int	drive_data;	/* for use by tuneproc/selectproc as needed */
-	struct hwif_s   *hwif;		/* parent pointer to the interface we are attached to  */
+
 	wait_queue_head_t wqueue;	/* used to wait for drive in open() */
+
 	struct hd_driveid *id;		/* drive model identification info */
 	struct hd_struct  *part;	/* drive partition table */
+
 	char		name[4];	/* drive name, such as "hda" */
 	struct ata_operations *driver;
+
 	void		*driver_data;	/* extra driver data */
 	devfs_handle_t	de;		/* directory for device */
 	struct proc_dir_entry *proc;	/* /proc/ide/ directory entry */
 	struct ide_settings_s *settings;    /* /proc/ide/ drive settings */
 	char		driver_req[10];	/* requests specific driver */
+
 	int		last_lun;	/* last logical unit */
 	int		forced_lun;	/* if hdxlun was given at boot */
 	int		lun;		/* logical unit */
+
 	int		crc_count;	/* crc counter to reduce drive speed */
 	byte		quirk_list;	/* drive is considered quirky if set for a specific host */
 	byte		suspend_reset;	/* drive suspend mode flag, soft-reset recovers */
@@ -409,7 +415,7 @@
  *
  * If it is not defined for a controller, standard-code is used from ide.c.
  *
- * Controllers which are not memory-mapped in the standard way need to 
+ * Controllers which are not memory-mapped in the standard way need to
  * override that mechanism using this function to work.
  *
  */
@@ -478,7 +484,7 @@
 	struct proc_dir_entry *proc;	/* /proc/ide/ directory entry */
 	int		irq;		/* our irq number */
 	int		major;		/* our major number */
-	char		name[80];	/* name of interface */
+	char		name[8];	/* name of interface */
 	int		index;		/* 0 for ide0; 1 for ide1; ... */
 	hwif_chipset_t	chipset;	/* sub-module for tuning.. */
 	unsigned	noprobe    : 1;	/* don't probe for this interface */
@@ -781,15 +787,9 @@
 typedef struct ide_task_s {
 	task_ioreg_t		tfRegister[8];
 	task_ioreg_t		hobRegister[8];
-	ide_reg_valid_t		tf_out_flags;
-	ide_reg_valid_t		tf_in_flags;
-	int			data_phase;
 	int			command_type;
 	ide_pre_handler_t	*prehandler;
 	ide_handler_t		*handler;
-	void			*special;	/* valid_t generally */
-	struct request		*rq;		/* copy of request */
-	unsigned long		block;		/* copy of block */
 } ide_task_t;
 
 void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
@@ -908,8 +908,6 @@
 void __init ide_scan_pcibus(int scan_direction);
 #endif
 #ifdef CONFIG_BLK_DEV_IDEDMA
-# define BAD_DMA_DRIVE		0
-# define GOOD_DMA_DRIVE		1
 int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func);
 void ide_destroy_dmatable (ide_drive_t *drive);
 ide_startstop_t ide_dma_intr (ide_drive_t *drive);

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

* [PATCH] 2.5.7 IDE 25
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (2 preceding siblings ...)
  2002-03-28  9:23 ` PATCH 2.5.7 IDE 24 Martin Dalecki
@ 2002-03-28  9:25 ` Martin Dalecki
  2002-03-28  9:29 ` [PATCH] 2.5.7 IDE 26 Martin Dalecki
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-03-28  9:25 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Wed Mar 20 01:52:22 CET 2002 ide-clean-25

- Replace the task_io_reg_t with the simple u8. There is no need to obfuscate
   the code more then necessary.

- kill some unnecessary type definitions out from hdreg.h.

- Add proper attributes to register files in hdreg.h.

- Don't use raw arrays for tfRegister and hobRegister in ide_task_s.  Use out
   nice global structures describing the fields in them.  This allows to kill
   the following defines:

     IDE_DATA_OFFSET
     IDE_FEATURE_OFFSET
     IDE_NSECTOR_OFFSET
     IDE_SECTOR_OFFSET
     IDE_LCYL_OFFSET
     IDE_HCYL_OFFSET
     IDE_SELECT_OFFSET
     IDE_COMMAND_OFFSET

   and many many others.

- Please have a look at the following in pdc4030.c. It couldn't have worked!
   This has been fixed in one go with the above change:

   memcpy(args.hobRegister, NULL, sizeof(struct hd_drive_hob_hdr));

- Kill the redundant *_REG_HOB definitions. They don't help readability in any
   way.

[-- Attachment #2: ide-clean-25.diff --]
[-- Type: text/plain, Size: 29036 bytes --]

diff -urN linux-2.5.7/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.7/drivers/ide/ide-disk.c	Wed Mar 20 03:28:37 2002
+++ linux/drivers/ide/ide-disk.c	Wed Mar 20 03:10:27 2002
@@ -106,7 +106,7 @@
 	return 0;	/* lba_capacity value may be bad */
 }
 
-static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
+static u8 get_command(ide_drive_t *drive, int cmd)
 {
 	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
 
@@ -162,17 +162,19 @@
 	unsigned int head	= (track % drive->head);
 	unsigned int cyl	= (track / drive->head);
 
-	memset(&taskfile, 0, sizeof(task_struct_t));
-	memset(&hobfile, 0, sizeof(hob_struct_t));
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 
 	sectors = rq->nr_sectors;
 	if (sectors == 256)
 		sectors = 0;
 
 	taskfile.sector_count	= sectors;
+
 	taskfile.sector_number	= sect;
 	taskfile.low_cylinder	= cyl;
 	taskfile.high_cylinder	= (cyl>>8);
+
 	taskfile.device_head	= head;
 	taskfile.device_head	|= drive->select.all;
 	taskfile.command	=  get_command(drive, rq_data_dir(rq));
@@ -186,14 +188,14 @@
 	printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
 #endif
 
-	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
-	memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
+	args.taskfile = taskfile;
+	args.hobfile = hobfile;
 	ide_cmd_type_parser(&args);
 	rq->special = &args;
 
 	return ata_taskfile(drive,
-			(struct hd_drive_task_hdr *) &args.tfRegister,
-			(struct hd_drive_hob_hdr *) &args.hobRegister,
+			&args.taskfile,
+			&args.hobfile,
 			args.handler,
 			args.prehandler,
 			rq);
@@ -210,14 +212,16 @@
 	if (sectors == 256)
 		sectors = 0;
 
-	memset(&taskfile, 0, sizeof(task_struct_t));
-	memset(&hobfile, 0, sizeof(hob_struct_t));
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 
 	taskfile.sector_count	= sectors;
 	taskfile.sector_number	= block;
-	taskfile.low_cylinder	= (block>>=8);
-	taskfile.high_cylinder	= (block>>=8);
-	taskfile.device_head	= ((block>>8)&0x0f);
+	taskfile.low_cylinder	= (block >>= 8);
+
+	taskfile.high_cylinder	= (block >>= 8);
+
+	taskfile.device_head	= ((block >> 8) & 0x0f);
 	taskfile.device_head	|= drive->select.all;
 	taskfile.command	= get_command(drive, rq_data_dir(rq));
 
@@ -230,14 +234,14 @@
 	printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
 #endif
 
-	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
-	memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
+	args.taskfile = taskfile;
+	args.hobfile = hobfile;
 	ide_cmd_type_parser(&args);
 	rq->special = &args;
 
 	return ata_taskfile(drive,
-			(struct hd_drive_task_hdr *) &args.tfRegister,
-			(struct hd_drive_hob_hdr *) &args.hobRegister,
+			&args.taskfile,
+			&args.hobfile,
 			args.handler,
 			args.prehandler,
 			rq);
@@ -256,8 +260,8 @@
 	ide_task_t			args;
 	int				sectors;
 
-	memset(&taskfile, 0, sizeof(task_struct_t));
-	memset(&hobfile, 0, sizeof(hob_struct_t));
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 
 	sectors = rq->nr_sectors;
 	if (sectors == 65536)
@@ -271,12 +275,14 @@
 		hobfile.sector_count	= 0x00;
 	}
 
-	taskfile.sector_number	= block;	/* low lba */
-	taskfile.low_cylinder	= (block>>=8);	/* mid lba */
-	taskfile.high_cylinder	= (block>>=8);	/* hi  lba */
-	hobfile.sector_number	= (block>>=8);	/* low lba */
-	hobfile.low_cylinder	= (block>>=8);	/* mid lba */
-	hobfile.high_cylinder	= (block>>=8);	/* hi  lba */
+	taskfile.sector_number	= block;		/* low lba */
+	taskfile.low_cylinder	= (block >>= 8);	/* mid lba */
+	taskfile.high_cylinder	= (block >>= 8);	/* hi  lba */
+
+	hobfile.sector_number	= (block >>= 8);	/* low lba */
+	hobfile.low_cylinder	= (block >>= 8);	/* mid lba */
+	hobfile.high_cylinder	= (block >>= 8);	/* hi  lba */
+
 	taskfile.device_head	= drive->select.all;
 	hobfile.device_head	= taskfile.device_head;
 	hobfile.control		= (drive->ctl|0x80);
@@ -291,14 +297,14 @@
 	printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
 #endif
 
-	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
-	memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
+	args.taskfile = taskfile;
+	args.hobfile = hobfile;
 	ide_cmd_type_parser(&args);
 	rq->special = &args;
 
 	return ata_taskfile(drive,
-			(struct hd_drive_task_hdr *) &args.tfRegister,
-			(struct hd_drive_hob_hdr *) &args.hobRegister,
+			&args.taskfile,
+			&args.hobfile,
 			args.handler,
 			args.prehandler,
 			rq);
@@ -355,6 +361,7 @@
 		memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 
 		check_disk_change(inode->i_rdev);
+
 		taskfile.command = WIN_DOORLOCK;
 
 		/*
@@ -376,9 +383,9 @@
 	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
 	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 	if (drive->id->cfs_enable_2 & 0x2400)
-		taskfile.command	= WIN_FLUSH_CACHE_EXT;
+		taskfile.command = WIN_FLUSH_CACHE_EXT;
 	else
-		taskfile.command	= WIN_FLUSH_CACHE;
+		taskfile.command = WIN_FLUSH_CACHE;
 	return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
 }
 
@@ -387,9 +394,12 @@
 	if (drive->removable && !drive->usage) {
 		struct hd_drive_task_hdr taskfile;
 		struct hd_drive_hob_hdr hobfile;
+
 		memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
 		memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+
 		invalidate_bdev(inode->i_bdev, 0);
+
 		taskfile.command = WIN_DOORUNLOCK;
 		if (drive->doorlocking &&
 		    ide_wait_taskfile(drive, &taskfile, &hobfile, NULL))
@@ -423,21 +433,23 @@
 
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_SELECT_OFFSET]	= 0x40;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_READ_NATIVE_MAX;
-	args.handler				= task_no_data_intr;
+	args.taskfile.device_head = 0x40;
+	args.taskfile.command = WIN_READ_NATIVE_MAX;
+	args.handler = task_no_data_intr;
 
 	/* submit command request */
 	ide_raw_taskfile(drive, &args, NULL);
 
 	/* if OK, compute maximum address value */
-	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
-		addr = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24)
-		     | ((args.tfRegister[  IDE_HCYL_OFFSET]       ) << 16)
-		     | ((args.tfRegister[  IDE_LCYL_OFFSET]       ) <<  8)
-		     | ((args.tfRegister[IDE_SECTOR_OFFSET]       ));
+	if ((args.taskfile.command & 0x01) == 0) {
+		addr = ((args.taskfile.device_head & 0x0f) << 24)
+		     | (args.taskfile.high_cylinder << 16)
+		     | (args.taskfile.low_cylinder <<  8)
+		     | args.taskfile.sector_number;
 	}
+
 	addr++;	/* since the return value is (maxlba - 1), we add 1 */
+
 	return addr;
 }
 
@@ -449,24 +461,26 @@
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
 
-	args.tfRegister[IDE_SELECT_OFFSET]	= 0x40;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_READ_NATIVE_MAX_EXT;
-	args.handler				= task_no_data_intr;
+	args.taskfile.device_head = 0x40;
+	args.taskfile.command = WIN_READ_NATIVE_MAX_EXT;
+	args.handler = task_no_data_intr;
 
         /* submit command request */
         ide_raw_taskfile(drive, &args, NULL);
 
 	/* if OK, compute maximum address value */
-	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
-		u32 high = ((args.hobRegister[IDE_HCYL_OFFSET_HOB])<<16) |
-			   ((args.hobRegister[IDE_LCYL_OFFSET_HOB])<<8) |
-			    (args.hobRegister[IDE_SECTOR_OFFSET_HOB]);
-		u32 low  = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) |
-			   ((args.tfRegister[IDE_LCYL_OFFSET])<<8) |
-			    (args.tfRegister[IDE_SECTOR_OFFSET]);
+	if ((args.taskfile.command & 0x01) == 0) {
+		u32 high = (args.hobfile.high_cylinder << 16) |
+			   (args.hobfile.low_cylinder << 8) |
+			    args.hobfile.sector_number;
+		u32 low  = (args.taskfile.high_cylinder << 16) |
+			   (args.taskfile.low_cylinder << 8) |
+			    args.taskfile.sector_number;
 		addr = ((__u64)high << 24) | low;
 	}
+
 	addr++;	/* since the return value is (maxlba - 1), we add 1 */
+
 	return addr;
 }
 
@@ -483,20 +497,22 @@
 	addr_req--;
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_SECTOR_OFFSET]	= ((addr_req >>  0) & 0xff);
-	args.tfRegister[IDE_LCYL_OFFSET]	= ((addr_req >>  8) & 0xff);
-	args.tfRegister[IDE_HCYL_OFFSET]	= ((addr_req >> 16) & 0xff);
-	args.tfRegister[IDE_SELECT_OFFSET]	= ((addr_req >> 24) & 0x0f) | 0x40;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SET_MAX;
+
+	args.taskfile.sector_number = (addr_req >> 0);
+	args.taskfile.low_cylinder = (addr_req >> 8);
+	args.taskfile.high_cylinder = (addr_req >> 16);
+
+	args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
+	args.taskfile.command = WIN_SET_MAX;
 	args.handler				= task_no_data_intr;
 	/* submit command request */
 	ide_raw_taskfile(drive, &args, NULL);
 	/* if OK, read new maximum address value */
-	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
-		addr_set = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24)
-			 | ((args.tfRegister[  IDE_HCYL_OFFSET]       ) << 16)
-			 | ((args.tfRegister[  IDE_LCYL_OFFSET]       ) <<  8)
-			 | ((args.tfRegister[IDE_SECTOR_OFFSET]       ));
+	if ((args.taskfile.command & 0x01) == 0) {
+		addr_set = ((args.taskfile.device_head & 0x0f) << 24)
+			 | (args.taskfile.high_cylinder << 16)
+			 | (args.taskfile.low_cylinder <<  8)
+			 | args.taskfile.sector_number;
 	}
 	addr_set++;
 	return addr_set;
@@ -510,27 +526,31 @@
 	addr_req--;
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_SECTOR_OFFSET]	= ((addr_req >>  0) & 0xff);
-	args.tfRegister[IDE_LCYL_OFFSET]	= ((addr_req >>= 8) & 0xff);
-	args.tfRegister[IDE_HCYL_OFFSET]	= ((addr_req >>= 8) & 0xff);
-	args.tfRegister[IDE_SELECT_OFFSET]      = 0x40;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SET_MAX_EXT;
-	args.hobRegister[IDE_SECTOR_OFFSET_HOB]	= ((addr_req >>= 8) & 0xff);
-	args.hobRegister[IDE_LCYL_OFFSET_HOB]	= ((addr_req >>= 8) & 0xff);
-	args.hobRegister[IDE_HCYL_OFFSET_HOB]	= ((addr_req >>= 8) & 0xff);
-	args.hobRegister[IDE_SELECT_OFFSET_HOB]	= 0x40;
-	args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80);
+
+	args.taskfile.sector_number = (addr_req >>  0);
+	args.taskfile.low_cylinder = (addr_req >>= 8);
+	args.taskfile.high_cylinder = (addr_req >>= 8);
+	args.taskfile.device_head = 0x40;
+	args.taskfile.command = WIN_SET_MAX_EXT;
+
+	args.hobfile.sector_number = (addr_req >>= 8);
+	args.hobfile.low_cylinder = (addr_req >>= 8);
+	args.hobfile.high_cylinder = (addr_req >>= 8);
+
+	args.hobfile.device_head = 0x40;
+	args.hobfile.control = (drive->ctl | 0x80);
+
         args.handler				= task_no_data_intr;
 	/* submit command request */
 	ide_raw_taskfile(drive, &args, NULL);
 	/* if OK, compute maximum address value */
-	if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) {
-		u32 high = ((args.hobRegister[IDE_HCYL_OFFSET_HOB])<<16) |
-			   ((args.hobRegister[IDE_LCYL_OFFSET_HOB])<<8) |
-			    (args.hobRegister[IDE_SECTOR_OFFSET_HOB]);
-		u32 low  = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) |
-			   ((args.tfRegister[IDE_LCYL_OFFSET])<<8) |
-			    (args.tfRegister[IDE_SECTOR_OFFSET]);
+	if ((args.taskfile.command & 0x01) == 0) {
+		u32 high = (args.hobfile.high_cylinder << 16) |
+			   (args.hobfile.low_cylinder << 8) |
+			    args.hobfile.sector_number;
+		u32 low  = (args.taskfile.high_cylinder << 16) |
+			   (args.taskfile.low_cylinder << 8) |
+			    args.taskfile.sector_number;
 		addr_set = ((__u64)high << 24) | low;
 	}
 	return addr_set;
diff -urN linux-2.5.7/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.7/drivers/ide/ide-dma.c	Mon Mar 18 21:37:07 2002
+++ linux/drivers/ide/ide-dma.c	Wed Mar 20 02:44:47 2002
@@ -592,7 +592,7 @@
 			if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
 			    (drive->addressing == 1)) {
 				ide_task_t *args = HWGROUP(drive)->rq->special;
-				OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+				OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
 			} else if (drive->addressing) {
 				OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
 			} else {
diff -urN linux-2.5.7/drivers/ide/ide-features.c linux/drivers/ide/ide-features.c
--- linux-2.5.7/drivers/ide/ide-features.c	Mon Mar 18 21:37:17 2002
+++ linux/drivers/ide/ide-features.c	Wed Mar 20 03:03:34 2002
@@ -2,7 +2,7 @@
  * linux/drivers/block/ide-features.c	Version 0.04	June 9, 2000
  *
  *  Copyright (C) 1999-2000	Linus Torvalds & authors (see below)
- *  
+ *
  *  Copyright (C) 1999-2000	Andre Hedrick <andre@linux-ide.org>
  *
  *  Extracts if ide.c to address the evolving transfer rate code for
@@ -186,9 +186,9 @@
  */
 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->taskfile.command == WIN_SETFEATURES) &&
+	    (args->taskfile.sector_number > XFER_UDMA_2) &&
+	    (args->taskfile.feature == SETFEATURES_XFER)) {
 		if (!HWIF(drive)->udma_four) {
 			printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", HWIF(drive)->name);
 			return 1;
@@ -213,9 +213,9 @@
  */
 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->taskfile.command == WIN_SETFEATURES) &&
+	    (args->taskfile.sector_number >= XFER_SW_DMA_0) &&
+	    (args->taskfile.feature == SETFEATURES_XFER) &&
 	    (drive->id->dma_ultra ||
 	     drive->id->dma_mword ||
 	     drive->id->dma_1word))
diff -urN linux-2.5.7/drivers/ide/ide-geometry.c linux/drivers/ide/ide-geometry.c
--- linux-2.5.7/drivers/ide/ide-geometry.c	Mon Mar 18 21:37:03 2002
+++ linux/drivers/ide/ide-geometry.c	Wed Mar 20 02:03:29 2002
@@ -7,6 +7,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/types.h>
 #include <linux/ide.h>
 #include <linux/mc146818rtc.h>
 #include <asm/io.h>
diff -urN linux-2.5.7/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.7/drivers/ide/ide-taskfile.c	Wed Mar 20 03:28:37 2002
+++ linux/drivers/ide/ide-taskfile.c	Wed Mar 20 03:06:52 2002
@@ -534,8 +534,8 @@
 	}
 
 	/* (ks/hs): Fixed Multi Write */
-	if ((args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE) &&
-	    (args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE_EXT)) {
+	if ((args->taskfile.command != WIN_MULTWRITE) &&
+	    (args->taskfile.command != WIN_MULTWRITE_EXT)) {
 		unsigned long flags;
 		char *buf = ide_map_rq(rq, &flags);
 		/* For Write_sectors we need to stuff the first sector */
@@ -741,12 +741,12 @@
 /* Called by ioctl to feature out type of command being called */
 void ide_cmd_type_parser(ide_task_t *args)
 {
-	struct hd_drive_task_hdr *taskfile = (struct hd_drive_task_hdr *) args->tfRegister;
+	struct hd_drive_task_hdr *taskfile = &args->taskfile;
 
 	args->prehandler = NULL;
 	args->handler = NULL;
 
-	switch(args->tfRegister[IDE_COMMAND_OFFSET]) {
+	switch(args->taskfile.command) {
 		case WIN_IDENTIFY:
 		case WIN_PIDENTIFY:
 			args->handler = task_in_intr;
@@ -797,9 +797,11 @@
 		case WIN_SMART:
 			if (taskfile->feature == SMART_WRITE_LOG_SECTOR)
 				args->prehandler = pre_task_out_intr;
-			args->tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS;
-			args->tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS;
-			switch(args->tfRegister[IDE_FEATURE_OFFSET]) {
+
+			args->taskfile.low_cylinder = SMART_LCYL_PASS;
+			args->taskfile.high_cylinder = SMART_HCYL_PASS;
+
+			switch(args->taskfile.feature) {
 				case SMART_READ_VALUES:
 				case SMART_READ_THRESHOLDS:
 				case SMART_READ_LOG_SECTOR:
@@ -837,7 +839,7 @@
 #endif
 		case WIN_SETFEATURES:
 			args->handler = task_no_data_intr;
-			switch(args->tfRegister[IDE_FEATURE_OFFSET]) {
+			switch(args->taskfile.feature) {
 				case SETFEATURES_XFER:
 					args->command_type = IDE_DRIVE_TASK_SET_XFER;
 					return;
@@ -944,27 +946,13 @@
 int ide_wait_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf)
 {
 	struct request rq;
+	/* FIXME: This is on stack! */
 	ide_task_t args;
 
 	memset(&args, 0, sizeof(ide_task_t));
 
-	args.tfRegister[IDE_DATA_OFFSET]         = taskfile->data;
-	args.tfRegister[IDE_FEATURE_OFFSET]      = taskfile->feature;
-	args.tfRegister[IDE_NSECTOR_OFFSET]      = taskfile->sector_count;
-	args.tfRegister[IDE_SECTOR_OFFSET]       = taskfile->sector_number;
-	args.tfRegister[IDE_LCYL_OFFSET]         = taskfile->low_cylinder;
-	args.tfRegister[IDE_HCYL_OFFSET]         = taskfile->high_cylinder;
-	args.tfRegister[IDE_SELECT_OFFSET]       = taskfile->device_head;
-	args.tfRegister[IDE_COMMAND_OFFSET]      = taskfile->command;
-
-	args.hobRegister[IDE_DATA_OFFSET_HOB]    = hobfile->data;
-	args.hobRegister[IDE_FEATURE_OFFSET_HOB] = hobfile->feature;
-	args.hobRegister[IDE_NSECTOR_OFFSET_HOB] = hobfile->sector_count;
-	args.hobRegister[IDE_SECTOR_OFFSET_HOB]  = hobfile->sector_number;
-	args.hobRegister[IDE_LCYL_OFFSET_HOB]    = hobfile->low_cylinder;
-	args.hobRegister[IDE_HCYL_OFFSET_HOB]    = hobfile->high_cylinder;
-	args.hobRegister[IDE_SELECT_OFFSET_HOB]  = hobfile->device_head;
-	args.hobRegister[IDE_CONTROL_OFFSET_HOB] = hobfile->control;
+	args.taskfile = *taskfile;
+	args.hobfile = *hobfile;
 
 	init_taskfile_request(&rq);
 
@@ -986,7 +974,9 @@
 	rq.buffer = buf;
 
 	if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
-		rq.current_nr_sectors = rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET_HOB] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET];
+		rq.current_nr_sectors = rq.nr_sectors
+			= (args->hobfile.sector_count << 8)
+			| args->taskfile.sector_count;
 
 	rq.special = args;
 
@@ -1032,13 +1022,13 @@
 	if (copy_from_user(args, (void *)arg, 4))
 		return -EFAULT;
 
-	tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2];
-	tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3];
-	tfargs.tfRegister[IDE_SECTOR_OFFSET]  = args[1];
-	tfargs.tfRegister[IDE_LCYL_OFFSET]    = 0x00;
-	tfargs.tfRegister[IDE_HCYL_OFFSET]    = 0x00;
-	tfargs.tfRegister[IDE_SELECT_OFFSET]  = 0x00;
-	tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
+	tfargs.taskfile.feature = args[2];
+	tfargs.taskfile.sector_count = args[3];
+	tfargs.taskfile.sector_number = args[1];
+	tfargs.taskfile.low_cylinder = 0x00;
+	tfargs.taskfile.high_cylinder = 0x00;
+	tfargs.taskfile.device_head = 0x00;
+	tfargs.taskfile.command = args[0];
 
 	if (args[3]) {
 		argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
diff -urN linux-2.5.7/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.7/drivers/ide/ide.c	Wed Mar 20 03:28:37 2002
+++ linux/drivers/ide/ide.c	Wed Mar 20 03:17:31 2002
@@ -737,22 +737,25 @@
 		ide_task_t *args = (ide_task_t *) rq->special;
 		rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
 		if (args) {
-			args->tfRegister[IDE_ERROR_OFFSET]   = err;
-			args->tfRegister[IDE_NSECTOR_OFFSET] = IN_BYTE(IDE_NSECTOR_REG);
-			args->tfRegister[IDE_SECTOR_OFFSET]  = IN_BYTE(IDE_SECTOR_REG);
-			args->tfRegister[IDE_LCYL_OFFSET]    = IN_BYTE(IDE_LCYL_REG);
-			args->tfRegister[IDE_HCYL_OFFSET]    = IN_BYTE(IDE_HCYL_REG);
-			args->tfRegister[IDE_SELECT_OFFSET]  = IN_BYTE(IDE_SELECT_REG);
-			args->tfRegister[IDE_STATUS_OFFSET]  = stat;
+			args->taskfile.feature = err;
+			args->taskfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
+			args->taskfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
+			args->taskfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
+			args->taskfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
+			args->taskfile.device_head = IN_BYTE(IDE_SELECT_REG);
+			args->taskfile.command = stat;
 			if ((drive->id->command_set_2 & 0x0400) &&
 			    (drive->id->cfs_enable_2 & 0x0400) &&
 			    (drive->addressing == 1)) {
-				OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG_HOB);
-				args->hobRegister[IDE_FEATURE_OFFSET_HOB] = IN_BYTE(IDE_FEATURE_REG);
-				args->hobRegister[IDE_NSECTOR_OFFSET_HOB] = IN_BYTE(IDE_NSECTOR_REG);
-				args->hobRegister[IDE_SECTOR_OFFSET_HOB]  = IN_BYTE(IDE_SECTOR_REG);
-				args->hobRegister[IDE_LCYL_OFFSET_HOB]    = IN_BYTE(IDE_LCYL_REG);
-				args->hobRegister[IDE_HCYL_OFFSET_HOB]    = IN_BYTE(IDE_HCYL_REG);
+				/* The following command goes to the hob file! */
+
+				OUT_BYTE(drive->ctl|0x80, IDE_CONTROL_REG);
+				args->hobfile.feature = IN_BYTE(IDE_FEATURE_REG);
+				args->hobfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
+
+				args->hobfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
+				args->hobfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
+				args->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
 			}
 		}
 	}
@@ -1081,12 +1084,12 @@
 					goto args_error;
 
 				ata_taskfile(drive,
-						(struct hd_drive_task_hdr *)&args->tfRegister,
-						(struct hd_drive_hob_hdr *)&args->hobRegister,
+						&args->taskfile,
+						&args->hobfile,
 						args->handler, NULL, NULL);
 
 				if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
-							(args->command_type == IDE_DRIVE_TASK_OUT)) &&
+					(args->command_type == IDE_DRIVE_TASK_OUT)) &&
 						args->prehandler && args->handler)
 					return args->prehandler(drive, rq);
 				return ide_started;
diff -urN linux-2.5.7/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c
--- linux-2.5.7/drivers/ide/pdc4030.c	Wed Mar 20 03:28:37 2002
+++ linux/drivers/ide/pdc4030.c	Wed Mar 20 03:09:00 2002
@@ -549,8 +549,8 @@
  */
 ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
 {
-	struct request *rq	= HWGROUP(drive)->rq;
-	task_struct_t *taskfile	= (task_struct_t *) task->tfRegister;
+	struct request *rq = HWGROUP(drive)->rq;
+	struct hd_drive_task_hdr *taskfile = &task->taskfile;
 	unsigned long timeout;
 	byte stat;
 
@@ -652,8 +652,9 @@
 	taskfile.device_head	= ((block>>8)&0x0f)|drive->select.all;
 	taskfile.command	= (rq_data_dir(rq)==READ)?PROMISE_READ:PROMISE_WRITE;
 
-	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
-	memcpy(args.hobRegister, NULL, sizeof(struct hd_drive_hob_hdr));
+	args.taskfile = taskfile;
+	memset(&args.hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+
 	ide_cmd_type_parser(&args);
 	/* We don't use the generic inerrupt handlers here? */
 	args.prehandler		= NULL;
diff -urN linux-2.5.7/include/linux/hdreg.h linux/include/linux/hdreg.h
--- linux-2.5.7/include/linux/hdreg.h	Mon Mar 18 21:37:14 2002
+++ linux/include/linux/hdreg.h	Wed Mar 20 03:23:44 2002
@@ -54,16 +54,9 @@
  *	HDIO_DRIVE_CMD and HDIO_DRIVE_TASK
  */
 
-#if 0
-#include <asm/hdreg.h>
-typedef ide_ioreg_t task_ioreg_t;
-#else
-typedef unsigned char task_ioreg_t;
-#endif
-
-#define HDIO_DRIVE_CMD_HDR_SIZE		4*sizeof(task_ioreg_t)
-#define HDIO_DRIVE_TASK_HDR_SIZE	8*sizeof(task_ioreg_t)
-#define HDIO_DRIVE_HOB_HDR_SIZE		8*sizeof(task_ioreg_t)
+#define HDIO_DRIVE_CMD_HDR_SIZE		(4 * sizeof(u8))
+#define HDIO_DRIVE_TASK_HDR_SIZE	(8 * sizeof(u8))
+#define HDIO_DRIVE_HOB_HDR_SIZE		(8 * sizeof(u8))
 
 #define IDE_DRIVE_TASK_INVALID		-1
 #define IDE_DRIVE_TASK_NO_DATA		0
@@ -74,57 +67,27 @@
 #define IDE_DRIVE_TASK_OUT		3
 #define IDE_DRIVE_TASK_RAW_WRITE	4
 
-struct hd_drive_cmd_hdr {
-	task_ioreg_t command;
-	task_ioreg_t sector_number;
-	task_ioreg_t feature;
-	task_ioreg_t sector_count;
-};
-
-typedef struct hd_drive_task_hdr {
-	task_ioreg_t data;
-	task_ioreg_t feature;
-	task_ioreg_t sector_count;
-	task_ioreg_t sector_number;
-	task_ioreg_t low_cylinder;
-	task_ioreg_t high_cylinder;
-	task_ioreg_t device_head;
-	task_ioreg_t command;
-} task_struct_t;
-
-typedef struct hd_drive_hob_hdr {
-	task_ioreg_t data;
-	task_ioreg_t feature;
-	task_ioreg_t sector_count;
-	task_ioreg_t sector_number;
-	task_ioreg_t low_cylinder;
-	task_ioreg_t high_cylinder;
-	task_ioreg_t device_head;
-	task_ioreg_t control;
-} hob_struct_t;
-
-typedef union ide_reg_valid_s {
-	unsigned all				: 16;
-	struct {
-		unsigned data			: 1;
-		unsigned error_feature		: 1;
-		unsigned sector			: 1;
-		unsigned nsector		: 1;
-		unsigned lcyl			: 1;
-		unsigned hcyl			: 1;
-		unsigned select			: 1;
-		unsigned status_command		: 1;
-
-		unsigned data_hob		: 1;
-		unsigned error_feature_hob	: 1;
-		unsigned sector_hob		: 1;
-		unsigned nsector_hob		: 1;
-		unsigned lcyl_hob		: 1;
-		unsigned hcyl_hob		: 1;
-		unsigned select_hob		: 1;
-		unsigned control_hob		: 1;
-	} b;
-} ide_reg_valid_t;
+struct hd_drive_task_hdr {
+	u8 data;
+	u8 feature;
+	u8 sector_count;
+	u8 sector_number;
+	u8 low_cylinder;
+	u8 high_cylinder;
+	u8 device_head;
+	u8 command;
+} __attribute__((packed));
+
+struct hd_drive_hob_hdr {
+	u8 data;
+	u8 feature;
+	u8 sector_count;
+	u8 sector_number;
+	u8 low_cylinder;
+	u8 high_cylinder;
+	u8 device_head;
+	u8 control;
+} __attribute__((packed));
 
 /*
  * Define standard taskfile in/out register
@@ -134,23 +97,6 @@
 #define IDE_HOB_STD_OUT_FLAGS		0xC0
 #define IDE_HOB_STD_IN_FLAGS		0xC0
 
-typedef struct ide_task_request_s {
-	task_ioreg_t	io_ports[8];
-	task_ioreg_t	hob_ports[8];
-	ide_reg_valid_t	out_flags;
-	ide_reg_valid_t	in_flags;
-	int		data_phase;
-	int		req_cmd;
-	unsigned long	out_size;
-	unsigned long	in_size;
-} ide_task_request_t;
-
-typedef struct ide_ioctl_request_s {
-	ide_task_request_t	*task_request;
-	unsigned char		*out_buffer;
-	unsigned char		*in_buffer;
-} ide_ioctl_request_t;
-
 #define TASKFILE_INVALID		0x7fff
 #define TASKFILE_48			0x8000
 
@@ -212,7 +158,7 @@
 #define WIN_PIDENTIFY			0xA1 /* identify ATAPI device	*/
 #define WIN_QUEUED_SERVICE		0xA2
 #define WIN_SMART			0xB0 /* self-monitoring and reporting */
-#define CFA_ERASE_SECTORS       	0xC0
+#define CFA_ERASE_SECTORS		0xC0
 #define WIN_MULTREAD			0xC4 /* read sectors using multiple mode*/
 #define WIN_MULTWRITE			0xC5 /* write sectors using multiple mode */
 #define WIN_SETMULT			0xC6 /* enable/disable multiple mode */
@@ -221,12 +167,12 @@
 #define WIN_WRITEDMA			0xCA /* write sectors using DMA transfers */
 #define WIN_WRITEDMA_QUEUED		0xCC /* write sectors using Queued DMA transfers */
 #define CFA_WRITE_MULTI_WO_ERASE	0xCD /* CFA Write multiple without erase */
-#define WIN_GETMEDIASTATUS		0xDA	
+#define WIN_GETMEDIASTATUS		0xDA
 #define WIN_DOORLOCK			0xDE /* lock door on removable drives */
 #define WIN_DOORUNLOCK			0xDF /* unlock door on removable drives */
 #define WIN_STANDBYNOW1			0xE0
 #define WIN_IDLEIMMEDIATE		0xE1 /* force drive to become "ready" */
-#define WIN_STANDBY             	0xE2 /* Set device in Standby Mode */
+#define WIN_STANDBY			0xE2 /* Set device in Standby Mode */
 #define WIN_SETIDLE1			0xE3
 #define WIN_READ_BUFFER			0xE4 /* force read only 1 sector */
 #define WIN_CHECKPOWERMODE1		0xE5
@@ -268,7 +214,7 @@
 
 #define SMART_LCYL_PASS			0x4F
 #define SMART_HCYL_PASS			0xC2
-		
+
 /* WIN_SETFEATURES sub-commands */
 
 #define SETFEATURES_EN_WCACHE	0x02	/* Enable write cache */
diff -urN linux-2.5.7/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.7/include/linux/ide.h	Wed Mar 20 03:28:37 2002
+++ linux/include/linux/ide.h	Wed Mar 20 03:23:51 2002
@@ -90,17 +90,6 @@
 #define IDE_FEATURE_OFFSET	IDE_ERROR_OFFSET
 #define IDE_COMMAND_OFFSET	IDE_STATUS_OFFSET
 
-#define IDE_DATA_OFFSET_HOB	(0)
-#define IDE_ERROR_OFFSET_HOB	(1)
-#define IDE_NSECTOR_OFFSET_HOB	(2)
-#define IDE_SECTOR_OFFSET_HOB	(3)
-#define IDE_LCYL_OFFSET_HOB	(4)
-#define IDE_HCYL_OFFSET_HOB	(5)
-#define IDE_SELECT_OFFSET_HOB	(6)
-#define IDE_CONTROL_OFFSET_HOB	(7)
-
-#define IDE_FEATURE_OFFSET_HOB	IDE_ERROR_OFFSET_HOB
-
 #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])
@@ -112,16 +101,6 @@
 #define IDE_CONTROL_REG		(HWIF(drive)->io_ports[IDE_CONTROL_OFFSET])
 #define IDE_IRQ_REG		(HWIF(drive)->io_ports[IDE_IRQ_OFFSET])
 
-#define IDE_DATA_REG_HOB	(HWIF(drive)->io_ports[IDE_DATA_OFFSET])
-#define IDE_ERROR_REG_HOB	(HWIF(drive)->io_ports[IDE_ERROR_OFFSET])
-#define IDE_NSECTOR_REG_HOB	(HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET])
-#define IDE_SECTOR_REG_HOB	(HWIF(drive)->io_ports[IDE_SECTOR_OFFSET])
-#define IDE_LCYL_REG_HOB	(HWIF(drive)->io_ports[IDE_LCYL_OFFSET])
-#define IDE_HCYL_REG_HOB	(HWIF(drive)->io_ports[IDE_HCYL_OFFSET])
-#define IDE_SELECT_REG_HOB	(HWIF(drive)->io_ports[IDE_SELECT_OFFSET])
-#define IDE_STATUS_REG_HOB	(HWIF(drive)->io_ports[IDE_STATUS_OFFSET])
-#define IDE_CONTROL_REG_HOB	(HWIF(drive)->io_ports[IDE_CONTROL_OFFSET])
-
 #define IDE_FEATURE_REG		IDE_ERROR_REG
 #define IDE_COMMAND_REG		IDE_STATUS_REG
 #define IDE_ALTSTATUS_REG	IDE_CONTROL_REG
@@ -785,8 +764,8 @@
 void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err);
 
 typedef struct ide_task_s {
-	task_ioreg_t		tfRegister[8];
-	task_ioreg_t		hobRegister[8];
+	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_hob_hdr  hobfile;
 	int			command_type;
 	ide_pre_handler_t	*prehandler;
 	ide_handler_t		*handler;

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

* [PATCH] 2.5.7 IDE 26
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (3 preceding siblings ...)
  2002-03-28  9:25 ` [PATCH] 2.5.7 IDE 25 Martin Dalecki
@ 2002-03-28  9:29 ` Martin Dalecki
  2002-03-28 20:34   ` Vojtech Pavlik
  2002-03-28  9:31 ` [PATCH] 2.5.7 IDE 27 Martin Dalecki
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-03-28  9:29 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Wed Mar 20 23:17:06 CET 2002 ide-clean-26

- Mark all members of structures, which get jiffies assigned or involved in
   ugly timeout calculations with the prefix PADAM_  for easy spotting. This is
   Polish for "I'm falling down" or "This brings me to the knees" or slag
   comment for "What a sh..". Please be assured that it doesn't sound vulgar.

   Please grep for it to see immediately why this nomenclature is justified.

- Rename hwifs_s to ata_channel and eliminate ide_hwifs_t as well as the HWIF
   macro. OK this step makes this patch rather big.

[-- Attachment #2: ide-clean-26.diff.gz --]
[-- Type: application/x-gzip, Size: 30407 bytes --]

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

* Re: PATCH 2.5.7 IDE 24
  2002-03-28  9:23 ` PATCH 2.5.7 IDE 24 Martin Dalecki
@ 2002-03-28  9:29   ` Zwane Mwaikambo
  0 siblings, 0 replies; 39+ messages in thread
From: Zwane Mwaikambo @ 2002-03-28  9:29 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Kernel Mailing List


But i haven't even tried 23 yet!!

-- 
http://function.linuxpower.ca
		


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

* [PATCH] 2.5.7 IDE 27
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (4 preceding siblings ...)
  2002-03-28  9:29 ` [PATCH] 2.5.7 IDE 26 Martin Dalecki
@ 2002-03-28  9:31 ` Martin Dalecki
  2002-03-28 18:01   ` Davide Libenzi
  2002-03-28  9:32 ` [PATCH] 2.5.7 IDE 28a Martin Dalecki
                   ` (11 subsequent siblings)
  17 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-03-28  9:31 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Thu Mar 21 03:17:48 CET 2002 ide-clean-27

- Make for less terse error messages in ide-tape.c.

- Replaced all timecomparisions done by hand with all the proper timer_after()
   commands.

- Remove the drive niec1 mechanisms alltogether. There are several reasons for
   this:

   1. The code implementing it is nonintelliglible and therefore propably
   broken.

   2. If we have to invent somethig about sceduling drive IO, it should be done
   on the BIO level.

   3. We may in fact interleave with the IO sceduling on the upper layers and
   the results of two overlapping signal filters overlapped with each other can
   be disasterous to the overall throughput. (In fact they *are* most of the
   time.)

   4. It was not working if you had intermixed modes on different drives
   DMA versus PIO.

   5. Our goal is to have a driver which is able to share the badwidth
   properly and shouldn't needing this kind of "tuning".

- Remove unused nice2 from disk struct.

- Rename channel member of ata_channel to unit and device to dev to
   just prevent wrong interpretations. This prevents constructs like
   channel->channel...

[-- Attachment #2: ide-clean-27.diff --]
[-- Type: text/plain, Size: 51966 bytes --]

diff -urN linux-2.5.7/drivers/ide/aec62xx.c linux/drivers/ide/aec62xx.c
--- linux-2.5.7/drivers/ide/aec62xx.c	Thu Mar 21 23:54:16 2002
+++ linux/drivers/ide/aec62xx.c	Fri Mar 22 02:05:36 2002
@@ -259,7 +259,7 @@
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
 	byte unit		= (drive->select.b.unit & 0x01);
-	byte ultra_pci		= hwif->channel ? 0x45 : 0x44;
+	byte ultra_pci		= hwif->unit ? 0x45 : 0x44;
 	int err			= 0;
 	byte drive_conf		= 0x00;
 	byte ultra_conf		= 0x00;
@@ -532,7 +532,7 @@
 
 unsigned int __init ata66_aec62xx(struct ata_channel *hwif)
 {
-	byte mask	= hwif->channel ? 0x02 : 0x01;
+	byte mask	= hwif->unit ? 0x02 : 0x01;
 	byte ata66	= 0;
 
 	pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
@@ -565,7 +565,7 @@
 	__cli();		/* local CPU only */
 
 	pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
-	pci_write_config_byte(hwif->pci_dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F));
+	pci_write_config_byte(hwif->pci_dev, 0x54, reg54h & ~(hwif->unit ? 0xF0 : 0x0F));
 
 	__restore_flags(flags);	/* local CPU only */
 #endif /* CONFIG_AEC62XX_TUNING */
diff -urN linux-2.5.7/drivers/ide/ali14xx.c linux/drivers/ide/ali14xx.c
--- linux-2.5.7/drivers/ide/ali14xx.c	Thu Mar 21 23:54:16 2002
+++ linux/drivers/ide/ali14xx.c	Fri Mar 22 02:06:01 2002
@@ -214,7 +214,7 @@
 	ide_hwifs[1].tuneproc = &ali14xx_tune_drive;
 	ide_hwifs[0].mate = &ide_hwifs[1];
 	ide_hwifs[1].mate = &ide_hwifs[0];
-	ide_hwifs[1].channel = 1;
+	ide_hwifs[1].unit = 1;
 
 	/* initialize controller registers */
 	if (!initRegisters()) {
diff -urN linux-2.5.7/drivers/ide/alim15x3.c linux/drivers/ide/alim15x3.c
--- linux-2.5.7/drivers/ide/alim15x3.c	Thu Mar 21 23:54:16 2002
+++ linux/drivers/ide/alim15x3.c	Fri Mar 22 02:08:58 2002
@@ -247,8 +247,8 @@
 	int s_time, a_time, c_time;
 	byte s_clc, a_clc, r_clc;
 	unsigned long flags;
-	int port = hwif->index ? 0x5c : 0x58;
-	int portFIFO = hwif->channel ? 0x55 : 0x54;
+	int port = hwif->unit ? 0x5c : 0x58;
+	int portFIFO = hwif->unit ? 0x55 : 0x54;
 	byte cd_dma_fifo = 0;
 
 	if (pio == 255)
@@ -309,7 +309,7 @@
 	struct pci_dev *dev	= hwif->pci_dev;
 	byte unit		= (drive->select.b.unit & 0x01);
 	byte tmpbyte		= 0x00;
-	int m5229_udma		= hwif->channel? 0x57 : 0x56;
+	int m5229_udma		= hwif->unit ? 0x57 : 0x56;
 	int err			= 0;
 
 	if (speed < XFER_UDMA_0) {
@@ -597,7 +597,7 @@
 		/*
 		 * Allow ata66 if cable of current channel has 80 pins
 		 */
-		ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0];
+		ata66 = (hwif->unit)?cable_80_pin[1]:cable_80_pin[0];
 	} else {
 		/*
 		 * revision 0x20 (1543-E, 1543-F)
@@ -639,7 +639,7 @@
 	byte irq_routing_table[] = { -1,  9, 3, 10, 4,  5, 7,  6,
 				      1, 11, 0, 12, 0, 14, 0, 15 };
 
-	hwif->irq = hwif->channel ? 15 : 14;
+	hwif->irq = hwif->unit ? 15 : 14;
 
 	if (isa_dev) {
 		/*
@@ -651,14 +651,14 @@
 		ideic = ideic & 0x03;
 
 		/* get IRQ for IDE Controller */
-		if ((hwif->channel && ideic == 0x03) || (!hwif->channel && !ideic)) {
+		if ((hwif->unit && ideic == 0x03) || (!hwif->unit && !ideic)) {
 			/*
 			 * get SIRQ1 routing table
 			 */
 			pci_read_config_byte(isa_dev, 0x44, &inmir);
 			inmir = inmir & 0x0f;
 			hwif->irq = irq_routing_table[inmir];
-		} else if (hwif->channel && !(ideic & 0x01)) {
+		} else if (hwif->unit && !(ideic & 0x01)) {
 			/*
 			 * get SIRQ2 routing table
 			 */
diff -urN linux-2.5.7/drivers/ide/amd74xx.c linux/drivers/ide/amd74xx.c
--- linux-2.5.7/drivers/ide/amd74xx.c	Thu Mar 21 23:54:16 2002
+++ linux/drivers/ide/amd74xx.c	Fri Mar 22 02:10:04 2002
@@ -263,7 +263,7 @@
 
 static void amd74xx_tune_drive(ide_drive_t *drive, unsigned char pio)
 {
-	if (!((amd_enabled >> drive->channel->channel) & 1))
+	if (!((amd_enabled >> drive->channel->unit) & 1))
 		return;
 
 	if (pio == 255) {
@@ -411,7 +411,7 @@
 
 unsigned int __init ata66_amd74xx(struct ata_channel *hwif)
 {
-	return ((amd_enabled & amd_80w) >> hwif->channel) & 1;
+	return ((amd_enabled & amd_80w) >> hwif->unit) & 1;
 }
 
 void __init ide_init_amd74xx(struct ata_channel *hwif)
@@ -426,7 +426,7 @@
 		hwif->drives[i].io_32bit = 1;
 		hwif->drives[i].unmask = 1;
 		hwif->drives[i].autotune = 1;
-		hwif->drives[i].dn = hwif->channel * 2 + i;
+		hwif->drives[i].dn = hwif->unit * 2 + i;
 	}
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -447,6 +447,6 @@
 
 void __init ide_dmacapable_amd74xx(struct ata_channel *hwif, unsigned long dmabase)
 {
-	if ((amd_enabled >> hwif->channel) & 1)
+	if ((amd_enabled >> hwif->unit) & 1)
 		ide_setup_dma(hwif, dmabase, 8);
 }
diff -urN linux-2.5.7/drivers/ide/cmd640.c linux/drivers/ide/cmd640.c
--- linux-2.5.7/drivers/ide/cmd640.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/cmd640.c	Fri Mar 22 02:10:32 2002
@@ -795,7 +795,7 @@
 		cmd_hwif1->chipset = ide_cmd640;
 		cmd_hwif0->mate = cmd_hwif1;
 		cmd_hwif1->mate = cmd_hwif0;
-		cmd_hwif1->channel = 1;
+		cmd_hwif1->unit = 1;
 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
 		cmd_hwif1->tuneproc = &cmd640_tune_drive;
 #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
diff -urN linux-2.5.7/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c
--- linux-2.5.7/drivers/ide/cmd64x.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/cmd64x.c	Fri Mar 22 02:35:41 2002
@@ -224,7 +224,7 @@
 			{ DRWTIM0, DRWTIM1 },
 			{ DRWTIM2, DRWTIM3 }
 		};
-	int channel = (int) drive->channel->channel;
+	int channel = drive->channel->unit;
 	int slave = (drives != drive);  /* Is this really the best way to determine this?? */
 
 	cmdprintk("program_drive_count parameters = s(%d),a(%d),r(%d),p(%d)\n", setup_count,
@@ -336,7 +336,7 @@
 static byte cmd680_taskfile_timing(struct ata_channel *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
-	byte addr_mask		= (hwif->channel) ? 0xB2 : 0xA2;
+	byte addr_mask		= (hwif->unit) ? 0xB2 : 0xA2;
 	unsigned short		timing;
 
 	pci_read_config_word(dev, addr_mask, &timing);
@@ -397,7 +397,7 @@
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
 	u8 unit			= (drive->select.b.unit & 0x01);
-	u8 addr_mask		= (hwif->channel) ? 0x84 : 0x80;
+	u8 addr_mask		= (hwif->unit) ? 0x84 : 0x80;
 	u8 speed		= 0x00;
 	u8 mode_pci		= 0x00;
 	u8 channel_timings	= cmd680_taskfile_timing(hwif);
@@ -435,8 +435,8 @@
 	int err			= 0;
 
 	u8 unit			= (drive->select.b.unit & 0x01);
-	u8 pciU			= (hwif->channel) ? UDIDETCR1 : UDIDETCR0;
-	u8 pciD			= (hwif->channel) ? BMIDESR1 : BMIDESR0;
+	u8 pciU			= (hwif->unit) ? UDIDETCR1 : UDIDETCR0;
+	u8 pciD			= (hwif->unit) ? BMIDESR1 : BMIDESR0;
 	u8 regU			= 0;
 	u8 regD			= 0;
 
@@ -500,7 +500,7 @@
 {
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
-	u8 addr_mask		= (hwif->channel) ? 0x84 : 0x80;
+	u8 addr_mask		= (hwif->unit) ? 0x84 : 0x80;
 	u8 unit			= (drive->select.b.unit & 0x01);
 	u8 dma_pci		= 0;
 	u8 udma_pci		= 0;
@@ -841,7 +841,7 @@
 {
 	byte dma_stat		= 0;
 	byte dma_alt_stat	= 0;
-	byte mask		= (drive->channel->channel) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
+	byte mask		= (drive->channel->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
 	unsigned long dma_base	= drive->channel->dma_base;
 	struct pci_dev *dev	= drive->channel->pci_dev;
 	byte jack_slap		= ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
@@ -856,8 +856,8 @@
 			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
 			if (jack_slap) {
 				byte dma_intr	= 0;
-				byte dma_mask	= (drive->channel->channel) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
-				byte dma_reg	= (drive->channel->channel) ? ARTTIM2 : CFR;
+				byte dma_mask	= (drive->channel->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
+				byte dma_reg	= (drive->channel->unit) ? ARTTIM2 : CFR;
 				(void) pci_read_config_byte(dev, dma_reg, &dma_intr);
 				/*
 				 * DAMN BMIDE is not connected to PCI space!
@@ -918,7 +918,7 @@
 {
 #if 0
 	struct ata_channel *hwif	= drive->channel;
-	u8 addr_mask		= (hwif->channel) ? 0xB0 : 0xA0;
+	u8 addr_mask		= (hwif->unit) ? 0xB0 : 0xA0;
 	u32 stat_config		= 0;
 
         pci_read_config_dword(hwif->pci_dev, addr_mask, &stat_config);
@@ -951,7 +951,7 @@
 {
 #if 0
 	struct ata_channel *hwif = drive->channel;
-	u8 addr_mask		= (hwif->channel) ? 0xB0 : 0xA0;
+	u8 addr_mask		= (hwif->unit) ? 0xB0 : 0xA0;
 	byte reset		= 0;
 
 	pci_read_config_byte(hwif->pci_dev, addr_mask, &reset);
@@ -1084,7 +1084,7 @@
 unsigned int cmd680_ata66(struct ata_channel *hwif)
 {
 	byte ata66	= 0;
-	byte addr_mask	= (hwif->channel) ? 0xB0 : 0xA0;
+	byte addr_mask	= (hwif->unit) ? 0xB0 : 0xA0;
 
 	pci_read_config_byte(hwif->pci_dev, addr_mask, &ata66);
 	return (ata66 & 0x01) ? 1 : 0;
@@ -1093,7 +1093,7 @@
 unsigned int cmd64x_ata66(struct ata_channel *hwif)
 {
 	byte ata66 = 0;
-	byte mask = (hwif->channel) ? 0x02 : 0x01;
+	byte mask = (hwif->unit) ? 0x02 : 0x01;
 
 	pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66);
 	return (ata66 & mask) ? 1 : 0;
diff -urN linux-2.5.7/drivers/ide/cs5530.c linux/drivers/ide/cs5530.c
--- linux-2.5.7/drivers/ide/cs5530.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/cs5530.c	Fri Mar 22 02:14:34 2002
@@ -101,7 +101,7 @@
  * After chip reset, the PIO timings are set to 0x0000e132, which is not valid.
  */
 #define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132)
-#define CS5530_BASEREG(hwif)	(((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20))
+#define CS5530_BASEREG(hwif)	(((hwif)->dma_base & ~0xf) + ((hwif)->unit ? 0x30 : 0x20))
 
 /*
  * cs5530_tuneproc() handles selection/setting of PIO modes
diff -urN linux-2.5.7/drivers/ide/cy82c693.c linux/drivers/ide/cy82c693.c
--- linux-2.5.7/drivers/ide/cy82c693.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/cy82c693.c	Fri Mar 22 02:41:03 2002
@@ -192,7 +192,7 @@
 	if (mode > drive->id->tDMA)  /* to be absolutly sure we have a valid mode */
 		mode = drive->id->tDMA;
 	
-        index = (drive->channel->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1;
+        index = (drive->channel->unit == 0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1;
 
 #if CY82C693_DEBUG_LOGS
        	/* for debug let's show the previous values */
@@ -200,7 +200,7 @@
 	OUT_BYTE(index, CY82_INDEX_PORT);
 	data = IN_BYTE(CY82_DATA_PORT);
 
-	printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", drive->name, drive->channel->channel, drive->select.b.unit, (data&0x3), ((data>>2)&1));
+	printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", drive->name, drive->channel->unit, drive->select.b.unit, (data&0x3), ((data>>2)&1));
 #endif /* CY82C693_DEBUG_LOGS */
 
 	data = (byte)mode|(byte)(single<<2);
@@ -209,7 +209,7 @@
 	OUT_BYTE(data, CY82_DATA_PORT);
 
 #if CY82C693_DEBUG_INFO
-	printk (KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", drive->name, drive->channel->channel, drive->select.b.unit, mode, single);
+	printk (KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", drive->name, drive->channel->unit, drive->select.b.unit, mode, single);
 #endif /* CY82C693_DEBUG_INFO */
 
 	/* 
@@ -318,7 +318,7 @@
 		pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8);
 	}
 
-	printk (KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->channel, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
+	printk (KERN_INFO "%s (ch=%d, dev=%d): PIO timing is (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->unit, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
 #endif /* CY82C693_DEBUG_LOGS */
 
         /* first let's calc the pio modes */
@@ -371,7 +371,7 @@
 	}	
 
 #if CY82C693_DEBUG_INFO
-	printk (KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->channel, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
+	printk (KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to (addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", drive->name, hwif->unit, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
 #endif /* CY82C693_DEBUG_INFO */
 }
 
diff -urN linux-2.5.7/drivers/ide/dtc2278.c linux/drivers/ide/dtc2278.c
--- linux-2.5.7/drivers/ide/dtc2278.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/dtc2278.c	Fri Mar 22 02:16:14 2002
@@ -126,5 +126,5 @@
 	ide_hwifs[1].drives[1].no_unmask = 1;
 	ide_hwifs[0].mate = &ide_hwifs[1];
 	ide_hwifs[1].mate = &ide_hwifs[0];
-	ide_hwifs[1].channel = 1;
+	ide_hwifs[1].unit = 1;
 }
diff -urN linux-2.5.7/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c
--- linux-2.5.7/drivers/ide/hpt366.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/hpt366.c	Fri Mar 22 02:40:25 2002
@@ -485,7 +485,7 @@
 static void hpt366_tune_chipset (ide_drive_t *drive, byte speed)
 {
 	byte regtime		= (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
-	byte regfast		= (drive->channel->channel) ? 0x55 : 0x51;
+	byte regfast		= (drive->channel->unit) ? 0x55 : 0x51;
 			/*
 			 * since the channel is always 0 it does not matter.
 			 */
@@ -536,7 +536,7 @@
 
 static void hpt370_tune_chipset (ide_drive_t *drive, byte speed)
 {
-	byte regfast		= (drive->channel->channel) ? 0x55 : 0x51;
+	byte regfast		= (drive->channel->unit) ? 0x55 : 0x51;
 	unsigned int list_conf	= 0;
 	unsigned int drive_conf = 0;
 	unsigned int conf_mask	= (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
@@ -840,8 +840,8 @@
 {
 	struct ata_channel *hwif = drive->channel;
 	unsigned long dma_base = hwif->dma_base;
-	byte regstate = hwif->channel ? 0x54 : 0x50;
-	byte reginfo = hwif->channel ? 0x56 : 0x52;
+	byte regstate = hwif->unit ? 0x54 : 0x50;
+	byte reginfo = hwif->unit ? 0x56 : 0x52;
 	byte dma_stat;
 
 	switch (func) {
@@ -900,7 +900,7 @@
 {
 #if 0
 	unsigned long high_16	= pci_resource_start(drive->channel->pci_dev, 4);
-	byte reset		= (drive->channel->channel) ? 0x80 : 0x40;
+	byte reset		= (drive->channel->unit) ? 0x80 : 0x40;
 	byte reg59h		= 0;
 
 	pci_read_config_byte(drive->channel->pci_dev, 0x59, &reg59h);
@@ -914,8 +914,8 @@
 {
 	struct ata_channel *hwif	= drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
-	byte reset		= (hwif->channel) ? 0x80 : 0x40;
-	byte state_reg		= (hwif->channel) ? 0x57 : 0x53;
+	byte reset		= (hwif->unit) ? 0x80 : 0x40;
+	byte state_reg		= (hwif->unit) ? 0x57 : 0x53;
 	byte reg59h		= 0;
 	byte regXXh		= 0;
 
@@ -960,7 +960,7 @@
 
 	hwif->bus_state = state;
 
-	if (hwif->channel) { 
+	if (hwif->unit) { 
 		/* secondary channel */
 		tristate = 0x56;
 		resetmask = 0x80; 
@@ -1139,7 +1139,7 @@
 unsigned int __init ata66_hpt366(struct ata_channel *hwif)
 {
 	byte ata66	= 0;
-	byte regmask	= (hwif->channel) ? 0x01 : 0x02;
+	byte regmask	= (hwif->unit) ? 0x01 : 0x02;
 
 	pci_read_config_byte(hwif->pci_dev, 0x5a, &ata66);
 #ifdef DEBUG
@@ -1214,8 +1214,8 @@
 {
 	byte masterdma = 0, slavedma = 0;
 	byte dma_new = 0, dma_old = inb(dmabase+2);
-	byte primary	= hwif->channel ? 0x4b : 0x43;
-	byte secondary	= hwif->channel ? 0x4f : 0x47;
+	byte primary	= hwif->unit ? 0x4b : 0x43;
+	byte secondary	= hwif->unit ? 0x4f : 0x47;
 	unsigned long flags;
 
 	__save_flags(flags);	/* local CPU only */
diff -urN linux-2.5.7/drivers/ide/ht6560b.c linux/drivers/ide/ht6560b.c
--- linux-2.5.7/drivers/ide/ht6560b.c	Mon Mar 18 21:37:07 2002
+++ linux/drivers/ide/ht6560b.c	Fri Mar 22 02:18:32 2002
@@ -321,7 +321,7 @@
 			ide_hwifs[1].serialized = 1;  /* is this needed? */
 			ide_hwifs[0].mate = &ide_hwifs[1];
 			ide_hwifs[1].mate = &ide_hwifs[0];
-			ide_hwifs[1].channel = 1;
+			ide_hwifs[1].unit = 1;
 			
 			/*
 			 * Setting default configurations for drives
diff -urN linux-2.5.7/drivers/ide/icside.c linux/drivers/ide/icside.c
--- linux-2.5.7/drivers/ide/icside.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/icside.c	Fri Mar 22 02:39:18 2002
@@ -621,7 +621,7 @@
 			hwif->hw.dma  = ec->dma;
 			hwif->hw.priv = (void *)
 					(port + ICS_ARCIN_V6_INTRSTAT_1);
-			hwif->channel = 0;
+			hwif->unit = 0;
 			icside_setup_dma(hwif, autodma);
 		}
 		if (mate) {
@@ -630,7 +630,7 @@
 			mate->hw.dma  = ec->dma;
 			mate->hw.priv = (void *)
 					(port + ICS_ARCIN_V6_INTRSTAT_2);
-			mate->channel = 1;
+			mate->unit = 1;
 			icside_setup_dma(mate, autodma);
 		}
 	}
diff -urN linux-2.5.7/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.7/drivers/ide/ide-disk.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/ide-disk.c	Fri Mar 22 02:33:35 2002
@@ -1036,7 +1036,7 @@
 	    sprintf(drive->device.bus_id, "%d", drvid);
 	    sprintf(drive->device.name, "ide-disk");
 	    drive->device.driver = &idedisk_devdrv;
-	    drive->device.parent = &drive->channel->device;
+	    drive->device.parent = &drive->channel->dev;
 	    drive->device.driver_data = drive;
 	    device_register(&drive->device);
 	}
diff -urN linux-2.5.7/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.7/drivers/ide/ide-dma.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/ide-dma.c	Fri Mar 22 02:18:58 2002
@@ -660,7 +660,7 @@
 		kfree(hwif->sg_table);
 		hwif->sg_table = NULL;
 	}
-	if ((hwif->dma_extra) && (hwif->channel == 0))
+	if ((hwif->dma_extra) && (hwif->unit == 0))
 		release_region((hwif->dma_base + 16), hwif->dma_extra);
 	release_region(hwif->dma_base, 8);
 	hwif->dma_base = 0;
diff -urN linux-2.5.7/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- linux-2.5.7/drivers/ide/ide-pci.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/ide-pci.c	Fri Mar 22 02:21:22 2002
@@ -442,7 +442,7 @@
 	 */
 
 	if (hwif->mate && hwif->mate->dma_base)
-		dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
+		dma_base = hwif->mate->dma_base - (hwif->unit ? 0 : 8);
 	else
 		dma_base = pci_resource_start(dev, 4);
 
@@ -452,7 +452,7 @@
 	if (extra) /* PDC20246, PDC20262, HPT343, & HPT366 */
 		request_region(dma_base + 16, extra, name);
 
-	dma_base += hwif->channel ? 8 : 0;
+	dma_base += hwif->unit ? 8 : 0;
 	hwif->dma_extra = extra;
 
 	if ((dev->vendor == PCI_VENDOR_ID_AL && dev->device == PCI_DEVICE_ID_AL_M5219) ||
@@ -610,7 +610,7 @@
 
 	hwif->chipset = ide_pci;
 	hwif->pci_dev = dev;
-	hwif->channel = port;
+	hwif->unit = port;
 	if (!hwif->irq)
 		hwif->irq = pciirq;
 
diff -urN linux-2.5.7/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.7/drivers/ide/ide-probe.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/ide-probe.c	Fri Mar 22 02:04:10 2002
@@ -118,7 +118,7 @@
 		byte type = (id->config >> 8) & 0x1f;
 		printk("ATAPI ");
 #ifdef CONFIG_BLK_DEV_PDC4030
-		if (drive->channel->channel == 1 && drive->channel->chipset == ide_pdc4030) {
+		if (drive->channel->unit == 1 && drive->channel->chipset == ide_pdc4030) {
 			printk(" -- not supported on 2nd Promise port\n");
 			goto err_misc;
 		}
@@ -461,16 +461,16 @@
 {
 	/* Register this hardware interface within the global device tree.
 	 */
-	sprintf(hwif->device.bus_id, "%04x", hwif->io_ports[IDE_DATA_OFFSET]);
-	sprintf(hwif->device.name, "ide");
-	hwif->device.driver_data = hwif;
+	sprintf(hwif->dev.bus_id, "%04x", hwif->io_ports[IDE_DATA_OFFSET]);
+	sprintf(hwif->dev.name, "ide");
+	hwif->dev.driver_data = hwif;
 #ifdef CONFIG_BLK_DEV_IDEPCI
 	if (hwif->pci_dev)
-		hwif->device.parent = &hwif->pci_dev->dev;
+		hwif->dev.parent = &hwif->pci_dev->dev;
 	else
 #endif
-		hwif->device.parent = NULL; /* Would like to do = &device_legacy */
-	device_register(&hwif->device);
+		hwif->dev.parent = NULL; /* Would like to do = &device_legacy */
+	device_register(&hwif->dev);
 
 	if (((unsigned long)hwif->io_ports[IDE_DATA_OFFSET] | 7) ==
 	    ((unsigned long)hwif->io_ports[IDE_STATUS_OFFSET])) {
@@ -517,7 +517,7 @@
 
 	if (
 #if CONFIG_BLK_DEV_PDC4030
-	    (hwif->chipset != ide_pdc4030 || hwif->channel == 0) &&
+	    (hwif->chipset != ide_pdc4030 || hwif->unit == 0) &&
 #endif
 	    hwif_check_regions(hwif)) {
 		int msgout = 0;
@@ -824,11 +824,11 @@
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		char name[80];
 		ide_add_generic_settings(hwif->drives + unit);
-		hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit);
+		hwif->drives[unit].dn = ((hwif->unit ? 2 : 0) + unit);
 		sprintf (name, "host%d/bus%d/target%d/lun%d",
-			(hwif->channel && hwif->mate) ?
+			(hwif->unit && hwif->mate) ?
 			hwif->mate->index : hwif->index,
-			hwif->channel, unit, hwif->drives[unit].lun);
+			hwif->unit, unit, hwif->drives[unit].lun);
 		if (hwif->drives[unit].present)
 			hwif->drives[unit].de = devfs_mk_dir(ide_devfs_handle, name, NULL);
 	}
diff -urN linux-2.5.7/drivers/ide/ide-proc.c linux/drivers/ide/ide-proc.c
--- linux-2.5.7/drivers/ide/ide-proc.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/ide-proc.c	Fri Mar 22 02:33:06 2002
@@ -183,7 +183,7 @@
 	struct ata_channel *hwif = data;
 	int		len;
 
-	page[0] = hwif->channel ? '1' : '0';
+	page[0] = hwif->unit ? '1' : '0';
 	page[1] = '\n';
 	len = 2;
 	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
diff -urN linux-2.5.7/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux-2.5.7/drivers/ide/ide-tape.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/ide-tape.c	Thu Mar 21 14:06:19 2002
@@ -3103,10 +3103,10 @@
 	idetape_tape_t *tape = drive->driver_data;
 	idetape_read_position_result_t *result;
 	
-//#if IDETAPE_DEBUG_LOG
-//	if (tape->debug_level >= 4)
+#if IDETAPE_DEBUG_LOG
+	if (tape->debug_level >= 4)
 		printk (KERN_INFO "ide-tape: Reached idetape_read_position_callback\n");
-//#endif /* IDETAPE_DEBUG_LOG */
+#endif /* IDETAPE_DEBUG_LOG */
 
 	if (!tape->pc->error) {
 		result = (idetape_read_position_result_t *) tape->pc->buffer;
@@ -3280,10 +3280,10 @@
 	idetape_pc_t pc;
 	int position;
 
-//#if IDETAPE_DEBUG_LOG
-//        if (tape->debug_level >= 4)
-	printk (KERN_INFO "ide-tape: Reached idetape_read_position\n");
-//#endif /* IDETAPE_DEBUG_LOG */
+#if IDETAPE_DEBUG_LOG
+	if (tape->debug_level >= 4)
+	    printk (KERN_INFO "ide-tape: Reached idetape_read_position\n");
+#endif /* IDETAPE_DEBUG_LOG */
 
 #ifdef NO_LONGER_REQUIRED
 	idetape_flush_tape_buffers(drive);
diff -urN linux-2.5.7/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.7/drivers/ide/ide.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/ide.c	Fri Mar 22 02:00:34 2002
@@ -1213,40 +1213,20 @@
 {
 	ide_drive_t *drive, *best;
 
-repeat:
 	best = NULL;
 	drive = hwgroup->drive;
 	do {
-		if (!list_empty(&drive->queue.queue_head) && (!drive->PADAM_sleep || 0 <= (signed long)(jiffies - drive->PADAM_sleep))) {
+		if (!list_empty(&drive->queue.queue_head)
+		&& (!drive->PADAM_sleep	|| time_after_eq(drive->PADAM_sleep, jiffies))) {
 			if (!best
-			 || (drive->PADAM_sleep && (!best->PADAM_sleep || 0 < (signed long)(best->PADAM_sleep - drive->PADAM_sleep)))
-			 || (!best->PADAM_sleep && 0 < (signed long)((best->PADAM_service_start + 2 * best->PADAM_service_time)
-					 - (drive->PADAM_service_start + 2 * drive->PADAM_service_time))))
+			 || (drive->PADAM_sleep && (!best->PADAM_sleep || time_after(best->PADAM_sleep, drive->PADAM_sleep)))
+			 || (!best->PADAM_sleep && time_after(best->PADAM_service_start + 2 * best->PADAM_service_time, drive->PADAM_service_start + 2 * drive->PADAM_service_time)))
 			{
 				if (!blk_queue_plugged(&drive->queue))
 					best = drive;
 			}
 		}
 	} while ((drive = drive->next) != hwgroup->drive);
-	if (best && best->nice1 && !best->PADAM_sleep && best != hwgroup->drive && best->PADAM_service_time > WAIT_MIN_SLEEP) {
-		long t = (signed long)((best->PADAM_service_start + 2 * best->PADAM_service_time) - jiffies);
-		if (t >= WAIT_MIN_SLEEP) {
-			/*
-			 * We *may* have some time to spare, but first let's see if
-			 * someone can potentially benefit from our nice mood today..
-			 */
-			drive = best->next;
-			do {
-				if (!drive->PADAM_sleep
-				 && 0 < (signed long)((drive->PADAM_service_start + 2 * drive->PADAM_service_time) - (jiffies - best->PADAM_service_time))
-				 && 0 < (signed long)((jiffies + t) - (drive->PADAM_service_start + 2 * drive->PADAM_service_time)))
-				{
-					ide_stall_queue(best, min(t, 10L * WAIT_MIN_SLEEP));
-					goto repeat;
-				}
-			} while ((drive = drive->next) != best);
-		}
-	}
 	return best;
 }
 
@@ -1298,7 +1278,7 @@
 			hwgroup->rq = NULL;
 			drive = hwgroup->drive;
 			do {
-				if (drive->PADAM_sleep && (!sleep || 0 < (signed long)(sleep - drive->PADAM_sleep)))
+				if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
 					sleep = drive->PADAM_sleep;
 			} while ((drive = drive->next) != hwgroup->drive);
 			if (sleep) {
@@ -1968,23 +1948,22 @@
 #endif
 }
 
-void ide_unregister(struct ata_channel *hwif)
+void ide_unregister(struct ata_channel *channel)
 {
 	struct gendisk *gd;
 	ide_drive_t *drive, *d;
-	struct ata_channel *g;
 	ide_hwgroup_t *hwgroup;
-	int irq_count = 0, unit, i;
+	int unit, i;
 	unsigned long flags;
 	unsigned int p, minor;
 	struct ata_channel old_hwif;
 
 	spin_lock_irqsave(&ide_lock, flags);
-	if (!hwif->present)
+	if (!channel->present)
 		goto abort;
-	put_device(&hwif->device);
+	put_device(&channel->dev);
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		drive = &hwif->drives[unit];
+		drive = &channel->drives[unit];
 		if (!drive->present)
 			continue;
 		if (drive->busy || drive->usage)
@@ -1997,43 +1976,47 @@
 				ide_unregister_subdriver(drive);
 		}
 	}
-	hwif->present = 0;
+	channel->present = 0;
 
 	/*
 	 * All clear?  Then blow away the buffer cache
 	 */
 	spin_unlock_irqrestore(&ide_lock, flags);
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		drive = &hwif->drives[unit];
+		drive = &channel->drives[unit];
 		if (!drive->present)
 			continue;
 		minor = drive->select.b.unit << PARTN_BITS;
 		for (p = 0; p < (1<<PARTN_BITS); ++p) {
 			if (drive->part[p].nr_sects > 0) {
-				kdev_t devp = mk_kdev(hwif->major, minor+p);
+				kdev_t devp = mk_kdev(channel->major, minor+p);
 				invalidate_device(devp, 0);
 			}
 		}
 	}
 #ifdef CONFIG_PROC_FS
-	destroy_proc_ide_drives(hwif);
+	destroy_proc_ide_drives(channel);
 #endif
 	spin_lock_irqsave(&ide_lock, flags);
-	hwgroup = hwif->hwgroup;
+	hwgroup = channel->hwgroup;
 
 	/*
 	 * free the irq if we were the only hwif using it
 	 */
-	g = hwgroup->hwif;
-	do {
-		if (g->irq == hwif->irq)
-			++irq_count;
-		g = g->next;
-	} while (g != hwgroup->hwif);
-	if (irq_count == 1)
-		free_irq(hwif->irq, hwgroup);
-
-	hwif_unregister(hwif);
+	{
+		struct ata_channel *g;
+		int irq_count = 0;
+
+		g = hwgroup->hwif;
+		do {
+			if (g->irq == channel->irq)
+				++irq_count;
+			g = g->next;
+		} while (g != hwgroup->hwif);
+		if (irq_count == 1)
+			free_irq(channel->irq, hwgroup);
+	}
+	hwif_unregister(channel);
 
 	/*
 	 * Remove us from the hwgroup, and free
@@ -2041,7 +2024,7 @@
 	 */
 	d = hwgroup->drive;
 	for (i = 0; i < MAX_DRIVES; ++i) {
-		drive = &hwif->drives[i];
+		drive = &channel->drives[i];
 		if (drive->de) {
 			devfs_unregister (drive->de);
 			drive->de = NULL;
@@ -2062,27 +2045,27 @@
 	}
 	if (d->present)
 		hwgroup->drive = d;
-	while (hwgroup->hwif->next != hwif)
+	while (hwgroup->hwif->next != channel)
 		hwgroup->hwif = hwgroup->hwif->next;
-	hwgroup->hwif->next = hwif->next;
-	if (hwgroup->hwif == hwif)
+	hwgroup->hwif->next = channel->next;
+	if (hwgroup->hwif == channel)
 		kfree(hwgroup);
 	else
 		hwgroup->hwif = hwgroup->drive->channel;
 
 #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
-	ide_release_dma(hwif);
+	ide_release_dma(channel);
 #endif
 
 	/*
 	 * Remove us from the kernel's knowledge
 	 */
-	unregister_blkdev(hwif->major, hwif->name);
-	kfree(blksize_size[hwif->major]);
-	blk_dev[hwif->major].data = NULL;
-	blk_dev[hwif->major].queue = NULL;
-	blk_clear(hwif->major);
-	gd = hwif->gd;
+	unregister_blkdev(channel->major, channel->name);
+	kfree(blksize_size[channel->major]);
+	blk_dev[channel->major].data = NULL;
+	blk_dev[channel->major].queue = NULL;
+	blk_clear(channel->major);
+	gd = channel->gd;
 	if (gd) {
 		del_gendisk(gd);
 		kfree(gd->sizes);
@@ -2092,45 +2075,45 @@
 		if (gd->flags)
 			kfree (gd->flags);
 		kfree(gd);
-		hwif->gd = NULL;
+		channel->gd = NULL;
 	}
 
 	/*
-	 * Reinitialize the hwif handler, but preserve any special methods for
+	 * Reinitialize the channel handler, but preserve any special methods for
 	 * it.
 	 */
 
-	old_hwif		= *hwif;
-	init_hwif_data(hwif, hwif->index);
-	hwif->hwgroup		= old_hwif.hwgroup;
-	hwif->tuneproc		= old_hwif.tuneproc;
-	hwif->speedproc		= old_hwif.speedproc;
-	hwif->selectproc	= old_hwif.selectproc;
-	hwif->resetproc		= old_hwif.resetproc;
-	hwif->intrproc		= old_hwif.intrproc;
-	hwif->maskproc		= old_hwif.maskproc;
-	hwif->quirkproc		= old_hwif.quirkproc;
-	hwif->rwproc		= old_hwif.rwproc;
-	hwif->ideproc		= old_hwif.ideproc;
-	hwif->dmaproc		= old_hwif.dmaproc;
-	hwif->busproc		= old_hwif.busproc;
-	hwif->bus_state		= old_hwif.bus_state;
-	hwif->dma_base		= old_hwif.dma_base;
-	hwif->dma_extra		= old_hwif.dma_extra;
-	hwif->config_data	= old_hwif.config_data;
-	hwif->select_data	= old_hwif.select_data;
-	hwif->proc		= old_hwif.proc;
+	old_hwif		= *channel;
+	init_hwif_data(channel, channel->index);
+	channel->hwgroup = old_hwif.hwgroup;
+	channel->tuneproc = old_hwif.tuneproc;
+	channel->speedproc = old_hwif.speedproc;
+	channel->selectproc = old_hwif.selectproc;
+	channel->resetproc = old_hwif.resetproc;
+	channel->intrproc = old_hwif.intrproc;
+	channel->maskproc = old_hwif.maskproc;
+	channel->quirkproc = old_hwif.quirkproc;
+	channel->rwproc	= old_hwif.rwproc;
+	channel->ideproc = old_hwif.ideproc;
+	channel->dmaproc = old_hwif.dmaproc;
+	channel->busproc = old_hwif.busproc;
+	channel->bus_state = old_hwif.bus_state;
+	channel->dma_base = old_hwif.dma_base;
+	channel->dma_extra = old_hwif.dma_extra;
+	channel->config_data = old_hwif.config_data;
+	channel->select_data = old_hwif.select_data;
+	channel->proc = old_hwif.proc;
 #ifndef CONFIG_BLK_DEV_IDECS
-	hwif->irq		= old_hwif.irq;
+	channel->irq = old_hwif.irq;
 #endif
-	hwif->major		= old_hwif.major;
-	hwif->chipset		= old_hwif.chipset;
-	hwif->autodma		= old_hwif.autodma;
-	hwif->udma_four		= old_hwif.udma_four;
+	channel->major = old_hwif.major;
+	channel->chipset = old_hwif.chipset;
+	channel->autodma = old_hwif.autodma;
+	channel->udma_four = old_hwif.udma_four;
 #ifdef CONFIG_BLK_DEV_IDEPCI
-	hwif->pci_dev		= old_hwif.pci_dev;
+	channel->pci_dev = old_hwif.pci_dev;
 #endif
-	hwif->straight8		= old_hwif.straight8;
+	channel->straight8 = old_hwif.straight8;
 abort:
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
@@ -2419,7 +2402,6 @@
  */
 	ide_add_setting(drive,	"io_32bit",		drive->no_io_32bit ? SETTING_READ : SETTING_RW,	HDIO_GET_32BIT,		HDIO_SET_32BIT,		TYPE_BYTE,	0,	1 + (SUPPORT_VLB_SYNC << 1),	1,		1,		&drive->io_32bit,		set_io_32bit);
 	ide_add_setting(drive,	"keepsettings",		SETTING_RW,					HDIO_GET_KEEPSETTINGS,	HDIO_SET_KEEPSETTINGS,	TYPE_BYTE,	0,	1,				1,		1,		&drive->keep_settings,		NULL);
-	ide_add_setting(drive,	"nice1",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	1,				1,		1,		&drive->nice1,			NULL);
 	ide_add_setting(drive,	"pio_mode",		SETTING_WRITE,					-1,			HDIO_SET_PIO_MODE,	TYPE_BYTE,	0,	255,				1,		1,		NULL,				set_pio_mode);
 	ide_add_setting(drive,	"slow",			SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	1,				1,		1,		&drive->slow,			NULL);
 	ide_add_setting(drive,	"unmaskirq",		drive->no_unmask ? SETTING_READ : SETTING_RW,	HDIO_GET_UNMASKINTR,	HDIO_SET_UNMASKINTR,	TYPE_BYTE,	0,	1,				1,		1,		&drive->unmask,			NULL);
@@ -2545,10 +2527,7 @@
 
 		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->atapi_overlap	<<	IDE_NICE_ATAPI_OVERLAP,
 					(long *) arg);
 
 		case HDIO_DRIVE_CMD:
@@ -2563,7 +2542,7 @@
 
 		case HDIO_SET_NICE:
 			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-			if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
+			if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP))))
 				return -EPERM;
 			drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1;
 			/* Only CD-ROM's and tapes support DSC overlap. */
@@ -2571,7 +2550,6 @@
 				drive->dsc_overlap = 0;
 				return -EPERM;
 			}
-			drive->nice1 = (arg >> IDE_NICE_1) & 1;
 			return 0;
 		case BLKGETSIZE:
 		case BLKGETSIZE64:
@@ -3151,7 +3129,7 @@
 	}
 
 	/* FIXME: This will be pushed to the drivers! Thus allowing us to
-	 * save one parameter here eparate this out.
+	 * save one parameter here separate this out.
 	 */
 
 	drive->driver = driver;
@@ -3175,7 +3153,6 @@
 		/* Only CD-ROMs and tape drives support DSC overlap. */
 		drive->dsc_overlap = (drive->next != drive
 				&& (drive->type == ATA_ROM || drive->type == ATA_TAPE));
-		drive->nice1 = 1;
 	}
 	drive->revalidate = 1;
 	drive->suspend_reset = 0;
diff -urN linux-2.5.7/drivers/ide/ns87415.c linux/drivers/ide/ns87415.c
--- linux-2.5.7/drivers/ide/ns87415.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/ns87415.c	Fri Mar 22 02:22:40 2002
@@ -43,12 +43,12 @@
 	new = *old;
 
 	/* Adjust IRQ enable bit */
-	bit = 1 << (8 + hwif->channel);
+	bit = 1 << (8 + hwif->unit);
 	new = drive->present ? (new & ~bit) : (new | bit);
 
 	/* Select PIO or DMA, DMA may only be selected for one drive/channel. */
-	bit   = 1 << (20 + drive->select.b.unit       + (hwif->channel << 1));
-	other = 1 << (20 + (1 - drive->select.b.unit) + (hwif->channel << 1));
+	bit   = 1 << (20 + drive->select.b.unit       + (hwif->unit << 1));
+	other = 1 << (20 + (1 - drive->select.b.unit) + (hwif->unit << 1));
 	new = use_dma ? ((new & ~other) | bit) : (new & ~bit);
 
 	if (new != *old) {
@@ -138,9 +138,9 @@
 	(void) pci_read_config_dword(dev, 0x40, &ctrl);
 	(void) pci_read_config_byte(dev, 0x09, &progif);
 	/* is irq in "native" mode? */
-	using_inta = progif & (1 << (hwif->channel << 1));
+	using_inta = progif & (1 << (hwif->unit << 1));
 	if (!using_inta)
-		using_inta = ctrl & (1 << (4 + hwif->channel));
+		using_inta = ctrl & (1 << (4 + hwif->unit));
 	if (hwif->mate) {
 		hwif->select_data = hwif->mate->select_data;
 	} else {
@@ -180,7 +180,7 @@
 		outb(0x60, hwif->dma_base + 2);
 
 	if (!using_inta)
-		hwif->irq = hwif->channel ? 15 : 14;	/* legacy mode */
+		hwif->irq = hwif->unit ? 15 : 14;	/* legacy mode */
 	else if (!hwif->irq && hwif->mate && hwif->mate->irq)
 		hwif->irq = hwif->mate->irq;	/* share IRQ with mate */
 
diff -urN linux-2.5.7/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.5.7/drivers/ide/pdc202xx.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/pdc202xx.c	Fri Mar 22 02:26:12 2002
@@ -530,7 +530,7 @@
 #else
 	struct pci_dev *dev	= hwif->pci_dev;
 	unsigned long high_16	= pci_resource_start(dev, 4);
-	unsigned long indexreg	= high_16 + (hwif->channel ? 0x09 : 0x01);
+	unsigned long indexreg	= high_16 + (hwif->unit ? 0x09 : 0x01);
 	unsigned long datareg	= (indexreg + 2);
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 	byte thold		= 0x10;
@@ -725,8 +725,8 @@
 	byte udma_66		= ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0;
 	byte udma_100		= 0;
 	byte udma_133		= 0;
-	byte mask		= hwif->channel ? 0x08 : 0x02;
-	unsigned short c_mask	= hwif->channel ? (1<<11) : (1<<10);
+	byte mask		= hwif->unit ? 0x08 : 0x02;
+	unsigned short c_mask	= hwif->unit ? (1<<11) : (1<<10);
 
 	byte ultra_66		= ((id->dma_ultra & 0x0010) ||
 				   (id->dma_ultra & 0x0008)) ? 1 : 0;
@@ -792,14 +792,14 @@
 
 	if (((ultra_66) || (ultra_100) || (ultra_133)) && (cable)) {
 #ifdef DEBUG
-		printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary");
+		printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->unit ? "Secondary" : "Primary");
 		printk("         Switching to Ultra33 mode.\n");
 #endif /* DEBUG */
 		/* Primary   : zero out second bit */
 		/* Secondary : zero out fourth bit */
 		if (!jumpbit)
 			OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
-		printk("Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary");
+		printk("Warning: %s channel requires an 80-pin cable for operation.\n", hwif->unit ? "Secondary":"Primary");
 		printk("%s reduced to Ultra33 mode.\n", drive->name);
 		udma_66 = 0; udma_100 = 0; udma_133 = 0;
 	} else {
@@ -990,7 +990,7 @@
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
 	unsigned long high_16	= pci_resource_start(dev, 4);
-	unsigned long atapi_reg	= high_16 + (hwif->channel ? 0x24 : 0x00);
+	unsigned long atapi_reg	= high_16 + (hwif->unit ? 0x24 : 0x00);
 	unsigned long dma_base	= hwif->dma_base;
 
 	switch (dev->device) {
@@ -1023,7 +1023,7 @@
 				struct request *rq = HWGROUP(drive)->rq;
 				unsigned long word_count = 0;
 
-				outb(clock|(hwif->channel ? 0x08 : 0x02), high_16 + 0x11);
+				outb(clock|(hwif->unit ? 0x08 : 0x02), high_16 + 0x11);
 				word_count = (rq->nr_sectors << 8);
 				word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000;
 				outl(word_count, atapi_reg);
@@ -1033,7 +1033,7 @@
 			if ((drive->addressing) && (hardware48hack)) {
 				outl(0, atapi_reg);	/* zero out extra */
 				clock = IN_BYTE(high_16 + 0x11);
-				OUT_BYTE(clock & ~(hwif->channel ? 0x08:0x02), high_16 + 0x11);
+				OUT_BYTE(clock & ~(hwif->unit ? 0x08:0x02), high_16 + 0x11);
 			}
 			break;
 		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
@@ -1042,7 +1042,7 @@
 				return (dma_stat & 4) == 4;
 
 			sc1d = IN_BYTE(high_16 + 0x001d);
-			if (drive->channel->channel) {
+			if (drive->channel->unit) {
 				if ((sc1d & 0x50) == 0x50) goto somebody_else;
 				else if ((sc1d & 0x40) == 0x40)
 					return (dma_stat & 4) == 4;
@@ -1071,7 +1071,7 @@
 	OUT_BYTE(0x00,IDE_CONTROL_REG);
 	mdelay(1000);
 	printk("PDC202XX: %s channel reset.\n",
-		drive->channel->channel ? "Secondary" : "Primary");
+		drive->channel->unit ? "Secondary" : "Primary");
 }
 
 void pdc202xx_reset (ide_drive_t *drive)
@@ -1084,7 +1084,7 @@
 	OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
 	mdelay(2000);		/* 2 seconds ?! */
 	printk("PDC202XX: %s channel reset.\n",
-		drive->channel->channel ? "Secondary" : "Primary");
+		drive->channel->unit ? "Secondary" : "Primary");
 }
 
 /*
@@ -1218,7 +1218,7 @@
 
 unsigned int __init ata66_pdc202xx(struct ata_channel *hwif)
 {
-	unsigned short mask = (hwif->channel) ? (1<<11) : (1<<10);
+	unsigned short mask = (hwif->unit) ? (1<<11) : (1<<10);
 	unsigned short CIS;
 
         switch(hwif->pci_dev->device) {
diff -urN linux-2.5.7/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c
--- linux-2.5.7/drivers/ide/pdc4030.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/pdc4030.c	Fri Mar 22 02:27:02 2002
@@ -99,7 +99,7 @@
 {
 	unsigned int number;
 
-	number = (drive->channel->channel << 1) + drive->select.b.unit;
+	number = (drive->channel->unit << 1) + drive->select.b.unit;
 	OUT_BYTE(number,IDE_FEATURE_REG);
 }
 
@@ -226,7 +226,7 @@
 	hwif->chipset	= hwif2->chipset = ide_pdc4030;
 	hwif->mate	= hwif2;
 	hwif2->mate	= hwif;
-	hwif2->channel	= 1;
+	hwif2->unit	= 1;
 	hwif->selectproc = hwif2->selectproc = &promise_selectproc;
 	hwif->serialized = hwif2->serialized = 1;
 
diff -urN linux-2.5.7/drivers/ide/piix.c linux/drivers/ide/piix.c
--- linux-2.5.7/drivers/ide/piix.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/piix.c	Fri Mar 22 02:28:22 2002
@@ -357,7 +357,7 @@
 
 static void piix_tune_drive(ide_drive_t *drive, unsigned char pio)
 {
-	if (!((piix_enabled >> drive->channel->channel) & 1))
+	if (!((piix_enabled >> drive->channel->unit) & 1))
 		return;
 
 	if (pio == 255) {
@@ -535,7 +535,7 @@
 
 unsigned int __init ata66_piix(struct ata_channel *hwif)
 {
-	return ((piix_enabled & piix_80w) >> hwif->channel) & 1;
+	return ((piix_enabled & piix_80w) >> hwif->unit) & 1;
 }
 
 void __init ide_init_piix(struct ata_channel *hwif)
@@ -550,7 +550,7 @@
 		hwif->drives[i].io_32bit = 1;
 		hwif->drives[i].unmask = 1;
 		hwif->drives[i].autotune = 1;
-		hwif->drives[i].dn = hwif->channel * 2 + i;
+		hwif->drives[i].dn = hwif->unit * 2 + i;
 	}
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -572,7 +572,7 @@
 
 void __init ide_dmacapable_piix(struct ata_channel *hwif, unsigned long dmabase)
 {
-	if (((piix_enabled >> hwif->channel) & 1)
+	if (((piix_enabled >> hwif->unit) & 1)
 		&& !(piix_config->flags & PIIX_NODMA))
 			ide_setup_dma(hwif, dmabase, 8);
 }
diff -urN linux-2.5.7/drivers/ide/qd65xx.c linux/drivers/ide/qd65xx.c
--- linux-2.5.7/drivers/ide/qd65xx.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/qd65xx.c	Fri Mar 22 02:29:05 2002
@@ -291,7 +291,7 @@
 		printk(KERN_INFO "%s: PIO mode%d\n", drive->name, pio - XFER_PIO_0);
 	}
 
-	if (!drive->channel->channel && drive->type != ATA_DISK) {
+	if (!drive->channel->unit && drive->type != ATA_DISK) {
 		qd_write_reg(0x5f,QD_CONTROL_PORT);
 		printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO and post-write buffer on %s.\n",drive->name, drive->channel->name);
 	}
@@ -420,7 +420,7 @@
 
 				ide_hwifs[i].chipset = ide_qd65xx;
 				ide_hwifs[i].mate = &ide_hwifs[i^1];
-				ide_hwifs[i].channel = i;
+				ide_hwifs[i].unit = i;
 
 				ide_hwifs[i].select_data = base;
 				ide_hwifs[i].config_data = config | (control <<8);
diff -urN linux-2.5.7/drivers/ide/rz1000.c linux/drivers/ide/rz1000.c
--- linux-2.5.7/drivers/ide/rz1000.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/rz1000.c	Fri Mar 22 02:39:41 2002
@@ -71,7 +71,7 @@
 				hwif->drives[0].no_unmask = 1;
 				hwif->drives[1].no_unmask = 1;
 				if (hwif->io_ports[IDE_DATA_OFFSET] == 0x170)
-					hwif->channel = 1;
+					hwif->unit = 1;
 				printk("%s: serialized, disabled unmasking (buggy %s)\n", hwif->name, name);
 			}
 		}
diff -urN linux-2.5.7/drivers/ide/serverworks.c linux/drivers/ide/serverworks.c
--- linux-2.5.7/drivers/ide/serverworks.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/serverworks.c	Fri Mar 22 02:23:40 2002
@@ -255,7 +255,7 @@
 
 	byte drive_pci		= 0x00;
 	byte drive_pci2		= 0x00;
-	byte drive_pci3		= hwif->channel ? 0x57 : 0x56;
+	byte drive_pci3		= hwif->unit ? 0x57 : 0x56;
 
 	byte ultra_enable	= 0x00;
 	byte ultra_timing	= 0x00;
@@ -590,7 +590,7 @@
 	if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
 	    dev->vendor	== PCI_VENDOR_ID_SERVERWORKS &&
 	    dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
-		return ((1 << (hwif->channel + 14)) &
+		return ((1 << (hwif->unit + 14)) &
 			dev->subsystem_device) ? 1 : 0;
 	return 0;
 }
@@ -607,7 +607,7 @@
 	if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&
 	    dev->vendor	== PCI_VENDOR_ID_SERVERWORKS &&
 	    dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
-		return ((1 << (hwif->channel + 14)) &
+		return ((1 << (hwif->unit + 14)) &
 			dev->subsystem_device) ? 1 : 0;
 	return 0;
 }
@@ -630,7 +630,7 @@
 void __init ide_init_svwks(struct ata_channel *hwif)
 {
 	if (!hwif->irq)
-		hwif->irq = hwif->channel ? 15 : 14;
+		hwif->irq = hwif->unit ? 15 : 14;
 
 	hwif->tuneproc = &svwks_tune_drive;
 	hwif->speedproc = &svwks_tune_chipset;
diff -urN linux-2.5.7/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c
--- linux-2.5.7/drivers/ide/sis5513.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/sis5513.c	Fri Mar 22 02:29:45 2002
@@ -844,7 +844,7 @@
 unsigned int __init ata66_sis5513(struct ata_channel *hwif)
 {
 	byte reg48h = 0, ata66 = 0;
-	byte mask = hwif->channel ? 0x20 : 0x10;
+	byte mask = hwif->unit ? 0x20 : 0x10;
 	pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h);
 
 	if (dma_capability >= ATA_66) {
@@ -856,7 +856,7 @@
 void __init ide_init_sis5513(struct ata_channel *hwif)
 {
 
-	hwif->irq = hwif->channel ? 15 : 14;
+	hwif->irq = hwif->unit ? 15 : 14;
 
 	hwif->tuneproc = &sis5513_tune_drive;
 	hwif->speedproc = &sis5513_tune_chipset;
diff -urN linux-2.5.7/drivers/ide/sl82c105.c linux/drivers/ide/sl82c105.c
--- linux-2.5.7/drivers/ide/sl82c105.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/sl82c105.c	Fri Mar 22 02:36:44 2002
@@ -63,7 +63,7 @@
 	unsigned short drv_ctrl = 0x909;
 	unsigned int xfer_mode, reg;
 
-	reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
+	reg = (hwif->unit ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
 
 	if (pio == 255)
 		xfer_mode = ata_timing_mode(drive, XFER_PIO | XFER_EPIO);
@@ -100,7 +100,7 @@
 	unsigned short drv_ctrl = 0x909;
 	unsigned int reg;
 
-	reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
+	reg = (hwif->unit ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
 
 	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) == 0)
 		drv_ctrl = 0x0240;
diff -urN linux-2.5.7/drivers/ide/trm290.c linux/drivers/ide/trm290.c
--- linux-2.5.7/drivers/ide/trm290.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/trm290.c	Fri Mar 22 02:31:23 2002
@@ -153,14 +153,14 @@
 
 	if (reg != hwif->select_data) {
 		hwif->select_data = reg;
-		outb(0x51|(hwif->channel<<3), hwif->config_data+1);	/* set PIO/DMA */
+		outb(0x51|(hwif->unit<<3), hwif->config_data+1);	/* set PIO/DMA */
 		outw(reg & 0xff, hwif->config_data);
 	}
 
 	/* enable IRQ if not probing */
 	if (drive->present) {
 		reg = inw(hwif->config_data+3) & 0x13;
-		reg &= ~(1 << hwif->channel);
+		reg &= ~(1 << hwif->unit);
 		outw(reg, hwif->config_data+3);
 	}
 
@@ -237,7 +237,7 @@
 	__save_flags(flags);	/* local CPU only */
 	__cli();		/* local CPU only */
 	/* put config reg into first byte of hwif->select_data */
-	outb(0x51|(hwif->channel<<3), hwif->config_data+1);
+	outb(0x51|(hwif->unit<<3), hwif->config_data+1);
 	hwif->select_data = 0x21;			/* select PIO as default */
 	outb(hwif->select_data, hwif->config_data);
 	reg = inb(hwif->config_data+3);			/* get IRQ info */
@@ -246,10 +246,10 @@
 	__restore_flags(flags);	/* local CPU only */
 
 	if ((reg & 0x10))
-		hwif->irq = hwif->channel ? 15 : 14;	/* legacy mode */
+		hwif->irq = hwif->unit ? 15 : 14;	/* legacy mode */
 	else if (!hwif->irq && hwif->mate && hwif->mate->irq)
 		hwif->irq = hwif->mate->irq;		/* sharing IRQ with mate */
-	ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
+	ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->unit ? 0x0080 : 0x0000), 3);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	hwif->dmaproc = &trm290_dmaproc;
@@ -264,10 +264,10 @@
 		 * for the control basereg, so this kludge ensures that we use only
 		 * values that are known to work.  Ugh.		-ml
 		 */
-		unsigned short old, compat = hwif->channel ? 0x374 : 0x3f4;
+		unsigned short old, compat = hwif->unit ? 0x374 : 0x3f4;
 		static unsigned short next_offset = 0;
 
-		outb(0x54|(hwif->channel<<3), hwif->config_data+1);
+		outb(0x54|(hwif->unit<<3), hwif->config_data+1);
 		old = inw(hwif->config_data) & ~1;
 		if (old != compat && inb(old+2) == 0xff) {
 			compat += (next_offset += 0x400);	/* leave lower 10 bits untouched */
diff -urN linux-2.5.7/drivers/ide/umc8672.c linux/drivers/ide/umc8672.c
--- linux-2.5.7/drivers/ide/umc8672.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/umc8672.c	Fri Mar 22 02:31:45 2002
@@ -160,5 +160,5 @@
 	ide_hwifs[1].tuneproc = &tune_umc;
 	ide_hwifs[0].mate = &ide_hwifs[1];
 	ide_hwifs[1].mate = &ide_hwifs[0];
-	ide_hwifs[1].channel = 1;
+	ide_hwifs[1].unit = 1;
 }
diff -urN linux-2.5.7/drivers/ide/via82cxxx.c linux/drivers/ide/via82cxxx.c
--- linux-2.5.7/drivers/ide/via82cxxx.c	Thu Mar 21 23:54:17 2002
+++ linux/drivers/ide/via82cxxx.c	Fri Mar 22 02:32:43 2002
@@ -344,7 +344,7 @@
 
 static void via82cxxx_tune_drive(ide_drive_t *drive, unsigned char pio)
 {
-	if (!((via_enabled >> drive->channel->channel) & 1))
+	if (!((via_enabled >> drive->channel->unit) & 1))
 		return;
 
 	if (pio == 255) {
@@ -525,7 +525,7 @@
 
 unsigned int __init ata66_via82cxxx(struct ata_channel *hwif)
 {
-	return ((via_enabled & via_80w) >> hwif->channel) & 1;
+	return ((via_enabled & via_80w) >> hwif->unit) & 1;
 }
 
 void __init ide_init_via82cxxx(struct ata_channel *hwif)
@@ -540,7 +540,7 @@
 		hwif->drives[i].io_32bit = 1;
 		hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
 		hwif->drives[i].autotune = 1;
-		hwif->drives[i].dn = hwif->channel * 2 + i;
+		hwif->drives[i].dn = hwif->unit * 2 + i;
 	}
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -561,6 +561,6 @@
 
 void __init ide_dmacapable_via82cxxx(struct ata_channel *hwif, unsigned long dmabase)
 {
-	if ((via_enabled >> hwif->channel) & 1)
+	if ((via_enabled >> hwif->unit) & 1)
 		ide_setup_dma(hwif, dmabase, 8);
 }
diff -urN linux-2.5.7/include/linux/hdreg.h linux/include/linux/hdreg.h
--- linux-2.5.7/include/linux/hdreg.h	Thu Mar 21 23:26:22 2002
+++ linux/include/linux/hdreg.h	Fri Mar 22 01:36:43 2002
@@ -584,8 +584,5 @@
  */
 #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 */
-#define IDE_NICE_2		(4)	/* when we know it's on our expense */
 
 #endif	/* _LINUX_HDREG_H */
diff -urN linux-2.5.7/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.7/include/linux/ide.h	Thu Mar 21 23:54:17 2002
+++ linux/include/linux/ide.h	Fri Mar 22 01:48:51 2002
@@ -271,14 +271,14 @@
 typedef struct ide_drive_s {
 	struct ata_channel *channel;	/* parent pointer to the channel we are attached to  */
 
-	unsigned int	usage;		/* current "open()" count for drive */
+	unsigned int usage;		/* current "open()" count for drive */
 	char type; /* distingiush different devices: disk, cdrom, tape, floppy, ... */
 
 	/* NOTE: If we had proper separation between channel and host chip, we
 	 * could move this to the chanell and many sync problems would
 	 * magically just go away.
 	 */
-	request_queue_t		 queue;	/* per device request queue */
+	request_queue_t	queue;	/* per device request queue */
 
 	struct ide_drive_s	*next;	/* circular list of hwgroup drives */
 
@@ -300,7 +300,6 @@
 	byte     slow;			/* flag: slow data port */
 	byte     bswap;			/* flag: byte swap data */
 	byte     dsc_overlap;		/* flag: DSC overlap */
-	byte     nice1;			/* flag: give potential excess bandwidth */
 	unsigned waiting_for_dma: 1;	/* dma currently in progress */
 	unsigned present	: 1;	/* drive is physically present */
 	unsigned noprobe	: 1;	/* from:  hdx=noprobe */
@@ -312,8 +311,6 @@
 	unsigned nobios		: 1;	/* flag: do not probe bios for drive */
 	unsigned revalidate	: 1;	/* request revalidation */
 	unsigned atapi_overlap	: 1;	/* flag: ATAPI overlap (not supported) */
-	unsigned nice0		: 1;	/* flag: give obvious excess bandwidth */
-	unsigned nice2		: 1;	/* flag: give a share in our own bandwidth */
 	unsigned doorlocking	: 1;	/* flag: for removable only: door lock/unlock works */
 	unsigned autotune	: 2;	/* 1=autotune, 2=noautotune, 0=default */
 	unsigned remap_0_to_1	: 2;	/* 0=remap if ezdrive, 1=remap, 2=noremap */
@@ -440,10 +437,17 @@
 typedef int (ide_busproc_t) (ide_drive_t *, int);
 
 struct ata_channel {
+	struct device	dev;		/* device handle */
+	int		unit;		/* channel number */
+
 	struct ata_channel *next;	/* for linked-list in ide_hwgroup_t */
 	struct hwgroup_s *hwgroup;	/* actually (ide_hwgroup_t *) */
+
 	ide_ioreg_t	io_ports[IDE_NR_PORTS];	/* task file registers */
 	hw_regs_t	hw;		/* Hardware info */
+#ifdef CONFIG_BLK_DEV_IDEPCI
+	struct pci_dev	*pci_dev;	/* for pci chipsets */
+#endif
 	ide_drive_t	drives[MAX_DRIVES];	/* drive info */
 	struct gendisk	*gd;		/* gendisk structure */
 	ide_tuneproc_t	*tuneproc;	/* routine to tune PIO mode for drives */
@@ -480,17 +484,12 @@
 	unsigned	autodma    : 1;	/* automatically try to enable DMA at boot */
 	unsigned	udma_four  : 1;	/* 1=ATA-66 capable, 0=default */
 	unsigned	highmem	   : 1; /* can do full 32-bit dma */
-	byte		channel;	/* for dual-port chips: 0=primary, 1=secondary */
-#ifdef CONFIG_BLK_DEV_IDEPCI
-	struct pci_dev	*pci_dev;	/* for pci chipsets */
-#endif
 #if (DISK_RECOVERY_TIME > 0)
 	unsigned long	last_time;	/* time when previous rq was done */
 #endif
 	byte		straight8;	/* Alan's straight 8 check */
 	ide_busproc_t	*busproc;	/* driver soft-power interface */
 	byte		bus_state;	/* power state of the IDE bus */
-	struct device	device;		/* global device tree handle */
 };
 
 /*

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

* [PATCH] 2.5.7 IDE 28a
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (5 preceding siblings ...)
  2002-03-28  9:31 ` [PATCH] 2.5.7 IDE 27 Martin Dalecki
@ 2002-03-28  9:32 ` Martin Dalecki
  2002-04-15  7:42 ` [PATCH] 2.5.8 IDE 34 Martin Dalecki
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-03-28  9:32 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Fri Mar 22 13:43:55 CET 2002 ide-clean-28a

- Apply Pavel Macheks suspend resume double resume fix.

- Finally remove the busy field for ata_operations and replace it with
   MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT.

- Fix ali15xx chipset support by removing initialization differences,
   apparently caused by mislead interpretation of the specs or a mismatch
   between the specification and reality.

- Guard calls to ide_set_handler with checks to see whatever the previously
   installed IRQ handler already served it's purpose.

- Convert timeout checks on poll_timeout to the time_before() interface.

- Consolidate the two different IRQ handlers for multi mode PIO writes into
   one. The problems remain the same but at least now we will only have to
   tangle one single problem.

[-- Attachment #2: ide-clean-28a.diff --]
[-- Type: text/plain, Size: 32966 bytes --]

diff -urN linux-2.5.7/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- linux-2.5.7/arch/cris/drivers/ide.c	Thu Mar 28 06:59:54 2002
+++ linux/arch/cris/drivers/ide.c	Wed Mar 27 02:47:13 2002
@@ -798,7 +798,7 @@
 	 * not a diskdrive.
 	 */
 
-        if (drive->media != ide_disk)
+        if (drive->type != ATA_DISK)
                 return 0;
 
  dma_begin:
@@ -809,7 +809,7 @@
 		WAIT_DMA(ATA_RX_DMA_NBR);
 
 		/* set up the Etrax DMA descriptors */
-		
+
 		if(e100_ide_build_dmatable (drive))
 			return 1;
 
diff -urN linux-2.5.7/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- linux-2.5.7/drivers/ide/hpt34x.c	Thu Mar 28 06:59:54 2002
+++ linux/drivers/ide/hpt34x.c	Wed Mar 27 02:47:13 2002
@@ -334,6 +334,7 @@
 			drive->waiting_for_dma = 1;
 			if (drive->type != ATA_DISK)
 				return 0;
+			BUG_ON(HWGROUP(drive)->handler);
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);	/* issue cmd to drive */
 			OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 			return 0;
diff -urN linux-2.5.7/drivers/ide/icside.c linux/drivers/ide/icside.c
--- linux-2.5.7/drivers/ide/icside.c	Thu Mar 28 06:59:56 2002
+++ linux/drivers/ide/icside.c	Wed Mar 27 02:47:13 2002
@@ -441,9 +441,10 @@
 			     : DMA_MODE_WRITE);
 
 		drive->waiting_for_dma = 1;
-		if (drive->media != ide_disk)
+		if (drive->type != ATA_DISK)
 			return 0;
 
+		BUG_ON(HWGROUP(drive)->handler);
 		ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL);
 		OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
 			 IDE_COMMAND_REG);
diff -urN linux-2.5.7/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.7/drivers/ide/ide-cd.c	Thu Mar 28 06:59:54 2002
+++ linux/drivers/ide/ide-cd.c	Wed Mar 27 02:47:13 2002
@@ -740,11 +740,12 @@
 	OUT_BYTE (xferlen >> 8  , IDE_HCYL_REG);
 	if (IDE_CONTROL_REG)
 		OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
- 
+
 	if (info->dma)
 		(void) drive->channel->dmaproc(ide_dma_begin, drive);
 
 	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
+		BUG_ON(HWGROUP(drive)->handler);
 		ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
 		return ide_started;
@@ -787,6 +788,7 @@
 	}
 
 	/* Arm the interrupt handler. */
+	BUG_ON(HWGROUP(drive)->handler);
 	ide_set_handler (drive, handler, timeout, cdrom_timer_expiry);
 
 	/* Send the command to the device. */
@@ -1005,7 +1007,9 @@
 
 	/* Done moving data!
 	   Wait for another interrupt. */
+	BUG_ON(HWGROUP(drive)->handler);
 	ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL);
+
 	return ide_started;
 }
 
@@ -1335,6 +1339,8 @@
 	}
 
 	/* Now we wait for another interrupt. */
+
+	BUG_ON(HWGROUP(drive)->handler);
 	ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
 	return ide_started;
 }
@@ -1559,6 +1565,7 @@
 	}
 
 	/* re-arm handler */
+	BUG_ON(HWGROUP(drive)->handler);
 	ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL);
 	return ide_started;
 }
@@ -2984,15 +2991,14 @@
 		memset (info, 0, sizeof (struct cdrom_info));
 		drive->driver_data = info;
 
-		/* ATA-PATTERN */
-		ata_ops(drive)->busy++;
+		MOD_INC_USE_COUNT;
 		if (ide_cdrom_setup (drive)) {
-			ata_ops(drive)->busy--;
+			MOD_DEC_USE_COUNT;
 			if (ide_cdrom_cleanup (drive))
 				printk ("%s: ide_cdrom_cleanup failed in ide_cdrom_init\n", drive->name);
 			continue;
 		}
-		ata_ops(drive)->busy--;
+		MOD_DEC_USE_COUNT;
 
 		failed--;
 	}
diff -urN linux-2.5.7/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.7/drivers/ide/ide-disk.c	Thu Mar 28 06:59:56 2002
+++ linux/drivers/ide/ide-disk.c	Wed Mar 27 02:48:05 2002
@@ -323,7 +323,7 @@
 
 	while (drive->blocked) {
 		yield();
-		// panic("ide: Request while drive blocked?");
+		printk("ide: Request while drive blocked?");
 	}
 
 	if (!(rq->flags & REQ_CMD)) {
@@ -380,12 +380,14 @@
 {
 	struct hd_drive_task_hdr taskfile;
 	struct hd_drive_hob_hdr hobfile;
+
 	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
 	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 	if (drive->id->cfs_enable_2 & 0x2400)
 		taskfile.command = WIN_FLUSH_CACHE_EXT;
 	else
 		taskfile.command = WIN_FLUSH_CACHE;
+
 	return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
 }
 
@@ -504,7 +506,7 @@
 
 	args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
 	args.taskfile.command = WIN_SET_MAX;
-	args.handler				= task_no_data_intr;
+	args.handler = task_no_data_intr;
 	/* submit command request */
 	ide_raw_taskfile(drive, &args, NULL);
 	/* if OK, read new maximum address value */
@@ -540,7 +542,7 @@
 	args.hobfile.device_head = 0x40;
 	args.hobfile.control = (drive->ctl | 0x80);
 
-        args.handler				= task_no_data_intr;
+        args.handler = task_no_data_intr;
 	/* submit command request */
 	ide_raw_taskfile(drive, &args, NULL);
 	/* if OK, compute maximum address value */
@@ -611,10 +613,10 @@
 				drive->select.b.lba = 1;
 				drive->id->lba_capacity_2 = capacity_2;
                         }
-#else /* !CONFIG_IDEDISK_STROKE */
+#else
 			printk("%s: setmax_ext LBA %llu, native  %llu\n",
 				drive->name, set_max_ext, capacity_2);
-#endif /* CONFIG_IDEDISK_STROKE */
+#endif
 		}
 		drive->bios_cyl		= drive->cyl;
 		drive->capacity48	= capacity_2;
@@ -637,10 +639,10 @@
 			drive->select.b.lba = 1;
 			drive->id->lba_capacity = capacity;
 		}
-#else /* !CONFIG_IDEDISK_STROKE */
+#else
 		printk("%s: setmax LBA %lu, native  %lu\n",
 			drive->name, set_max, capacity);
-#endif /* CONFIG_IDEDISK_STROKE */
+#endif
 	}
 
 	drive->capacity = capacity;
@@ -954,6 +956,9 @@
 	 * already been done...
 	 */
 
+	if (level != SUSPEND_SAVE_STATE)
+		return 0;
+
 	/* wait until all commands are finished */
 	printk("ide_disk_suspend()\n");
 	while (HWGROUP(drive)->handler)
@@ -973,6 +978,9 @@
 static int idedisk_resume(struct device *dev, u32 level)
 {
 	ide_drive_t *drive = dev->driver_data;
+
+	if (level != RESUME_RESTORE_STATE)
+		return 0;
 	if (!drive->blocked)
 		panic("ide: Resume but not suspended?\n");
 
@@ -1113,8 +1121,11 @@
 	(void) probe_lba_addressing(drive, 1);
 }
 
-static int idedisk_cleanup (ide_drive_t *drive)
+static int idedisk_cleanup(ide_drive_t *drive)
 {
+	if (!drive)
+	    return 0;
+
 	put_device(&drive->device);
 	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
 		if (idedisk_flushcache(drive))
diff -urN linux-2.5.7/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.7/drivers/ide/ide-dma.c	Thu Mar 28 06:59:56 2002
+++ linux/drivers/ide/ide-dma.c	Wed Mar 27 02:47:13 2002
@@ -588,6 +588,8 @@
 			drive->waiting_for_dma = 1;
 			if (drive->type != ATA_DISK)
 				return 0;
+
+			BUG_ON(HWGROUP(drive)->handler);
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry);	/* issue cmd to drive */
 			if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
 			    (drive->addressing == 1)) {
diff -urN linux-2.5.7/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.5.7/drivers/ide/ide-floppy.c	Thu Mar 28 06:59:54 2002
+++ linux/drivers/ide/ide-floppy.c	Wed Mar 27 02:47:13 2002
@@ -968,6 +968,7 @@
 			if (temp > pc->buffer_size) {
 				printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n");
 				idefloppy_discard_data (drive,bcount.all);
+				BUG_ON(HWGROUP(drive)->handler);
 				ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
 				return ide_started;
 			}
@@ -990,7 +991,9 @@
 	pc->actually_transferred+=bcount.all;				/* Update the current position */
 	pc->current_position+=bcount.all;
 
-	ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);		/* And set the interrupt handler again */
+	BUG_ON(HWGROUP(drive)->handler);
+	ide_set_handler(drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);		/* And set the interrupt handler again */
+
 	return ide_started;
 }
 
@@ -1014,8 +1017,11 @@
 		printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
 		return ide_stopped;
 	}
+
+	BUG_ON(HWGROUP(drive)->handler);
 	ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);	/* Set the interrupt routine */
 	atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */
+
 	return ide_started;
 }
 
@@ -1055,17 +1061,19 @@
 		printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
 		return ide_stopped;
 	}
-	/* 
+	/*
 	 * 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 1200 MHz Athlon system. 10/26/01
-	 * 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will 
+	 * 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will
 	 * not be actually used until after the packet is moved in about 50 msec.
 	 */
-	ide_set_handler (drive, 
-	  &idefloppy_pc_intr, 		/* service routine for packet command */
+	BUG_ON(HWGROUP(drive)->handler);
+	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 */
+
 	return ide_started;
 }
 
@@ -1143,8 +1151,9 @@
 	} else {
 		pkt_xfer_routine = &idefloppy_transfer_pc;	/* immediate */
 	}
-	
+
 	if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
+		BUG_ON(HWGROUP(drive)->handler);
 		ide_set_handler (drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);		/* Issue the packet command */
 		return ide_started;
@@ -1156,7 +1165,7 @@
 
 static void idefloppy_rw_callback (ide_drive_t *drive)
 {
-#if IDEFLOPPY_DEBUG_LOG	
+#if IDEFLOPPY_DEBUG_LOG
 	printk (KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n");
 #endif /* IDEFLOPPY_DEBUG_LOG */
 
@@ -2109,10 +2118,9 @@
 			kfree (floppy);
 			continue;
 		}
-		/* ATA-PATTERN */
-		ata_ops(drive)->busy++;
+		MOD_INC_USE_COUNT;
 		idefloppy_setup (drive, floppy);
-		ata_ops(drive)->busy--;
+		MOD_DEC_USE_COUNT;
 
 		failed--;
 	}
diff -urN linux-2.5.7/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.7/drivers/ide/ide-pmac.c	Thu Mar 28 06:59:54 2002
+++ linux/drivers/ide/ide-pmac.c	Wed Mar 27 02:47:13 2002
@@ -931,12 +931,12 @@
 	int enable = 1;
 
 	drive->using_dma = 0;
-	
+
 	idx = pmac_ide_find(drive);
 	if (idx < 0)
 		return 0;
-		
-	if (drive->media == ide_floppy)
+
+	if (drive->type == ATA_FLOPPY)
 		enable = 0;
 	if (((id->capability & 1) == 0) && !check_drive_lists(drive, GOOD_DMA_DRIVE))
 		enable = 0;
@@ -945,9 +945,9 @@
 
 	udma = 0;
 	ata4 = (pmac_ide[idx].kind == controller_kl_ata4);
-			
+
 	if(enable) {
-		if (ata4 && (drive->media == ide_disk) &&
+		if (ata4 && (drive->type == ATA_DISK) &&
 		    (id->field_valid & 0x0004) && (id->dma_ultra & 0x17)) {
 			/* UltraDMA modes. */
 			drive->using_dma = pmac_ide_udma_enable(drive, idx);
@@ -994,8 +994,9 @@
 		if (!pmac_ide_build_dmatable(drive, ix, func==ide_dma_write))
 			return 1;
 		drive->waiting_for_dma = 1;
-		if (drive->media != ide_disk)
+		if (drive->type != ATA_DISK)
 			return 0;
+		BUG_ON(HWGROUP(drive)->handler);
 		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
 		OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
 			 IDE_COMMAND_REG);
@@ -1054,12 +1055,12 @@
 static void idepmac_sleep_device(ide_drive_t *drive, int i, unsigned base)
 {
 	int j;
-	
+
 	/* FIXME: We only handle the master IDE disk, we shoud
 	 *        try to fix CD-ROMs here
 	 */
-	switch (drive->media) {
-	case ide_disk:
+	switch (drive->type) {
+	case ATA_DISK:
 		/* Spin down the drive */
 		outb(0xa0, base+0x60);
 		outb(0x0, base+0x30);
@@ -1067,7 +1068,7 @@
 		outb(0x0, base+0x40);
 		outb(0x0, base+0x50);
 		outb(0xe0, base+0x70);
-		outb(0x2, base+0x160);   
+		outb(0x2, base+0x160);
 		for (j = 0; j < 10; j++) {
 			int status;
 			mdelay(100);
@@ -1076,10 +1077,10 @@
 				break;
 		}
 		break;
-	case ide_cdrom:
+	case ATA_ROM:
 		// todo
 		break;
-	case ide_floppy:
+	case ATA_FLOPPY:
 		// todo
 		break;
 	}
diff -urN linux-2.5.7/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux-2.5.7/drivers/ide/ide-tape.c	Thu Mar 28 06:59:56 2002
+++ linux/drivers/ide/ide-tape.c	Wed Mar 27 02:47:13 2002
@@ -2155,7 +2155,8 @@
 			if (temp > pc->buffer_size) {
 				printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
 				idetape_discard_data (drive, bcount.all);
-				ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
+				BUG_ON(HWGROUP(drive)->handler);
+				ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
 				return ide_started;
 			}
 #if IDETAPE_DEBUG_LOG
@@ -2181,7 +2182,8 @@
 	if (tape->debug_level >= 2)
 		printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all);
 #endif
-	ide_set_handler (drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* And set the interrupt handler again */
+	BUG_ON(HWGROUP(drive)->handler);
+	ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* And set the interrupt handler again */
 	return ide_started;
 }
 
@@ -2255,6 +2257,7 @@
 		return ide_stopped;
 	}
 	tape->cmd_start_time = jiffies;
+	BUG_ON(HWGROUP(drive)->handler);
 	ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* Set the interrupt routine */
 	atapi_output_bytes (drive,pc->c,12);			/* Send the actual packet */
 	return ide_started;
@@ -2328,6 +2331,7 @@
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 	if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
+		BUG_ON(HWGROUP(drive)->handler);
 		ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
 		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
 		return ide_started;
@@ -6099,8 +6103,7 @@
 	idetape_chrdevs[minor].drive = NULL;
 	restore_flags (flags);	/* all CPUs (overkill?) */
 
-	/* FIXME: this appears to be totally wrong! */
-	ata_ops(drive)->busy = 0;
+	MOD_DEC_USE_COUNT;
 
 	ide_unregister_subdriver (drive);
 	drive->driver_data = NULL;
diff -urN linux-2.5.7/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.7/drivers/ide/ide-taskfile.c	Thu Mar 28 06:59:54 2002
+++ linux/drivers/ide/ide-taskfile.c	Thu Mar 28 06:18:08 2002
@@ -33,7 +33,7 @@
 #define DEBUG_TASKFILE	0	/* unset when fixed */
 
 #if DEBUG_TASKFILE
-#define DTF(x...) printk(##x)
+#define DTF(x...) printk(x)
 #else
 #define DTF(x...)
 #endif
@@ -55,7 +55,7 @@
 				unsigned long *flags)
 {
 	if (rq->bio)
-	    bio_kunmap_irq(to, flags);
+		bio_kunmap_irq(to, flags);
 }
 
 static void bswap_data (void *buffer, int wcount)
@@ -288,73 +288,104 @@
 			break;
 	}
 }
-static ide_startstop_t bio_mulout_intr(ide_drive_t *drive);
 
-/*
- * Handler for command write multiple
- * Called directly from execute_drive_cmd for the first bunch of sectors,
- * afterwards only by the ISR
- */
-static ide_startstop_t task_mulout_intr(ide_drive_t *drive)
+static ide_startstop_t pre_task_mulout_intr(ide_drive_t *drive, struct request *rq)
+{
+	ide_task_t *args = rq->special;
+	ide_startstop_t startstop;
+
+	/*
+	 * assign private copy for multi-write
+	 */
+	memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request));
+
+	if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ))
+		return startstop;
+
+	ata_poll_drive_ready(drive);
+	return args->handler(drive);
+}
+
+static ide_startstop_t task_mulout_intr (ide_drive_t *drive)
 {
-	unsigned int		msect, nsect;
 	byte stat		= GET_STAT();
 	byte io_32bit		= drive->io_32bit;
-	struct request *rq	= HWGROUP(drive)->rq;
+	struct request *rq	= &HWGROUP(drive)->wrq;
 	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
-	char *pBuf		= NULL;
-	unsigned long flags;
+	int mcount		= drive->mult_count;
+	ide_startstop_t startstop;
 
 	/*
 	 * (ks/hs): Handle last IRQ on multi-sector transfer,
 	 * occurs after all data was sent in this chunk
 	 */
-	if (rq->current_nr_sectors == 0) {
-		if (stat & (ERR_STAT|DRQ_STAT))
-			return ide_error(drive, "task_mulout_intr", stat);
+	if (!rq->nr_sectors) {
+		if (stat & (ERR_STAT|DRQ_STAT)) {
+			startstop = ide_error(drive, "task_mulout_intr", stat);
+			memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request));
+			return startstop;
+		}
 
-		/*
-		 * there may be more, ide_do_request will restart it if
-		 * necessary
-		 */
-		ide_end_request(drive, 1);
+		__ide_end_request(drive, 1, rq->hard_nr_sectors);
+		rq->bio = NULL;
 
 		return ide_stopped;
 	}
 
-	if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
-		if (stat & (ERR_STAT|DRQ_STAT)) {
-			return ide_error(drive, "task_mulout_intr", stat);
+	if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
+		if (stat & (ERR_STAT | DRQ_STAT)) {
+			startstop = ide_error(drive, "task_mulout_intr", stat);
+			memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request));
+			return startstop;
 		}
+
 		/* no data yet, so wait for another interrupt */
 		if (hwgroup->handler == NULL)
-			ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
+			ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
+
 		return ide_started;
 	}
 
-	/* (ks/hs): See task_mulin_intr */
-	msect = drive->mult_count;
-	nsect = rq->current_nr_sectors;
-	if (nsect > msect)
-		nsect = msect;
+	do {
+		char *buffer;
+		int nsect = rq->current_nr_sectors;
+		unsigned long flags;
 
-	pBuf = ide_map_rq(rq, &flags);
-	DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
-		pBuf, nsect, rq->current_nr_sectors);
+		if (nsect > mcount)
+			nsect = mcount;
+		mcount -= nsect;
 
-	drive->io_32bit = 0;
-	taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
+		buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
+		rq->sector += nsect;
+		rq->nr_sectors -= nsect;
+		rq->current_nr_sectors -= nsect;
 
-	ide_unmap_rq(rq, pBuf, &flags);
+		/* Do we move to the next bio after this? */
+		if (!rq->current_nr_sectors) {
+			/* remember to fix this up /jens */
+			struct bio *bio = rq->bio->bi_next;
 
-	drive->io_32bit = io_32bit;
+			/* end early if we ran out of requests */
+			if (!bio) {
+				mcount = 0;
+			} else {
+				rq->bio = bio;
+				rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
+			}
+		}
 
-	rq->errors = 0;
-	/* Are we sure that this as all been already transfered? */
-	rq->current_nr_sectors -= nsect;
+		/*
+		 * Ok, we're all setup for the interrupt
+		 * re-entering us on the last transfer.
+		 */
+		taskfile_output_data(drive, buffer, nsect * SECTOR_WORDS);
+		bio_kunmap_irq(buffer, &flags);
+	} while (mcount);
 
+	drive->io_32bit = io_32bit;
+	rq->errors = 0;
 	if (hwgroup->handler == NULL)
-		ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
+		ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
 
 	return ide_started;
 }
@@ -371,7 +402,7 @@
 	u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
 
 	/* (ks/hs): Moved to start, do not use for multiple out commands */
-	if (handler != task_mulout_intr && handler != bio_mulout_intr) {
+	if (handler != task_mulout_intr) {
 		if (IDE_CONTROL_REG)
 			OUT_BYTE(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */
 		SELECT_MASK(drive->channel, drive, 0);
@@ -583,107 +614,6 @@
 	return ide_started;
 }
 
-static ide_startstop_t pre_bio_out_intr(ide_drive_t *drive, struct request *rq)
-{
-	ide_task_t *args = rq->special;
-	ide_startstop_t startstop;
-
-	/*
-	 * assign private copy for multi-write
-	 */
-	memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request));
-
-	if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ))
-		return startstop;
-
-	ata_poll_drive_ready(drive);
-	return args->handler(drive);
-}
-
-
-static ide_startstop_t bio_mulout_intr (ide_drive_t *drive)
-{
-	byte stat		= GET_STAT();
-	byte io_32bit		= drive->io_32bit;
-	struct request *rq	= &HWGROUP(drive)->wrq;
-	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
-	int mcount		= drive->mult_count;
-	ide_startstop_t startstop;
-
-	/*
-	 * (ks/hs): Handle last IRQ on multi-sector transfer,
-	 * occurs after all data was sent in this chunk
-	 */
-	if (!rq->nr_sectors) {
-		if (stat & (ERR_STAT|DRQ_STAT)) {
-			startstop = ide_error(drive, "bio_mulout_intr", stat);
-			memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request));
-			return startstop;
-		}
-
-		__ide_end_request(drive, 1, rq->hard_nr_sectors);
-		HWGROUP(drive)->wrq.bio = NULL;
-		return ide_stopped;
-	}
-
-	if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
-		if (stat & (ERR_STAT | DRQ_STAT)) {
-			startstop = ide_error(drive, "bio_mulout_intr", stat);
-			memcpy(rq, HWGROUP(drive)->rq, sizeof(struct request));
-			return startstop;
-		}
-
-		/* no data yet, so wait for another interrupt */
-		if (hwgroup->handler == NULL)
-			ide_set_handler(drive, bio_mulout_intr, WAIT_CMD, NULL);
-
-		return ide_started;
-	}
-
-	do {
-		char *buffer;
-		int nsect = rq->current_nr_sectors;
-		unsigned long flags;
-
-		if (nsect > mcount)
-			nsect = mcount;
-		mcount -= nsect;
-
-		buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
-		rq->sector += nsect;
-		rq->nr_sectors -= nsect;
-		rq->current_nr_sectors -= nsect;
-
-		/* Do we move to the next bio after this? */
-		if (!rq->current_nr_sectors) {
-			/* remember to fix this up /jens */
-			struct bio *bio = rq->bio->bi_next;
-
-			/* end early early we ran out of requests */
-			if (!bio) {
-				mcount = 0;
-			} else {
-				rq->bio = bio;
-				rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
-			}
-		}
-
-		/*
-		 * Ok, we're all setup for the interrupt
-		 * re-entering us on the last transfer.
-		 */
-		taskfile_output_data(drive, buffer, nsect * SECTOR_WORDS);
-		bio_kunmap_irq(buffer, &flags);
-	} while (mcount);
-
-	drive->io_32bit = io_32bit;
-	rq->errors = 0;
-	if (hwgroup->handler == NULL)
-		ide_set_handler(drive, bio_mulout_intr, WAIT_CMD, NULL);
-
-	return ide_started;
-}
-
 /*
  * Handler for command with Read Multiple
  */
@@ -781,8 +711,8 @@
 		case CFA_WRITE_MULTI_WO_ERASE:
 		case WIN_MULTWRITE:
 		case WIN_MULTWRITE_EXT:
-			args->prehandler = pre_bio_out_intr;
-			args->handler = bio_mulout_intr;
+			args->prehandler = pre_task_mulout_intr;
+			args->handler = task_mulout_intr;
 			args->command_type = IDE_DRIVE_TASK_RAW_WRITE;
 			return;
 
@@ -989,7 +919,7 @@
  *
  * The caller has to make sure buf is never NULL!
  */
-static int ide_wait_cmd(ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *argbuf)
+static int ide_wait_cmd(ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *argbuf)
 {
 	struct request rq;
 
@@ -998,10 +928,10 @@
 	memset(argbuf, 0, 4 + SECTOR_WORDS * 4 * sectors);
 	ide_init_drive_cmd(&rq);
 	rq.buffer = argbuf;
-	*argbuf++ = cmd;
-	*argbuf++ = nsect;
-	*argbuf++ = feature;
-	*argbuf++ = sectors;
+	argbuf[0] = cmd;
+	argbuf[1] = nsect;
+	argbuf[2] = feature;
+	argbuf[3] = sectors;
 
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
@@ -1009,7 +939,8 @@
 int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	int err = 0;
-	byte args[4], *argbuf = args;
+	u8 args[4];
+	u8 *argbuf = args;
 	byte xfer_rate = 0;
 	int argsize = 4;
 	ide_task_t tfargs;
diff -urN linux-2.5.7/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.7/drivers/ide/ide.c	Thu Mar 28 06:59:56 2002
+++ linux/drivers/ide/ide.c	Wed Mar 27 02:47:13 2002
@@ -548,7 +548,8 @@
 	if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) {
 		printk("%s: ATAPI reset complete\n", drive->name);
 	} else {
-		if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
+		if (time_before(jiffies, hwgroup->poll_timeout)) {
+			BUG_ON(HWGROUP(drive)->handler);
 			ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
 			return ide_started;	/* continue polling */
 		}
@@ -573,7 +574,8 @@
 	byte tmp;
 
 	if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) {
-		if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
+		if (time_before(jiffies, hwgroup->poll_timeout)) {
+			BUG_ON(HWGROUP(drive)->handler);
 			ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
 			return ide_started;	/* continue polling */
 		}
@@ -645,6 +647,7 @@
 		udelay (20);
 		OUT_BYTE (WIN_SRST, IDE_COMMAND_REG);
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
+		BUG_ON(HWGROUP(drive)->handler);
 		ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
 		__restore_flags (flags);	/* local CPU only */
 		return ide_started;
@@ -679,7 +682,8 @@
 	}
 	udelay(10);			/* more than enough time */
 	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
-	ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
+	BUG_ON(HWGROUP(drive)->handler);
+	ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
 
 	/*
 	 * Some weird controller like resetting themselves to a strange
@@ -931,6 +935,7 @@
  */
 void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
 {
+	BUG_ON(HWGROUP(drive)->handler);
 	ide_set_handler (drive, handler, WAIT_CMD, NULL);
 	if (IDE_CONTROL_REG)
 		OUT_BYTE(drive->ctl,IDE_CONTROL_REG);	/* clear nIEN */
@@ -1553,7 +1558,7 @@
 /*
  * entry point for all interrupts, caller does __cli() for us
  */
-void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
+void ide_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned long flags;
 	ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;
@@ -1596,7 +1601,7 @@
 			 * Whack the status register, just in case we have a leftover pending IRQ.
 			 */
 			IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);
-#endif /* CONFIG_BLK_DEV_IDEPCI */
+#endif
 		}
 		goto out_lock;
 	}
@@ -3175,10 +3180,19 @@
 
 	save_flags(flags);		/* all CPUs */
 	cli();				/* all CPUs */
-	if (drive->usage || drive->busy || !ata_ops(drive) || ata_ops(drive)->busy) {
+
+#if 0
+	if (__MOD_IN_USE(ata_ops(drive)->owner)) {
+		restore_flags(flags);
+		return 1;
+	}
+#endif
+
+	if (drive->usage || drive->busy || !ata_ops(drive)) {
 		restore_flags(flags);	/* all CPUs */
 		return 1;
 	}
+
 #if defined(CONFIG_BLK_DEV_ISAPNP) && defined(CONFIG_ISAPNP) && defined(MODULE)
 	pnpide_init(0);
 #endif
@@ -3189,7 +3203,10 @@
 #endif
 	auto_remove_settings(drive);
 	drive->driver = NULL;
+	drive->present = 0;
+
 	restore_flags(flags);		/* all CPUs */
+
 	return 0;
 }
 
@@ -3298,6 +3315,7 @@
 		hwif = &ide_hwifs[i];
 		if (!hwif->present)
 			continue;
+
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
 			drive = &hwif->drives[unit];
 			if (!drive->present)
diff -urN linux-2.5.7/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c
--- linux-2.5.7/drivers/ide/pdc4030.c	Thu Mar 28 06:59:56 2002
+++ linux/drivers/ide/pdc4030.c	Thu Mar 28 05:42:44 2002
@@ -394,6 +394,7 @@
 
 	if (GET_STAT() & BUSY_STAT) {
 		if (time_before(jiffies, hwgroup->poll_timeout)) {
+			BUG_ON(HWGROUP(drive)->handler);
 			ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
 			return ide_started; /* continue polling... */
 		}
@@ -476,6 +477,7 @@
 
 	if (IN_BYTE(IDE_NSECTOR_REG) != 0) {
 		if (time_before(jiffies, hwgroup->poll_timeout)) {
+			BUG_ON(HWGROUP(drive)->handler);
 			ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
 			return ide_started; /* continue polling... */
 		}
@@ -489,6 +491,7 @@
 	 */
 	promise_multwrite(drive, 4);
 	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
+	BUG_ON(HWGROUP(drive)->handler);
 	ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
 #ifdef DEBUG_WRITE
 	printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
@@ -523,6 +526,7 @@
 		if (promise_multwrite(drive, rq->nr_sectors - 4))
 			return ide_stopped;
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
+		BUG_ON(HWGROUP(drive)->handler);
 		ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
 		return ide_started;
 	} else {
@@ -533,6 +537,7 @@
 		if (promise_multwrite(drive, rq->nr_sectors))
 			return ide_stopped;
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
+		BUG_ON(HWGROUP(drive)->handler);
 		ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
 #ifdef DEBUG_WRITE
 		printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
@@ -554,6 +559,13 @@
 	unsigned long timeout;
 	byte stat;
 
+	/* Check that it's a regular command. If not, bomb out early. */
+	if (!(rq->flags & REQ_CMD)) {
+		blk_dump_rq_flags(rq, "pdc4030 bad flags");
+		ide_end_request(drive, 0);
+		return ide_stopped;
+	}
+
 	if (IDE_CONTROL_REG)
 		OUT_BYTE(drive->ctl, IDE_CONTROL_REG);  /* clear nIEN */
 	SELECT_MASK(drive->channel, drive, 0);
@@ -568,20 +580,12 @@
 	OUT_BYTE(taskfile->device_head, IDE_SELECT_REG);
 	OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
 
-/* Check that it's a regular command. If not, bomb out early. */
-	if (!(rq->flags & REQ_CMD)) {
-		blk_dump_rq_flags(rq, "pdc4030 bad flags");
-		ide_end_request(drive, 0);
-		return ide_stopped;
-	}
-
 	switch (rq_data_dir(rq)) {
 	case READ:
-		OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
 /*
  * The card's behaviour is odd at this point. If the data is
  * available, DRQ will be true, and no interrupt will be
- * generated by the card. If this is the case, we need to call the 
+ * generated by the card. If this is the case, we need to call the
  * "interrupt" handler (promise_read_intr) directly. Otherwise, if
  * an interrupt is going to occur, bit0 of the SELECT register will
  * be high, so we can set the handler the just return and be interrupted.
@@ -600,6 +604,7 @@
 				printk(KERN_DEBUG "%s: read: waiting for "
 				                  "interrupt\n", drive->name);
 #endif
+				BUG_ON(HWGROUP(drive)->handler);
 				ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
 				return ide_started;
 			}
@@ -612,7 +617,6 @@
 
 	case WRITE: {
 		ide_startstop_t startstop;
-		OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
 /*
  * Strategy on write is:
  *	look for the DRQ that should have been immediately asserted
@@ -624,7 +628,7 @@
 			printk(KERN_ERR "%s: no DRQ after issuing "
 			       "PROMISE_WRITE\n", drive->name);
 			return startstop;
-	    	}
+		}
 		if (!drive->unmask)
 			__cli();	/* local CPU only */
 		HWGROUP(drive)->wrq = *rq; /* scratchpad */
diff -urN linux-2.5.7/drivers/ide/trm290.c linux/drivers/ide/trm290.c
--- linux-2.5.7/drivers/ide/trm290.c	Thu Mar 28 06:59:56 2002
+++ linux/drivers/ide/trm290.c	Wed Mar 27 02:47:13 2002
@@ -194,6 +194,7 @@
 			outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
 			if (drive->type != ATA_DISK)
 				return 0;
+			BUG_ON(HWGROUP(drive)->handler);
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
 			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 			return 0;
diff -urN linux-2.5.7/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.5.7/drivers/scsi/ide-scsi.c	Thu Mar 28 06:59:54 2002
+++ linux/drivers/scsi/ide-scsi.c	Wed Mar 27 02:47:13 2002
@@ -508,7 +508,7 @@
  */
 static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id)
 {
-	ata_ops(drive)->busy++;
+	MOD_INC_USE_COUNT;
 
 	idescsi_drives[id] = drive;
 	drive->driver_data = scsi;
@@ -629,8 +629,9 @@
 
 	for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
 		drive = idescsi_drives[id];
-		if (drive)
-			ata_ops(drive)->busy--;
+		if (drive) {
+			MOD_DEC_USE_COUNT;
+		}
 	}
 	return 0;
 }
diff -urN linux-2.5.7/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.7/include/linux/ide.h	Thu Mar 28 06:59:56 2002
+++ linux/include/linux/ide.h	Thu Mar 28 05:42:51 2002
@@ -300,10 +300,13 @@
 	byte     slow;			/* flag: slow data port */
 	byte     bswap;			/* flag: byte swap data */
 	byte     dsc_overlap;		/* flag: DSC overlap */
+
 	unsigned waiting_for_dma: 1;	/* dma currently in progress */
+	unsigned busy		: 1;	/* currently doing revalidate_disk() */
+	unsigned blocked        : 1;	/* 1=powermanagment told us not to do anything, so sleep nicely */
+
 	unsigned present	: 1;	/* drive is physically present */
 	unsigned noprobe	: 1;	/* from:  hdx=noprobe */
-	unsigned busy		: 1;	/* currently doing revalidate_disk() */
 	unsigned removable	: 1;	/* 1 if need to do check_media_change */
 	unsigned forced_geom	: 1;	/* 1 if hdx=c,h,s was given at boot */
 	unsigned no_unmask	: 1;	/* disallow setting unmask bit */
@@ -315,7 +318,6 @@
 	unsigned autotune	: 2;	/* 1=autotune, 2=noautotune, 0=default */
 	unsigned remap_0_to_1	: 2;	/* 0=remap if ezdrive, 1=remap, 2=noremap */
 	unsigned ata_flash	: 1;	/* 1=present, 0=default */
-	unsigned blocked        : 1;	/* 1=powermanagment told us not to do anything, so sleep nicely */
 	unsigned	addressing;	/* : 2; 0=28-bit, 1=48-bit, 2=64-bit */
 	byte		scsi;		/* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */
 	select_t	select;		/* basic drive/head select reg value */
@@ -620,7 +622,6 @@
 
 struct ata_operations {
 	struct module *owner;
-	unsigned busy: 1; /* FIXME: this will go soon away... */
 	int (*cleanup)(ide_drive_t *);
 	int (*standby)(ide_drive_t *);
 	ide_startstop_t	(*do_request)(ide_drive_t *, struct request *, unsigned long);
@@ -635,6 +636,7 @@
 	void (*pre_reset)(ide_drive_t *);
 	unsigned long (*capacity)(ide_drive_t *);
 	ide_startstop_t	(*special)(ide_drive_t *);
+
 	ide_proc_entry_t *proc;
 };
 

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

* Re: [PATCH] 2.5.7 IDE 27
  2002-03-28  9:31 ` [PATCH] 2.5.7 IDE 27 Martin Dalecki
@ 2002-03-28 18:01   ` Davide Libenzi
  2002-03-29 13:49     ` Martin Dalecki
  0 siblings, 1 reply; 39+ messages in thread
From: Davide Libenzi @ 2002-03-28 18:01 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, Kernel Mailing List

On Thu, 28 Mar 2002, Martin Dalecki wrote:

> Thu Mar 21 03:17:48 CET 2002 ide-clean-27
>
> - Make for less terse error messages in ide-tape.c.
>
> - Replaced all timecomparisions done by hand with all the proper timer_after()
>    commands.
>
> - Remove the drive niec1 mechanisms alltogether. There are several reasons for
>    this:

I did not have the time to test it Martin but looking at the code i'm
pretty confident that this is the cause of the ide_set_handler()/timer
problem on my box ...




- Davide



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

* Re: [PATCH] 2.5.7 IDE 26
  2002-03-28  9:29 ` [PATCH] 2.5.7 IDE 26 Martin Dalecki
@ 2002-03-28 20:34   ` Vojtech Pavlik
  2002-03-28 20:58     ` Anton Altaparmakov
  0 siblings, 1 reply; 39+ messages in thread
From: Vojtech Pavlik @ 2002-03-28 20:34 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Kernel Mailing List

On Thu, Mar 28, 2002 at 10:29:38AM +0100, Martin Dalecki wrote:
> Wed Mar 20 23:17:06 CET 2002 ide-clean-26
> 
> - Mark all members of structures, which get jiffies assigned or involved in
>    ugly timeout calculations with the prefix PADAM_  for easy spotting. This is
>    Polish for "I'm falling down" or "This brings me to the knees" or slag
>    comment for "What a sh..". Please be assured that it doesn't sound vulgar.

In Czech, too. :)

>    Please grep for it to see immediately why this nomenclature is justified.
> 
> - Rename hwifs_s to ata_channel and eliminate ide_hwifs_t as well as the HWIF
>    macro. OK this step makes this patch rather big.

-- 
Vojtech Pavlik
SuSE Labs

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

* Re: [PATCH] 2.5.7 IDE 26
  2002-03-28 20:34   ` Vojtech Pavlik
@ 2002-03-28 20:58     ` Anton Altaparmakov
  2002-03-29 13:53       ` Martin Dalecki
  0 siblings, 1 reply; 39+ messages in thread
From: Anton Altaparmakov @ 2002-03-28 20:58 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Martin Dalecki, Kernel Mailing List

At 20:34 28/03/02, Vojtech Pavlik wrote:
>On Thu, Mar 28, 2002 at 10:29:38AM +0100, Martin Dalecki wrote:
> > Wed Mar 20 23:17:06 CET 2002 ide-clean-26
> >
> > - Mark all members of structures, which get jiffies assigned or involved in
> >    ugly timeout calculations with the prefix PADAM_  for easy spotting. 
> This is
> >    Polish for "I'm falling down" or "This brings me to the knees" or slag
> >    comment for "What a sh..". Please be assured that it doesn't sound 
> vulgar.
>
>In Czech, too. :)

<AOL> In Bulgarian, too. (-: </AOL>

And same in <place your favourite slavic eastern european language here>...

Anton


> >    Please grep for it to see immediately why this nomenclature is 
> justified.
> >
> > - Rename hwifs_s to ata_channel and eliminate ide_hwifs_t as well as 
> the HWIF
> >    macro. OK this step makes this patch rather big.
>
>--
>Vojtech Pavlik
>SuSE Labs

-- 
   "I've not lost my mind. It's backed up on tape somewhere." - Unknown
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Linux NTFS Maintainer / WWW: http://linux-ntfs.sf.net/
ICQ: 8561279 / WWW: http://www-stu.christs.cam.ac.uk/~aia21/


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

* Re: [PATCH] 2.5.7 IDE 27
  2002-03-28 18:01   ` Davide Libenzi
@ 2002-03-29 13:49     ` Martin Dalecki
  2002-03-29 20:39       ` Davide Libenzi
  0 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-03-29 13:49 UTC (permalink / raw)
  To: Davide Libenzi; +Cc: Linus Torvalds, Kernel Mailing List

Davide Libenzi wrote:
> On Thu, 28 Mar 2002, Martin Dalecki wrote:
> 
> 
>>Thu Mar 21 03:17:48 CET 2002 ide-clean-27
>>
>>- Make for less terse error messages in ide-tape.c.
>>
>>- Replaced all timecomparisions done by hand with all the proper timer_after()
>>   commands.
>>
>>- Remove the drive niec1 mechanisms alltogether. There are several reasons for
>>   this:
> 
> 
> I did not have the time to test it Martin but looking at the code i'm
> pretty confident that this is the cause of the ide_set_handler()/timer
> problem on my box ...

Does it mean that you think that my guess was right?


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

* Re: [PATCH] 2.5.7 IDE 26
  2002-03-28 20:58     ` Anton Altaparmakov
@ 2002-03-29 13:53       ` Martin Dalecki
  0 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-03-29 13:53 UTC (permalink / raw)
  To: Anton Altaparmakov; +Cc: Vojtech Pavlik, Kernel Mailing List

Anton Altaparmakov wrote:
> At 20:34 28/03/02, Vojtech Pavlik wrote:
> 
>> On Thu, Mar 28, 2002 at 10:29:38AM +0100, Martin Dalecki wrote:
>> > Wed Mar 20 23:17:06 CET 2002 ide-clean-26
>> >
>> > - Mark all members of structures, which get jiffies assigned or 
>> involved in
>> >    ugly timeout calculations with the prefix PADAM_  for easy 
>> spotting. This is
>> >    Polish for "I'm falling down" or "This brings me to the knees" or 
>> slag
>> >    comment for "What a sh..". Please be assured that it doesn't 
>> sound vulgar.
>>
>> In Czech, too. :)
> 
> 
> <AOL> In Bulgarian, too. (-: </AOL>
> 
> And same in <place your favourite slavic eastern european language here>...

I hope it's clear that the intention is to replace them
by proper timeout handler callbacks.


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

* Re: [PATCH] 2.5.7 IDE 27
  2002-03-29 13:49     ` Martin Dalecki
@ 2002-03-29 20:39       ` Davide Libenzi
  0 siblings, 0 replies; 39+ messages in thread
From: Davide Libenzi @ 2002-03-29 20:39 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, Kernel Mailing List

On Fri, 29 Mar 2002, Martin Dalecki wrote:

> Davide Libenzi wrote:
> > On Thu, 28 Mar 2002, Martin Dalecki wrote:
> >
> >
> >>Thu Mar 21 03:17:48 CET 2002 ide-clean-27
> >>
> >>- Make for less terse error messages in ide-tape.c.
> >>
> >>- Replaced all timecomparisions done by hand with all the proper timer_after()
> >>   commands.
> >>
> >>- Remove the drive niec1 mechanisms alltogether. There are several reasons for
> >>   this:
> >
> >
> > I did not have the time to test it Martin but looking at the code i'm
> > pretty confident that this is the cause of the ide_set_handler()/timer
> > problem on my box ...
>
> Does it mean that you think that my guess was right?

ok, the nice1 defaulted to zero did not fix it but enabling the VIA
support yes, arghhh !!! i was using the VIA chipset w/out enabling it in
.config and this made the kernel to not probe it correctly and to force
off using_dma ( and io32bit ). this resulted, besides the ide_set_handler/timer
problem, in an throughput of 3.9 MB/sec against the 24 MB/sec that i'm getting now.
i need a vacation ...


(a couple of weeks ago i screwed up my patch-bot scripts that was hunging
by trying to merge 2.5.6-pre3 on 2.5.6 - not only i considered the
operation perfectly legal but i ended up asking Linus why he screwed up
the patch :-( )


- Davide




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

* [PATCH] 2.5.8 IDE 34
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (6 preceding siblings ...)
  2002-03-28  9:32 ` [PATCH] 2.5.7 IDE 28a Martin Dalecki
@ 2002-04-15  7:42 ` Martin Dalecki
  2002-04-15  8:51   ` Jens Axboe
  2002-04-22 15:36 ` [PATCH] 2.5.8 IDE 40 Martin Dalecki
                   ` (9 subsequent siblings)
  17 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-04-15  7:42 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

I'm *storgly* recommending this patch to everyoby who wan't
to try 2.5.8 and has to use hdparm for a reasonable setup
of his system

Mon Apr 15 01:27:53 CEST 2002 ide-clean-34

- Synchronize with 2.5.8.

- Eliminate the cdrom_log_sense() function.

- Pass a struct request to cdrom_analyze_sense_data() since this is the entity
   this function is working on. This shows nicely that this function is broken.

- Use CDROM_PACKET_SIZE where appropriate.

- Kill the obfuscating cmd_buf and cmd_len local variables from
   cdrom_transfer_packet_command(). This made it obvious that the parameters of
   this function where not adequate - to say the least. Fix this.

- Pass a packed command array directly to cdrom_queue_packed_command().  This
   is reducing the number of places where we have to deal with the c member of
   struct packet_command.

- Never pass NULL as sense to cdrom_lockdoor().

- Eliminate cdrom_do_block_pc().

- Eliminate the c member of struct packet_command. Pass them through struct
   request cmd member.

- Don't enable TCQ unconditionally if there is a TCQ queue depth defined.

- Fix small think in ide_cmd_ioctl() rewrite. (My appologies to everyone who
   has to use hdparm to setup his system...)

- Fix compilation without PCI support.


It's time for the next patch...

[-- Attachment #2: ide-clean-34.diff --]
[-- Type: text/plain, Size: 52281 bytes --]

diff -urN linux-2.5.8/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.8/drivers/ide/ide-cd.c	Mon Apr 15 08:53:44 2002
+++ linux/drivers/ide/ide-cd.c	Mon Apr 15 08:58:52 2002
@@ -1,6 +1,4 @@
 /*
- * linux/drivers/ide/ide-cd.c
- *
  * Copyright (C) 1994, 1995, 1996  scott snyder  <snyder@fnald0.fnal.gov>
  * Copyright (C) 1996-1998  Erik Andersen <andersee@debian.org>
  * Copyright (C) 1998-2000  Jens Axboe <axboe@suse.de>
@@ -13,9 +11,10 @@
  *
  * Suggestions are welcome. Patches that work are more welcome though. ;-)
  * For those wishing to work on this driver, please be sure you download
- * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI 
- * (SFF-8020i rev 2.6) standards. These documents can be obtained by 
+ * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
+ * (SFF-8020i rev 2.6) standards. These documents can be obtained by
  * anonymous ftp from:
+ *
  * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
  * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
  *
@@ -54,18 +53,18 @@
  *                       Aztech drives, which seem to have the same problem.
  * 2.04b May 30, 1995 -- Fix to match changes in ide.c version 3.16 -ml
  * 2.05  Jun  8, 1995 -- Don't attempt to retry after an illegal request
- *                        or data protect error.
+ *                       or data protect error.
  *                       Use HWIF and DEV_HWIF macros as in ide.c.
  *                       Always try to do a request_sense after
- *                        a failed command.
+ *                       a failed command.
  *                       Include an option to give textual descriptions
- *                        of ATAPI errors.
+ *                       of ATAPI errors.
  *                       Fix a bug in handling the sector cache which
- *                        showed up if the drive returned data in 512 byte
- *                        blocks (like Pioneer drives).  Thanks to
- *                        Richard Hirst <srh@gpt.co.uk> for diagnosing this.
+ *                       showed up if the drive returned data in 512 byte
+ *                       blocks (like Pioneer drives).  Thanks to
+ *                       Richard Hirst <srh@gpt.co.uk> for diagnosing this.
  *                       Properly supply the page number field in the
- *                        MODE_SELECT command.
+ *                       MODE_SELECT command.
  *                       PLAYAUDIO12 is broken on the Aztech; work around it.
  * 2.05x Aug 11, 1995 -- lots of data structure renaming/restructuring in ide.c
  *                       (my apologies to Scott, but now ide-cd.c is independent)
@@ -74,28 +73,28 @@
  *                       Use input_ide_data() and output_ide_data().
  *                       Add door locking.
  *                       Fix usage count leak in cdrom_open, which happened
- *                        when a read-write mount was attempted.
+ *                       when a read-write mount was attempted.
  *                       Try to load the disk on open.
  *                       Implement CDROMEJECT_SW ioctl (off by default).
  *                       Read total cdrom capacity during open.
  *                       Rearrange logic in cdrom_decode_status.  Issue
- *                        request sense commands for failed packet commands
- *                        from here instead of from cdrom_queue_packet_command.
- *                        Fix a race condition in retrieving error information.
+ *                       request sense commands for failed packet commands
+ *                       from here instead of from cdrom_queue_packet_command.
+ *                       Fix a race condition in retrieving error information.
  *                       Suppress printing normal unit attention errors and
- *                        some drive not ready errors.
+ *                       some drive not ready errors.
  *                       Implement CDROMVOLREAD ioctl.
  *                       Implement CDROMREADMODE1/2 ioctls.
  *                       Fix race condition in setting up interrupt handlers
- *                        when the `serialize' option is used.
+ *                       when the `serialize' option is used.
  * 3.01  Sep  2, 1995 -- Fix ordering of reenabling interrupts in
- *                        cdrom_queue_request.
+ *                       cdrom_queue_request.
  *                       Another try at using ide_[input,output]_data.
  * 3.02  Sep 16, 1995 -- Stick total disk capacity in partition table as well.
  *                       Make VERBOSE_IDE_CD_ERRORS dump failed command again.
  *                       Dump out more information for ILLEGAL REQUEST errs.
  *                       Fix handling of errors occurring before the
- *                        packet command is transferred.
+ *                       packet command is transferred.
  *                       Fix transfers with odd bytelengths.
  * 3.03  Oct 27, 1995 -- Some Creative drives have an id of just `CD'.
  *                       `DCI-2S10' drives are broken too.
@@ -103,17 +102,17 @@
  * 3.05  Dec  1, 1995 -- Changes to go with overhaul of ide.c and ide-tape.c
  * 3.06  Dec 16, 1995 -- Add support needed for partitions.
  *                       More workarounds for Vertos bugs (based on patches
- *                        from Holger Dietze <dietze@aix520.informatik.uni-leipzig.de>).
+ *                       from Holger Dietze <dietze@aix520.informatik.uni-leipzig.de>).
  *                       Try to eliminate byteorder assumptions.
  *                       Use atapi_cdrom_subchnl struct definition.
  *                       Add STANDARD_ATAPI compilation option.
  * 3.07  Jan 29, 1996 -- More twiddling for broken drives: Sony 55D,
- *                        Vertos 300.
+ *                       Vertos 300.
  *                       Add NO_DOOR_LOCKING configuration option.
  *                       Handle drive_cmd requests w/NULL args (for hdparm -t).
  *                       Work around sporadic Sony55e audio play problem.
  * 3.07a Feb 11, 1996 -- check drive->id for NULL before dereferencing, to fix
- *                        problem with "hde=cdrom" with no drive present.  -ml
+ *                       problem with "hde=cdrom" with no drive present.  -ml
  * 3.08  Mar  6, 1996 -- More Vertos workarounds.
  * 3.09  Apr  5, 1996 -- Add CDROMCLOSETRAY ioctl.
  *                       Switch to using MSF addressing for audio commands.
@@ -129,47 +128,47 @@
  * 3.14  May 29, 1996 -- Add work-around for Vertos 600.
  *                        (From Hennus Bergman <hennus@sky.ow.nl>.)
  * 3.15  July 2, 1996 -- Added support for Sanyo 3 CD changers
- *                        from Ben Galliart <bgallia@luc.edu> with 
- *                        special help from Jeff Lightfoot 
- *                        <jeffml@pobox.com>
+ *                       from Ben Galliart <bgallia@luc.edu> with
+ *                       special help from Jeff Lightfoot
+ *                       <jeffml@pobox.com>
  * 3.15a July 9, 1996 -- Improved Sanyo 3 CD changer identification
  * 3.16  Jul 28, 1996 -- Fix from Gadi to reduce kernel stack usage for ioctl.
  * 3.17  Sep 17, 1996 -- Tweak audio reads for some drives.
  *                       Start changing CDROMLOADFROMSLOT to CDROM_SELECT_DISC.
  * 3.18  Oct 31, 1996 -- Added module and DMA support.
- *                       
- *                       
+ *
+ *
  * 4.00  Nov 5, 1996   -- New ide-cd maintainer,
- *                                 Erik B. Andersen <andersee@debian.org>
+ *                        Erik B. Andersen <andersee@debian.org>
  *                     -- Newer Creative drives don't always set the error
- *                          register correctly.  Make sure we see media changes
- *                          regardless.
+ *                        register correctly.  Make sure we see media changes
+ *                        regardless.
  *                     -- Integrate with generic cdrom driver.
  *                     -- CDROMGETSPINDOWN and CDROMSETSPINDOWN ioctls, based on
- *                          a patch from Ciro Cattuto <>.
+ *                        a patch from Ciro Cattuto <>.
  *                     -- Call set_device_ro.
  *                     -- Implement CDROMMECHANISMSTATUS and CDROMSLOTTABLE
- *                          ioctls, based on patch by Erik Andersen
+ *                        ioctls, based on patch by Erik Andersen
  *                     -- Add some probes of drive capability during setup.
  *
  * 4.01  Nov 11, 1996  -- Split into ide-cd.c and ide-cd.h
- *                     -- Removed CDROMMECHANISMSTATUS and CDROMSLOTTABLE 
- *                          ioctls in favor of a generalized approach 
- *                          using the generic cdrom driver.
+ *                     -- Removed CDROMMECHANISMSTATUS and CDROMSLOTTABLE
+ *                        ioctls in favor of a generalized approach
+ *                        using the generic cdrom driver.
  *                     -- Fully integrated with the 2.1.X kernel.
  *                     -- Other stuff that I forgot (lots of changes)
  *
  * 4.02  Dec 01, 1996  -- Applied patch from Gadi Oxman <gadio@netvision.net.il>
- *                          to fix the drive door locking problems.
+ *                        to fix the drive door locking problems.
  *
  * 4.03  Dec 04, 1996  -- Added DSC overlap support.
- * 4.04  Dec 29, 1996  -- Added CDROMREADRAW ioclt based on patch 
- *                          by Ales Makarov (xmakarov@sun.felk.cvut.cz)
+ * 4.04  Dec 29, 1996  -- Added CDROMREADRAW ioclt based on patch
+ *                        by Aleks Makarov (xmakarov@sun.felk.cvut.cz)
  *
  * 4.05  Nov 20, 1997  -- Modified to print more drive info on init
  *                        Minor other changes
  *                        Fix errors on CDROMSTOP (If you have a "Dolphin",
- *                          you must define IHAVEADOLPHIN)
+ *                        you must define IHAVEADOLPHIN)
  *                        Added identifier so new Sanyo CD-changer works
  *                        Better detection if door locking isn't supported
  *
@@ -178,40 +177,40 @@
  * 4.08  Dec 18, 1997  -- spew less noise when tray is empty
  *                     -- fix speed display for ACER 24X, 18X
  * 4.09  Jan 04, 1998  -- fix handling of the last block so we return
- *                         an end of file instead of an I/O error (Gadi)
+ *                        an end of file instead of an I/O error (Gadi)
  * 4.10  Jan 24, 1998  -- fixed a bug so now changers can change to a new
- *                         slot when there is no disc in the current slot.
+ *                        slot when there is no disc in the current slot.
  *                     -- Fixed a memory leak where info->changer_info was
- *                         malloc'ed but never free'd when closing the device.
+ *                        malloc'ed but never free'd when closing the device.
  *                     -- Cleaned up the global namespace a bit by making more
- *                         functions static that should already have been.
+ *                        functions static that should already have been.
  * 4.11  Mar 12, 1998  -- Added support for the CDROM_SELECT_SPEED ioctl
- *                         based on a patch for 2.0.33 by Jelle Foks 
- *                         <jelle@scintilla.utwente.nl>, a patch for 2.0.33
- *                         by Toni Giorgino <toni@pcape2.pi.infn.it>, the SCSI
- *                         version, and my own efforts.  -erik
+ *                        based on a patch for 2.0.33 by Jelle Foks
+ *                        <jelle@scintilla.utwente.nl>, a patch for 2.0.33
+ *                        by Toni Giorgino <toni@pcape2.pi.infn.it>, the SCSI
+ *                        version, and my own efforts.  -erik
  *                     -- Fixed a stupid bug which egcs was kind enough to
- *                         inform me of where "Illegal mode for this track"
- *                         was never returned due to a comparison on data
- *                         types of limited range.
- * 4.12  Mar 29, 1998  -- Fixed bug in CDROM_SELECT_SPEED so write speed is 
- *                         now set ionly for CD-R and CD-RW drives.  I had 
- *                         removed this support because it produced errors.
- *                         It produced errors _only_ for non-writers. duh.
+ *                        inform me of where "Illegal mode for this track"
+ *                        was never returned due to a comparison on data
+ *                        types of limited range.
+ * 4.12  Mar 29, 1998  -- Fixed bug in CDROM_SELECT_SPEED so write speed is
+ *                        now set ionly for CD-R and CD-RW drives.  I had
+ *                        removed this support because it produced errors.
+ *                        It produced errors _only_ for non-writers. duh.
  * 4.13  May 05, 1998  -- Suppress useless "in progress of becoming ready"
- *                         messages, since this is not an error.
+ *                        messages, since this is not an error.
  *                     -- Change error messages to be const
  *                     -- Remove a "\t" which looks ugly in the syslogs
  * 4.14  July 17, 1998 -- Change to pointing to .ps version of ATAPI spec
- *                         since the .pdf version doesn't seem to work...
+ *                        since the .pdf version doesn't seem to work...
  *                     -- Updated the TODO list to something more current.
  *
- * 4.15  Aug 25, 1998  -- Updated ide-cd.h to respect mechine endianess, 
- *                         patch thanks to "Eddie C. Dost" <ecd@skynet.be>
+ * 4.15  Aug 25, 1998  -- Updated ide-cd.h to respect mechine endianess,
+ *                        patch thanks to "Eddie C. Dost" <ecd@skynet.be>
  *
  * 4.50  Oct 19, 1998  -- New maintainers!
- *                         Jens Axboe <axboe@image.dk>
- *                         Chris Zwilling <chris@cloudnet.com>
+ *                        Jens Axboe <axboe@image.dk>
+ *                        Chris Zwilling <chris@cloudnet.com>
  *
  * 4.51  Dec 23, 1998  -- Jens Axboe <axboe@image.dk>
  *                      - ide_cdrom_reset enabled since the ide subsystem
@@ -224,17 +223,17 @@
  *                      - Detect DVD-ROM/RAM drives
  *
  * 4.53  Feb 22, 1999   - Include other model Samsung and one Goldstar
- *                         drive in transfer size limit.
+ *                        drive in transfer size limit.
  *                      - Fix the I/O error when doing eject without a medium
- *                         loaded on some drives.
+ *                        loaded on some drives.
  *                      - CDROMREADMODE2 is now implemented through
- *                         CDROMREADRAW, since many drives don't support
- *                         MODE2 (even though ATAPI 2.6 says they must).
+ *                        CDROMREADRAW, since many drives don't support
+ *                        MODE2 (even though ATAPI 2.6 says they must).
  *                      - Added ignore parameter to ide-cd (as a module), eg
- *                         	insmod ide-cd ignore='hda hdb'
- *                         Useful when using ide-cd in conjunction with
- *                         ide-scsi. TODO: non-modular way of doing the
- *                         same.
+ *			  insmod ide-cd ignore='hda hdb'
+ *                        Useful when using ide-cd in conjunction with
+ *                        ide-scsi. TODO: non-modular way of doing the
+ *                        same.
  *
  * 4.54  Aug 5, 1999	- Support for MMC2 class commands through the generic
  *			  packet interface to cdrom.c.
@@ -270,7 +269,7 @@
  *			- Mode sense and mode select moved to the
  *			  Uniform layer.
  *			- Fixed a problem with WPI CDS-32X drive - it
- *			  failed the capabilities 
+ *			  failed the capabilities
  *
  * 4.57  Apr 7, 2000	- Fixed sense reporting.
  *			- Fixed possible oops in ide_cdrom_get_last_session()
@@ -293,7 +292,7 @@
  *			  Michael D Johnson <johnsom@orst.edu>
  *
  *************************************************************************/
- 
+
 #define IDECD_VERSION "4.59"
 
 #include <linux/config.h>
@@ -326,63 +325,68 @@
 static void cdrom_saw_media_change (ide_drive_t *drive)
 {
 	struct cdrom_info *info = drive->driver_data;
-	
+
 	CDROM_STATE_FLAGS (drive)->media_changed = 1;
 	CDROM_STATE_FLAGS (drive)->toc_valid = 0;
 	info->nsectors_buffered = 0;
 }
 
-static int cdrom_log_sense(ide_drive_t *drive, struct packet_command *pc,
-			   struct request_sense *sense)
+static
+void cdrom_analyze_sense_data(ide_drive_t *drive, struct request *rq)
 {
 	int log = 0;
+	/* FIXME --mdcki */
+	struct packet_command *pc = (struct packet_command *) rq->special;
+	struct packet_command *failed_command = (struct packet_command *) pc->sense;
+	struct request_sense *sense = (struct request_sense *) (pc->buffer - rq->cmd[4]);
+	unsigned char fail_cmd;
 
-	if (sense == NULL || pc == NULL || pc->quiet)
-		return 0;
+	if (sense == NULL || failed_command == NULL || failed_command->quiet)
+		return;
 
+	fail_cmd = rq->cmd[0];
+
+	/* Check whatever this error should be logged:
+	 */
 	switch (sense->sense_key) {
-		case NO_SENSE: case RECOVERED_ERROR:
+		case NO_SENSE:
+		case RECOVERED_ERROR:
 			break;
+
 		case NOT_READY:
-			/*
-			 * don't care about tray state messages for
-			 * e.g. capacity commands or in-progress or
-			 * becoming ready
+
+			/* Don't care about tray state messages for e.g.
+			 * capacity commands or in-progress or becoming ready.
 			 */
 			if (sense->asc == 0x3a || sense->asc == 0x04)
 				break;
 			log = 1;
 			break;
+
 		case UNIT_ATTENTION:
-			/*
-			 * Make good and sure we've seen this potential media
+
+			/* Make good and sure we've seen this potential media
 			 * change. Some drives (i.e. Creative) fail to present
 			 * the correct sense key in the error register.
 			 */
 			cdrom_saw_media_change(drive);
 			break;
+
 		default:
 			log = 1;
 			break;
 	}
-	return log;
-}
-
-static
-void cdrom_analyze_sense_data(ide_drive_t *drive,
-			      struct packet_command *failed_command,
-			      struct request_sense *sense)
-{
 
-	if (!cdrom_log_sense(drive, failed_command, sense))
+	if (!log)
 		return;
 
 	/*
-	 * If a read toc is executed for a CD-R or CD-RW medium where
-	 * the first toc has not been recorded yet, it will fail with
-	 * 05/24/00 (which is a confusing error)
+	 * If a read toc is executed for a CD-R or CD-RW medium where the first
+	 * toc has not been recorded yet, it will fail with 05/24/00 (which is
+	 * a confusing error).
 	 */
-	if (failed_command && failed_command->c[0] == GPCMD_READ_TOC_PMA_ATIP)
+
+	if (fail_cmd == GPCMD_READ_TOC_PMA_ATIP)
 		if (sense->sense_key == 0x05 && sense->asc == 0x24)
 			return;
 
@@ -445,28 +449,26 @@
 		printk("  %s -- (asc=0x%02x, ascq=0x%02x)\n",
 			s, sense->asc, sense->ascq);
 
-		if (failed_command != NULL) {
+		{
 
 			int lo=0, mid, hi= ARY_LEN (packet_command_texts);
 			s = NULL;
 
 			while (hi > lo) {
 				mid = (lo + hi) / 2;
-				if (packet_command_texts[mid].packet_command ==
-				    failed_command->c[0]) {
+				if (packet_command_texts[mid].packet_command == fail_cmd) {
 					s = packet_command_texts[mid].text;
 					break;
 				}
-				if (packet_command_texts[mid].packet_command >
-				    failed_command->c[0])
+				if (packet_command_texts[mid].packet_command > fail_cmd)
 					hi = mid;
 				else
 					lo = mid+1;
 			}
 
 			printk ("  The failed \"%s\" packet command was: \n  \"", s);
-			for (i=0; i<sizeof (failed_command->c); i++)
-				printk ("%02x ", failed_command->c[i]);
+			for (i=0; i < CDROM_PACKET_SIZE; i++)
+				printk ("%02x ", rq->cmd[i]);
 			printk ("\"\n");
 		}
 
@@ -495,7 +497,7 @@
 		}
 	}
 
-#else /* not VERBOSE_IDE_CD_ERRORS */
+#else
 
 	/* Suppress printing unit attention and `in progress of becoming ready'
 	   errors when we're not being verbose. */
@@ -509,7 +511,7 @@
 		drive->name,
 		sense->error_code, sense->sense_key,
 		sense->asc, sense->ascq);
-#endif /* not VERBOSE_IDE_CD_ERRORS */
+#endif
 }
 
 static void cdrom_queue_request_sense(ide_drive_t *drive,
@@ -525,16 +527,20 @@
 		sense = &info->sense_data;
 
 	memset(pc, 0, sizeof(struct packet_command));
-	pc->c[0] = GPCMD_REQUEST_SENSE;
-	pc->c[4] = pc->buflen = 18;
-	pc->buffer = (char *) sense;
+	pc->buffer = (void *) sense;
+	pc->buflen = 18;
 	pc->sense = (struct request_sense *) failed_command;
 
 	/* stuff the sense request in front of our current request */
 	rq = &info->request_sense_request;
+	rq->cmd[0] = GPCMD_REQUEST_SENSE;
+	rq->cmd[4] = pc->buflen;
 	ide_init_drive_cmd(rq);
 	rq->flags = REQ_SENSE;
+
+	/* FIXME --mdcki */
 	rq->special = (char *) pc;
+
 	rq->waiting = wait;
 	ide_do_drive_cmd(drive, rq, ide_preempt);
 }
@@ -544,16 +550,13 @@
 {
 	struct request *rq = HWGROUP(drive)->rq;
 
-	if ((rq->flags & REQ_SENSE) && uptodate) {
-		struct packet_command *pc = (struct packet_command *) rq->special;
-		cdrom_analyze_sense_data(drive,
-			(struct packet_command *) pc->sense,
-			(struct request_sense *) (pc->buffer - pc->c[4]));
-	}
+	if ((rq->flags & REQ_SENSE) && uptodate)
+		cdrom_analyze_sense_data(drive, rq);
 
 	if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
 		uptodate = 1;
 
+	/* FIXME --mdcki */
 	HWGROUP(drive)->rq->special = NULL;
 	ide_end_request(drive, uptodate);
 }
@@ -567,7 +570,7 @@
 	struct request *rq = HWGROUP(drive)->rq;
 	int stat, err, sense_key;
 	struct packet_command *pc;
-	
+
 	/* Check for errors. */
 	stat = GET_STAT();
 	*stat_ret = stat;
@@ -590,6 +593,7 @@
 		   from the drive (probably while trying
 		   to recover from a former error).  Just give up. */
 
+		/* FIXME --mdcki */
 		pc = (struct packet_command *) rq->special;
 		pc->stat = 1;
 		cdrom_end_request(drive, 1);
@@ -598,6 +602,8 @@
 	} else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
 		/* All other functions, except for READ. */
 		struct completion *wait = NULL;
+
+		/* FIXME --mdcki */
 		pc = (struct packet_command *) rq->special;
 
 		/* Check for tray open. */
@@ -612,15 +618,14 @@
 			/* Otherwise, print an error. */
 			ide_dump_status(drive, "packet command error", stat);
 		}
-		
+
 		/* Set the error flag and complete the request.
-		   Then, if we have a CHECK CONDITION status,
-		   queue a request sense command.  We must be careful,
-		   though: we don't want the thread in
-		   cdrom_queue_packet_command to wake up until
-		   the request sense has completed.  We do this
-		   by transferring the semaphore from the packet
-		   command request to the request sense request. */
+		   Then, if we have a CHECK CONDITION status, queue a request
+		   sense command.  We must be careful, though: we don't want
+		   the thread in cdrom_queue_packet_command to wake up until
+		   the request sense has completed.  We do this by transferring
+		   the semaphore from the packet command request to the request
+		   sense request. */
 
 		if ((stat & ERR_STAT) != 0) {
 			wait = rq->waiting;
@@ -756,22 +761,15 @@
 	}
 }
 
-/* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
-   The device registers must have already been prepared
-   by cdrom_start_packet_command.
-   HANDLER is the interrupt handler to call when the command completes
-   or there's data ready. */
 /*
- * changed 5 parameters to 3 for dvd-ram
- * struct packet_command *pc; now packet_command_t *pc;
+ * Send a packet command cmd to the drive.  The device registers must have
+ * already been prepared by cdrom_start_packet_command.  "handler" is the
+ * interrupt handler to call when the command completes or there's data ready.
  */
 static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
-					  struct packet_command *pc,
-					  ide_handler_t *handler)
+		unsigned char *cmd, unsigned long timeout,
+		ide_handler_t *handler)
 {
-	unsigned char *cmd_buf	= pc->c;
-	int cmd_len		= sizeof(pc->c);
-	unsigned int timeout	= pc->timeout;
 	ide_startstop_t startstop;
 
 	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
@@ -780,20 +778,21 @@
 		int stat_dum;
 
 		/* Check for errors. */
-		if (cdrom_decode_status (&startstop, drive, DRQ_STAT, &stat_dum))
+		if (cdrom_decode_status(&startstop, drive, DRQ_STAT, &stat_dum))
 			return startstop;
 	} else {
 		/* Otherwise, we must wait for DRQ to get set. */
-		if (ide_wait_stat (&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY))
+		if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY))
 			return startstop;
 	}
 
 	/* Arm the interrupt handler. */
 	BUG_ON(HWGROUP(drive)->handler);
-	ide_set_handler (drive, handler, timeout, cdrom_timer_expiry);
+	ide_set_handler(drive, handler, timeout, cdrom_timer_expiry);
 
 	/* Send the command to the device. */
-	atapi_output_bytes (drive, cmd_buf, cmd_len);
+	atapi_output_bytes(drive, cmd, CDROM_PACKET_SIZE);
+
 	return ide_started;
 }
 
@@ -889,7 +888,7 @@
 /*
  * Interrupt routine.  Called when a read request has completed.
  */
-static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
+static ide_startstop_t cdrom_read_intr(ide_drive_t *drive)
 {
 	int stat;
 	int ireason, len, sectors_to_transfer, nskip;
@@ -908,7 +907,7 @@
 
 	if (cdrom_decode_status (&startstop, drive, 0, &stat))
 		return startstop;
- 
+
 	if (dma) {
 		if (!dma_error) {
 			__ide_end_request(drive, 1, rq->nr_sectors);
@@ -1071,14 +1070,12 @@
 }
 
 /*
- * Routine to send a read packet command to the drive.
- * This is usually called directly from cdrom_start_read.
- * However, for drq_interrupt devices, it is called from an interrupt
- * when the drive is ready to accept the command.
+ * Routine to send a read packet command to the drive.  This is usually called
+ * directly from cdrom_start_read.  However, for drq_interrupt devices, it is
+ * called from an interrupt when the drive is ready to accept the command.
  */
-static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive)
+static ide_startstop_t cdrom_start_read_continuation(ide_drive_t *drive)
 {
-	struct packet_command pc;
 	struct request *rq = HWGROUP(drive)->rq;
 	int nsect, sector, nframes, frame, nskip;
 
@@ -1117,15 +1114,11 @@
 
 	/* Largest number of frames was can transfer at once is 64k-1. For
 	   some drives we need to limit this even more. */
-	nframes = MIN (nframes, (CDROM_CONFIG_FLAGS (drive)->limit_nframes) ?
+	nframes = MIN(nframes, (CDROM_CONFIG_FLAGS (drive)->limit_nframes) ?
 		(65534 / CD_FRAMESIZE) : 65535);
 
-	/* Set up the command */
-	memcpy(pc.c, rq->cmd, sizeof(pc.c));
-	pc.timeout = WAIT_CMD;
-
 	/* Send the command to the drive and return. */
-	return cdrom_transfer_packet_command(drive, &pc, &cdrom_read_intr);
+	return cdrom_transfer_packet_command(drive, rq->cmd, WAIT_CMD, &cdrom_read_intr);
 }
 
 
@@ -1161,7 +1154,7 @@
 
 static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
 {
-	struct packet_command pc;
+	unsigned char cmd[CDROM_PACKET_SIZE];
 	struct request *rq = HWGROUP(drive)->rq;
 	int sector, frame, nskip;
 
@@ -1172,11 +1165,10 @@
 	frame = sector / SECTORS_PER_FRAME;
 
 	memset(rq->cmd, 0, sizeof(rq->cmd));
-	pc.c[0] = GPCMD_SEEK;
-	put_unaligned(cpu_to_be32(frame), (unsigned int *) &pc.c[2]);
+	cmd[0] = GPCMD_SEEK;
+	put_unaligned(cpu_to_be32(frame), (unsigned int *) &cmd[2]);
 
-	pc.timeout = WAIT_CMD;
-	return cdrom_transfer_packet_command(drive, &pc, &cdrom_seek_intr);
+	return cdrom_transfer_packet_command(drive, cmd, WAIT_CMD, &cdrom_seek_intr);
 }
 
 static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
@@ -1243,15 +1235,13 @@
  * Execute all other packet commands.
  */
 
-/* Forward declarations. */
-static int cdrom_lockdoor(ide_drive_t *drive, int lockflag,
-			  struct request_sense *sense);
-
 /* Interrupt routine for packet command completion. */
 static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
 {
 	int ireason, len, stat, thislen;
 	struct request *rq = HWGROUP(drive)->rq;
+
+	/* FIXME --mdcki */
 	struct packet_command *pc = (struct packet_command *) rq->special;
 	ide_startstop_t startstop;
 
@@ -1268,7 +1258,7 @@
 	if ((stat & DRQ_STAT) == 0) {
 		/* Some of the trailing request sense fields are optional, and
 		   some drives don't send them.  Sigh. */
-		if (pc->c[0] == GPCMD_REQUEST_SENSE &&
+		if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
 		    pc->buflen > 0 &&
 		    pc->buflen <= 5) {
 			while (pc->buflen > 0) {
@@ -1346,24 +1336,29 @@
 	return ide_started;
 }
 
-
-static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive)
+static ide_startstop_t cdrom_do_pc_continuation(ide_drive_t *drive)
 {
 	struct request *rq = HWGROUP(drive)->rq;
+	unsigned long timeout;
+
+	/* FIXME --mdcki */
 	struct packet_command *pc = (struct packet_command *) rq->special;
 
-	if (!pc->timeout)
-		pc->timeout = WAIT_CMD;
+	if (pc->timeout)
+		timeout = pc->timeout;
+	else
+		timeout = WAIT_CMD;
 
 	/* Send the command to the drive and return. */
-	return cdrom_transfer_packet_command(drive, pc, &cdrom_pc_intr);
+	return cdrom_transfer_packet_command(drive, rq->cmd, timeout, &cdrom_pc_intr);
 }
 
-
 static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
 {
 	int len;
 	struct request *rq = HWGROUP(drive)->rq;
+
+	/* FIXME --mdcki */
 	struct packet_command *pc = (struct packet_command *) rq->special;
 	struct cdrom_info *info = drive->driver_data;
 
@@ -1391,23 +1386,28 @@
 }
 
 static
-int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc)
+int cdrom_queue_packet_command(ide_drive_t *drive, unsigned char *cmd, struct packet_command *pc)
 {
 	struct request_sense sense;
-	struct request req;
+	struct request rq;
 	int retries = 10;
 
+	memcpy(rq.cmd, cmd, CDROM_PACKET_SIZE);
+
 	if (pc->sense == NULL)
 		pc->sense = &sense;
 
 	/* Start of retry loop. */
 	do {
-		ide_init_drive_cmd (&req);
-		req.flags = REQ_PC;
-		req.special = (char *) pc;
-		if (ide_do_drive_cmd (drive, &req, ide_wait)) {
+		ide_init_drive_cmd(&rq);
+
+		rq.flags = REQ_PC;
+
+		/* FIXME --mdcki */
+		rq.special = (void *) pc;
+		if (ide_do_drive_cmd(drive, &rq, ide_wait)) {
 			printk("%s: do_drive_cmd returned stat=%02x,err=%02x\n",
-				drive->name, req.buffer[0], req.buffer[1]);
+				drive->name, rq.buffer[0], rq.buffer[1]);
 			/* FIXME: we should probably abort/retry or something */
 		}
 		if (pc->stat != 0) {
@@ -1493,7 +1493,7 @@
 		printk("ide-cd: write_intr decode_status bad\n");
 		return startstop;
 	}
- 
+
 	/*
 	 * using dma, transfer is complete now
 	 */
@@ -1573,20 +1573,9 @@
 
 static ide_startstop_t cdrom_start_write_cont(ide_drive_t *drive)
 {
-	struct packet_command pc;	/* packet_command_t pc; */
 	struct request *rq = HWGROUP(drive)->rq;
-	unsigned nframes, frame;
-
-	nframes = rq->nr_sectors >> 2;
-	frame = rq->sector >> 2;
-
-	memcpy(pc.c, rq->cmd, sizeof(pc.c));
-#if 0	/* the immediate bit */
-	pc.c[1] = 1 << 3;
-#endif
-	pc.timeout = 2 * WAIT_CMD;
 
-	return cdrom_transfer_packet_command(drive, &pc, cdrom_write_intr);
+	return cdrom_transfer_packet_command(drive, rq->cmd, 2 * WAIT_CMD, cdrom_write_intr);
 }
 
 static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
@@ -1620,34 +1609,13 @@
 	return cdrom_start_packet_command(drive, 32768, cdrom_start_write_cont);
 }
 
-/*
- * just wrap this around cdrom_do_packet_command
- */
-static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
-{
-	struct packet_command pc;
-	ide_startstop_t startstop;
-
-	memset(&pc, 0, sizeof(pc));
-	memcpy(pc.c, rq->cmd, sizeof(pc.c));
-	pc.quiet = 1;
-	pc.timeout = 60 * HZ;
-	rq->special = (char *) &pc;
-
-	startstop = cdrom_do_packet_command(drive);
-	if (pc.stat)
-		rq->errors++;
-
-	return startstop;
-}
-
 #define IDE_LARGE_SEEK(b1,b2,t)	(((b1) > (b2) + (t)) || ((b2) > (b1) + (t)))
 
 /****************************************************************************
  * cdrom driver request routine.
  */
 static ide_startstop_t
-ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, unsigned long block)
+ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, unsigned long block)
 {
 	ide_startstop_t action;
 	struct cdrom_info *info = drive->driver_data;
@@ -1679,18 +1647,31 @@
 	} else if (rq->flags & (REQ_PC | REQ_SENSE)) {
 		return cdrom_do_packet_command(drive);
 	} else if (rq->flags & REQ_SPECIAL) {
-
 		/*
-		 * FIXME: Kill REQ_SEPCIAL and replace it will command commands
-		 * queued at the request queue instead as suggested (abd
-		 * rightly so) by Linus.
+		 * FIXME: Kill REQ_SEPCIAL and replace it with commands queued
+		 * at the request queue instead as suggested by Linus.
 		 *
 		 * right now this can only be a reset...
 		 */
-		cdrom_end_request(drive, 1); return ide_stopped;
 
+		cdrom_end_request(drive, 1);
+		return ide_stopped;
 	} else if (rq->flags & REQ_BLOCK_PC) {
-		return cdrom_do_block_pc(drive, rq);
+		struct packet_command pc;
+		ide_startstop_t startstop;
+
+		memset(&pc, 0, sizeof(pc));
+		pc.quiet = 1;
+		pc.timeout = 60 * HZ;
+
+		/* FIXME --mdcki */
+		rq->special = (char *) &pc;
+
+		startstop = cdrom_do_packet_command(drive);
+		if (pc.stat)
+			++rq->errors;
+
+		return startstop;
 	}
 
 	blk_dump_rq_flags(rq, "ide-cd bad flags");
@@ -1755,6 +1736,7 @@
 
 static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
 {
+	unsigned char cmd[CDROM_PACKET_SIZE];
 	struct packet_command pc;
 	struct cdrom_info *info = drive->driver_data;
 	struct cdrom_device_info *cdi = &info->devinfo;
@@ -1762,16 +1744,16 @@
 	memset(&pc, 0, sizeof(pc));
 	pc.sense = sense;
 
-	pc.c[0] = GPCMD_TEST_UNIT_READY;
+	cmd[0] = GPCMD_TEST_UNIT_READY;
 
-#if ! STANDARD_ATAPI
-        /* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to 
+#if !STANDARD_ATAPI
+        /* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to
            switch CDs instead of supporting the LOAD_UNLOAD opcode   */
 
-        pc.c[7] = cdi->sanyo_slot % 3;
-#endif /* not STANDARD_ATAPI */
+        cmd[7] = cdi->sanyo_slot % 3;
+#endif
 
-	return cdrom_queue_packet_command(drive, &pc);
+	return cdrom_queue_packet_command(drive, cmd, &pc);
 }
 
 
@@ -1779,22 +1761,20 @@
 static int
 cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense)
 {
-	struct request_sense my_sense;
 	struct packet_command pc;
 	int stat;
 
-	if (sense == NULL)
-		sense = &my_sense;
-
 	/* If the drive cannot lock the door, just pretend. */
 	if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
 		stat = 0;
 	} else {
+		unsigned char cmd[CDROM_PACKET_SIZE];
+
 		memset(&pc, 0, sizeof(pc));
 		pc.sense = sense;
-		pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
-		pc.c[4] = lockflag ? 1 : 0;
-		stat = cdrom_queue_packet_command (drive, &pc);
+		cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
+		cmd[4] = lockflag ? 1 : 0;
+		stat = cdrom_queue_packet_command(drive, cmd, &pc);
 	}
 
 	/* If we got an illegal field error, the drive
@@ -1807,7 +1787,7 @@
 		CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
 		stat = 0;
 	}
-	
+
 	/* no medium, that's alright. */
 	if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a)
 		stat = 0;
@@ -1825,10 +1805,11 @@
 		       struct request_sense *sense)
 {
 	struct packet_command pc;
+	unsigned char cmd[CDROM_PACKET_SIZE];
 
 	if (CDROM_CONFIG_FLAGS(drive)->no_eject && !ejectflag)
 		return -EDRIVE_CANT_DO_THIS;
-	
+
 	/* reload fails on some drives, if the tray is locked */
 	if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag)
 		return 0;
@@ -1836,9 +1817,9 @@
 	memset(&pc, 0, sizeof (pc));
 	pc.sense = sense;
 
-	pc.c[0] = GPCMD_START_STOP_UNIT;
-	pc.c[4] = 0x02 + (ejectflag != 0);
-	return cdrom_queue_packet_command (drive, &pc);
+	cmd[0] = GPCMD_START_STOP_UNIT;
+	cmd[4] = 0x02 + (ejectflag != 0);
+	return cdrom_queue_packet_command(drive, cmd, &pc);
 }
 
 static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
@@ -1850,16 +1831,16 @@
 	} capbuf;
 
 	int stat;
+	unsigned char cmd[CDROM_PACKET_SIZE];
 	struct packet_command pc;
 
 	memset(&pc, 0, sizeof(pc));
 	pc.sense = sense;
 
-	pc.c[0] = GPCMD_READ_CDVD_CAPACITY;
+	cmd[0] = GPCMD_READ_CDVD_CAPACITY;
 	pc.buffer = (char *)&capbuf;
 	pc.buflen = sizeof(capbuf);
-
-	stat = cdrom_queue_packet_command(drive, &pc);
+	stat = cdrom_queue_packet_command(drive, cmd, &pc);
 	if (stat == 0)
 		*capacity = 1 + be32_to_cpu(capbuf.lba);
 
@@ -1870,6 +1851,7 @@
 				int format, char *buf, int buflen,
 				struct request_sense *sense)
 {
+	unsigned char cmd[CDROM_PACKET_SIZE];
 	struct packet_command pc;
 
 	memset(&pc, 0, sizeof(pc));
@@ -1878,16 +1860,16 @@
 	pc.buffer =  buf;
 	pc.buflen = buflen;
 	pc.quiet = 1;
-	pc.c[0] = GPCMD_READ_TOC_PMA_ATIP;
-	pc.c[6] = trackno;
-	pc.c[7] = (buflen >> 8);
-	pc.c[8] = (buflen & 0xff);
-	pc.c[9] = (format << 6);
 
+	cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
 	if (msf_flag)
-		pc.c[1] = 2;
+		cmd[1] = 2;
+	cmd[6] = trackno;
+	cmd[7] = (buflen >> 8);
+	cmd[8] = (buflen & 0xff);
+	cmd[9] = (format << 6);
 
-	return cdrom_queue_packet_command (drive, &pc);
+	return cdrom_queue_packet_command(drive, cmd, &pc);
 }
 
 
@@ -1916,7 +1898,7 @@
 
 	/* Check to see if the existing data is still valid.
 	   If it is, just return. */
-	(void) cdrom_check_status(drive, sense);
+	cdrom_check_status(drive, sense);
 
 	if (CDROM_STATE_FLAGS(drive)->toc_valid)
 		return 0;
@@ -2049,6 +2031,7 @@
 static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf,
 				 int buflen, struct request_sense *sense)
 {
+	unsigned char cmd[CDROM_PACKET_SIZE];
 	struct packet_command pc;
 
 	memset(&pc, 0, sizeof(pc));
@@ -2056,13 +2039,14 @@
 
 	pc.buffer = buf;
 	pc.buflen = buflen;
-	pc.c[0] = GPCMD_READ_SUBCHANNEL;
-	pc.c[1] = 2;     /* MSF addressing */
-	pc.c[2] = 0x40;  /* request subQ data */
-	pc.c[3] = format;
-	pc.c[7] = (buflen >> 8);
-	pc.c[8] = (buflen & 0xff);
-	return cdrom_queue_packet_command(drive, &pc);
+	cmd[0] = GPCMD_READ_SUBCHANNEL;
+	cmd[1] = 2;     /* MSF addressing */
+	cmd[2] = 0x40;  /* request subQ data */
+	cmd[3] = format;
+	cmd[7] = (buflen >> 8);
+	cmd[8] = (buflen & 0xff);
+
+	return cdrom_queue_packet_command(drive, cmd, &pc);
 }
 
 /* ATAPI cdrom drives are free to select the speed you request or any slower
@@ -2070,6 +2054,7 @@
 static int cdrom_select_speed(ide_drive_t *drive, int speed,
 			      struct request_sense *sense)
 {
+	unsigned char cmd[CDROM_PACKET_SIZE];
 	struct packet_command pc;
 	memset(&pc, 0, sizeof(pc));
 	pc.sense = sense;
@@ -2079,36 +2064,37 @@
 	else
 		speed *= 177;   /* Nx to kbytes/s */
 
-	pc.c[0] = GPCMD_SET_SPEED;
+	cmd[0] = GPCMD_SET_SPEED;
 	/* Read Drive speed in kbytes/second MSB */
-	pc.c[2] = (speed >> 8) & 0xff;	
+	cmd[2] = (speed >> 8) & 0xff;
 	/* Read Drive speed in kbytes/second LSB */
-	pc.c[3] = speed & 0xff;
+	cmd[3] = speed & 0xff;
 	if (CDROM_CONFIG_FLAGS(drive)->cd_r ||
 	    CDROM_CONFIG_FLAGS(drive)->cd_rw ||
 	    CDROM_CONFIG_FLAGS(drive)->dvd_r) {
 		/* Write Drive speed in kbytes/second MSB */
-		pc.c[4] = (speed >> 8) & 0xff;
+		cmd[4] = (speed >> 8) & 0xff;
 		/* Write Drive speed in kbytes/second LSB */
-		pc.c[5] = speed & 0xff;
+		cmd[5] = speed & 0xff;
        }
 
-	return cdrom_queue_packet_command(drive, &pc);
+	return cdrom_queue_packet_command(drive, cmd, &pc);
 }
 
 static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end)
 {
 	struct request_sense sense;
+	unsigned char cmd[CDROM_PACKET_SIZE];
 	struct packet_command pc;
 
 	memset(&pc, 0, sizeof (pc));
 	pc.sense = &sense;
 
-	pc.c[0] = GPCMD_PLAY_AUDIO_MSF;
-	lba_to_msf(lba_start, &pc.c[3], &pc.c[4], &pc.c[5]);
-	lba_to_msf(lba_end-1, &pc.c[6], &pc.c[7], &pc.c[8]);
+	cmd[0] = GPCMD_PLAY_AUDIO_MSF;
+	lba_to_msf(lba_start, &cmd[3], &cmd[4], &cmd[5]);
+	lba_to_msf(lba_end-1, &cmd[6], &cmd[7], &cmd[8]);
 
-	return cdrom_queue_packet_command(drive, &pc);
+	return cdrom_queue_packet_command(drive, cmd, &pc);
 }
 
 static int cdrom_get_toc_entry(ide_drive_t *drive, int track,
@@ -2152,15 +2138,15 @@
 	   layer. the packet must be complete, as we do not
 	   touch it at all. */
 	memset(&pc, 0, sizeof(pc));
-	memcpy(pc.c, cgc->cmd, CDROM_PACKET_SIZE);
 	pc.buffer = cgc->buffer;
 	pc.buflen = cgc->buflen;
 	pc.quiet = cgc->quiet;
 	pc.timeout = cgc->timeout;
 	pc.sense = cgc->sense;
-	cgc->stat = cdrom_queue_packet_command(drive, &pc);
+	cgc->stat = cdrom_queue_packet_command(drive, cgc->cmd, &pc);
 	if (!cgc->stat)
 		cgc->buflen -= pc.buflen;
+
 	return cgc->stat;
 }
 
@@ -2177,34 +2163,34 @@
 
 	/* These will be moved into the Uniform layer shortly... */
 	switch (cmd) {
- 	case CDROMSETSPINDOWN: {
- 		char spindown;
- 
- 		if (copy_from_user(&spindown, (void *) arg, sizeof(char)))
+	case CDROMSETSPINDOWN: {
+		char spindown;
+
+		if (copy_from_user(&spindown, (void *) arg, sizeof(char)))
 			return -EFAULT;
- 
+
                 if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0)))
 			return stat;
 
- 		buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
+		buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
+
+		return cdrom_mode_select(cdi, &cgc);
+	}
+
+	case CDROMGETSPINDOWN: {
+		char spindown;
 
- 		return cdrom_mode_select(cdi, &cgc);
- 	} 
- 
- 	case CDROMGETSPINDOWN: {
- 		char spindown;
- 
                 if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0)))
 			return stat;
- 
- 		spindown = buffer[11] & 0x0f;
- 
+
+		spindown = buffer[11] & 0x0f;
+
 		if (copy_to_user((void *) arg, &spindown, sizeof (char)))
 			return -EFAULT;
- 
- 		return 0;
- 	}
-  
+
+		return 0;
+	}
+
 	default:
 		return -EINVAL;
 	}
@@ -2214,7 +2200,6 @@
 static
 int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
 			   unsigned int cmd, void *arg)
-			   
 {
 	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
 	struct cdrom_info *info = drive->driver_data;
@@ -2306,31 +2291,34 @@
 	 * lock it again.
 	 */
 	if (CDROM_STATE_FLAGS(drive)->door_locked)
-		(void) cdrom_lockdoor(drive, 1, &sense);
+		cdrom_lockdoor(drive, 1, &sense);
 
 	return ret;
 }
 
 
 static
-int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
+int ide_cdrom_tray_move(struct cdrom_device_info *cdi, int position)
 {
 	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
 	struct request_sense sense;
 
 	if (position) {
 		int stat = cdrom_lockdoor(drive, 0, &sense);
-		if (stat) return stat;
+		if (stat)
+			return stat;
 	}
 
 	return cdrom_eject(drive, !position, &sense);
 }
 
 static
-int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
+int ide_cdrom_lock_door(struct cdrom_device_info *cdi, int lock)
 {
 	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
-	return cdrom_lockdoor(drive, lock, NULL);
+	struct request_sense sense;
+
+	return cdrom_lockdoor(drive, lock, &sense);
 }
 
 static
@@ -2433,9 +2421,9 @@
 {
 	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
 	int retval;
-	
+
 	if (slot_nr == CDSL_CURRENT) {
-		(void) cdrom_check_status(drive, NULL);
+		cdrom_check_status(drive, NULL);
 		retval = CDROM_STATE_FLAGS (drive)->media_changed;
 		CDROM_STATE_FLAGS (drive)->media_changed = 0;
 		return retval;
@@ -2502,7 +2490,7 @@
 	*(int *)&devinfo->capacity = nslots;
 	devinfo->handle = (void *) drive;
 	strcpy(devinfo->name, drive->name);
-	
+
 	/* set capability mask to match the probe. */
 	if (!CDROM_CONFIG_FLAGS (drive)->cd_r)
 		devinfo->mask |= CDC_CD_R;
@@ -2578,8 +2566,8 @@
 	int nslots = 1;
 
 	if (CDROM_CONFIG_FLAGS (drive)->nec260) {
-		CDROM_CONFIG_FLAGS (drive)->no_eject = 0;                       
-		CDROM_CONFIG_FLAGS (drive)->audio_play = 1;       
+		CDROM_CONFIG_FLAGS (drive)->no_eject = 0;
+		CDROM_CONFIG_FLAGS (drive)->audio_play = 1;
 		return nslots;
 	}
 
@@ -2632,14 +2620,14 @@
 
 	/* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
 	if (drive->id && !drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) {
-		CDROM_STATE_FLAGS (drive)->current_speed  = 
+		CDROM_STATE_FLAGS (drive)->current_speed  =
 			(((unsigned int)cap.curspeed) + (176/2)) / 176;
-		CDROM_CONFIG_FLAGS (drive)->max_speed = 
+		CDROM_CONFIG_FLAGS (drive)->max_speed =
 			(((unsigned int)cap.maxspeed) + (176/2)) / 176;
 	} else {
-		CDROM_STATE_FLAGS (drive)->current_speed  = 
+		CDROM_STATE_FLAGS (drive)->current_speed  =
 			(ntohs(cap.curspeed) + (176/2)) / 176;
-		CDROM_CONFIG_FLAGS (drive)->max_speed = 
+		CDROM_CONFIG_FLAGS (drive)->max_speed =
 			(ntohs(cap.maxspeed) + (176/2)) / 176;
 	}
 
@@ -2651,19 +2639,19 @@
 	printk(" %s", CDROM_CONFIG_FLAGS(drive)->dvd ? "DVD-ROM" : "CD-ROM");
 
 	if (CDROM_CONFIG_FLAGS (drive)->dvd_r|CDROM_CONFIG_FLAGS (drive)->dvd_ram)
-        	printk (" DVD%s%s", 
-        	(CDROM_CONFIG_FLAGS (drive)->dvd_r)? "-R" : "", 
-        	(CDROM_CONFIG_FLAGS (drive)->dvd_ram)? "-RAM" : "");
-
-        if (CDROM_CONFIG_FLAGS (drive)->cd_r|CDROM_CONFIG_FLAGS (drive)->cd_rw) 
-        	printk (" CD%s%s", 
-        	(CDROM_CONFIG_FLAGS (drive)->cd_r)? "-R" : "", 
-        	(CDROM_CONFIG_FLAGS (drive)->cd_rw)? "/RW" : "");
-
-        if (CDROM_CONFIG_FLAGS (drive)->is_changer) 
-        	printk (" changer w/%d slots", nslots);
-        else 	
-        	printk (" drive");
+		printk (" DVD%s%s",
+		(CDROM_CONFIG_FLAGS (drive)->dvd_r)? "-R" : "",
+		(CDROM_CONFIG_FLAGS (drive)->dvd_ram)? "-RAM" : "");
+
+        if (CDROM_CONFIG_FLAGS (drive)->cd_r|CDROM_CONFIG_FLAGS (drive)->cd_rw)
+		printk (" CD%s%s",
+		(CDROM_CONFIG_FLAGS (drive)->cd_r)? "-R" : "",
+		(CDROM_CONFIG_FLAGS (drive)->cd_rw)? "/RW" : "");
+
+        if (CDROM_CONFIG_FLAGS (drive)->is_changer)
+		printk (" changer w/%d slots", nslots);
+        else
+		printk (" drive");
 
 	printk (", %dkB Cache", be16_to_cpu(cap.buffer_size));
 
@@ -2678,7 +2666,8 @@
 
 static void ide_cdrom_add_settings(ide_drive_t *drive)
 {
-	ide_add_setting(drive,	"dsc_overlap",		SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1,	1, &drive->dsc_overlap, NULL);
+	ide_add_setting(drive, "dsc_overlap",
+			SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1,	1, &drive->dsc_overlap, NULL);
 }
 
 static
@@ -2728,7 +2717,7 @@
 	CDROM_CONFIG_FLAGS (drive)->supp_disc_present = 0;
 	CDROM_CONFIG_FLAGS (drive)->audio_play = 0;
 	CDROM_CONFIG_FLAGS (drive)->close_tray = 1;
-	
+
 	/* limit transfer size per interrupt. */
 	CDROM_CONFIG_FLAGS (drive)->limit_nframes = 0;
 	if (drive->id != NULL) {
@@ -2763,16 +2752,12 @@
 			CDROM_CONFIG_FLAGS (drive)->tocaddr_as_bcd = 1;
 			CDROM_CONFIG_FLAGS (drive)->playmsf_as_bcd = 1;
 			CDROM_CONFIG_FLAGS (drive)->subchan_as_bcd = 1;
-		}
-
-		else if (strcmp (drive->id->model, "V006E0DS") == 0 &&
+		} else if (strcmp (drive->id->model, "V006E0DS") == 0 &&
 		    drive->id->fw_rev[4] == '1' &&
 		    drive->id->fw_rev[6] <= '2') {
 			/* Vertos 600 ESD. */
 			CDROM_CONFIG_FLAGS (drive)->toctracks_as_bcd = 1;
-		}
-
-		else if (strcmp (drive->id->model,
+		} else if (strcmp (drive->id->model,
 				 "NEC CD-ROM DRIVE:260") == 0 &&
 			 strncmp (drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */
 			/* Old NEC260 (not R).
@@ -2782,9 +2767,7 @@
 			CDROM_CONFIG_FLAGS (drive)->playmsf_as_bcd = 1;
 			CDROM_CONFIG_FLAGS (drive)->subchan_as_bcd = 1;
 			CDROM_CONFIG_FLAGS (drive)->nec260         = 1;
-		}
-
-		else if (strcmp (drive->id->model, "WEARNES CDD-120") == 0 &&
+		} else if (strcmp (drive->id->model, "WEARNES CDD-120") == 0 &&
 			 strncmp (drive->id->fw_rev, "A1.1", 4) == 0) { /* FIXME */
 			/* Wearnes */
 			CDROM_CONFIG_FLAGS (drive)->playmsf_as_bcd = 1;
@@ -2989,7 +2972,7 @@
 			kfree (info);
 			continue;
 		}
-		memset (info, 0, sizeof (struct cdrom_info));
+		memset(info, 0, sizeof (struct cdrom_info));
 		drive->driver_data = info;
 
 		MOD_INC_USE_COUNT;
diff -urN linux-2.5.8/drivers/ide/ide-cd.h linux/drivers/ide/ide-cd.h
--- linux-2.5.8/drivers/ide/ide-cd.h	Mon Mar 18 21:37:18 2002
+++ linux/drivers/ide/ide-cd.h	Mon Apr 15 09:11:15 2002
@@ -15,7 +15,7 @@
    memory, though. */
 
 #ifndef VERBOSE_IDE_CD_ERRORS
-#define VERBOSE_IDE_CD_ERRORS 1
+# define VERBOSE_IDE_CD_ERRORS 1
 #endif
 
 
@@ -24,7 +24,7 @@
    this will give you a slightly smaller kernel. */
 
 #ifndef STANDARD_ATAPI
-#define STANDARD_ATAPI 0
+# define STANDARD_ATAPI 0
 #endif
 
 
@@ -32,14 +32,14 @@
    This is apparently needed for supermount. */
 
 #ifndef NO_DOOR_LOCKING
-#define NO_DOOR_LOCKING 0
+# define NO_DOOR_LOCKING 0
 #endif
 
 /************************************************************************/
 
-#define SECTOR_BITS 		9
+#define SECTOR_BITS		9
 #ifndef SECTOR_SIZE
-#define SECTOR_SIZE		(1 << SECTOR_BITS)
+# define SECTOR_SIZE		(1 << SECTOR_BITS)
 #endif
 #define SECTORS_PER_FRAME	(CD_FRAMESIZE >> SECTOR_BITS)
 #define SECTOR_BUFFER_SIZE	(CD_FRAMESIZE * 32)
@@ -50,12 +50,6 @@
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 
-/* special command codes for strategy routine. */
-#define PACKET_COMMAND        4315
-#define REQUEST_SENSE_COMMAND 4316
-#define RESET_DRIVE_COMMAND   4317
-
-
 /* Configuration flags.  These describe the capabilities of the drive.
    They generally do not change after initialization, unless we learn
    more about the drive from stuff failing. */
@@ -90,7 +84,6 @@
 };
 #define CDROM_CONFIG_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->config_flags))
 
- 
 /* State flags.  These give information about the current state of the
    drive, and will change during normal operation. */
 struct ide_cd_state_flags {
@@ -111,24 +104,23 @@
 	int quiet;
 	int timeout;
 	struct request_sense *sense;
-	unsigned char c[12];
 };
 
 /* Structure of a MSF cdrom address. */
 struct atapi_msf {
-	byte reserved;
-	byte minute;
-	byte second;
-	byte frame;
-};
+	u8 __reserved;
+	u8 minute;
+	u8 second;
+	u8 frame;
+} __attribute__((packed));
 
 /* Space to hold the disk TOC. */
 #define MAX_TRACKS 99
 struct atapi_toc_header {
-	unsigned short toc_length;
-	byte first_track;
-	byte last_track;
-};
+	u16 toc_length;
+	u8 first_track;
+	u8 last_track;
+} __attribute__((packed));
 
 struct atapi_toc_entry {
 	byte reserved1;
@@ -162,17 +154,17 @@
 /* This structure is annoyingly close to, but not identical with,
    the cdrom_subchnl structure from cdrom.h. */
 struct atapi_cdrom_subchnl {
- 	u_char  acdsc_reserved;
- 	u_char  acdsc_audiostatus;
- 	u_short acdsc_length;
-	u_char  acdsc_format;
+	u8	acdsc_reserved;
+	u8	acdsc_audiostatus;
+	u16	acdsc_length;
+	u8	acdsc_format;
 
 #if defined(__BIG_ENDIAN_BITFIELD)
-	u_char  acdsc_ctrl:     4;
-	u_char  acdsc_adr:      4;
+	u8	acdsc_ctrl:     4;
+	u8	acdsc_adr:      4;
 #elif defined(__LITTLE_ENDIAN_BITFIELD)
-	u_char  acdsc_adr:	4;
-	u_char  acdsc_ctrl:	4;
+	u8	acdsc_adr:	4;
+	u8	acdsc_ctrl:	4;
 #else
 #error "Please fix <asm/byteorder.h>"
 #endif
diff -urN linux-2.5.8/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.8/drivers/ide/ide-taskfile.c	Mon Apr 15 08:53:44 2002
+++ linux/drivers/ide/ide-taskfile.c	Mon Apr 15 10:01:31 2002
@@ -980,7 +980,7 @@
 
 	/* FIXME: Do we really have to zero out the buffer?
 	 */
-	memset(argbuf, 0, 4 + SECTOR_WORDS * 4 * vals[3]);
+	memset(argbuf, 4, SECTOR_WORDS * 4 * vals[3]);
 	ide_init_drive_cmd(&rq);
 	rq.buffer = argbuf;
 	memcpy(argbuf, vals, 4);
diff -urN linux-2.5.8/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.8/drivers/ide/ide.c	Mon Apr 15 08:53:44 2002
+++ linux/drivers/ide/ide.c	Mon Apr 15 10:17:15 2002
@@ -2701,7 +2701,11 @@
 
 void ide_teardown_commandlist(ide_drive_t *drive)
 {
-	struct pci_dev *pdev= drive->channel->pci_dev;
+#ifdef CONFIG_BLK_DEV_IDEPCI
+	struct pci_dev *pdev = drive->channel->pci_dev;
+#else
+	struct pci_dev *pdev = NULL;
+#endif
 	struct list_head *entry;
 
 	list_for_each(entry, &drive->free_req) {
@@ -2716,7 +2720,11 @@
 
 int ide_build_commandlist(ide_drive_t *drive)
 {
-	struct pci_dev *pdev= drive->channel->pci_dev;
+#ifdef CONFIG_BLK_DEV_IDEPCI
+	struct pci_dev *pdev = drive->channel->pci_dev;
+#else
+	struct pci_dev *pdev = NULL;
+#endif
 	struct ata_request *ar;
 	ide_tag_info_t *tcq;
 	int i, err;
@@ -2764,9 +2772,9 @@
 	if (i) {
 		drive->queue_depth = i;
 		if (i >= 1) {
-			drive->using_tcq = 1;
 			drive->tcq->queued = 0;
 			drive->tcq->active_tag = -1;
+
 			return 0;
 		}
 

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

* Re: [PATCH] 2.5.8 IDE 34
  2002-04-15  8:51   ` Jens Axboe
@ 2002-04-15  8:11     ` Martin Dalecki
  0 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-04-15  8:11 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, Kernel Mailing List

Jens Axboe wrote:
> On Mon, Apr 15 2002, Martin Dalecki wrote:
> 
> Two comments --
> 
> Could you please _not_ just rearrange comments or change style in ide-cd
> just for the sake cleaning, it's very annoying when one has patches that
> need to be adapted every time. And it serves zero purpose. Thanks.

Please do me a small favour and use an editor which highlights trailing white
spaces please? The bandwidth waste caused by this is an waste of energy
and causes a significant amount of environmental pollution...

> I changed the CONFIG_BLK_DEV_IDEPCI stuff to always include the pci_dev
> in the hwgroup, and just leave it at NULL if not defined. This cleans up
> some ifdefs, I think this is the better approach.

Agreed.

> I'll sync the latest tcq stuff with you later today, it gets the
> enabling right etc.

Fine. I would like to go on with the request handling changes in ide-cd.c
thereafter.

> And a last comment not directly related to this particular patch -- when
> you include something and change minor stuff along the way, please do it
> in two steps. One that includes a patch, and a second version that
> changes what you want to change. That makes merging _so_ much easier.
> Thanks.

OK - sorry. I try already to make the granularity of the
patches smaller. Since I always apply patches line by line I wasn't aware of
your "modus operandi".


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

* Re: [PATCH] 2.5.8 IDE 34
  2002-04-15  7:42 ` [PATCH] 2.5.8 IDE 34 Martin Dalecki
@ 2002-04-15  8:51   ` Jens Axboe
  2002-04-15  8:11     ` Martin Dalecki
  0 siblings, 1 reply; 39+ messages in thread
From: Jens Axboe @ 2002-04-15  8:51 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, Kernel Mailing List

On Mon, Apr 15 2002, Martin Dalecki wrote:

Two comments --

Could you please _not_ just rearrange comments or change style in ide-cd
just for the sake cleaning, it's very annoying when one has patches that
need to be adapted every time. And it serves zero purpose. Thanks.

I changed the CONFIG_BLK_DEV_IDEPCI stuff to always include the pci_dev
in the hwgroup, and just leave it at NULL if not defined. This cleans up
some ifdefs, I think this is the better approach.

I'll sync the latest tcq stuff with you later today, it gets the
enabling right etc.

And a last comment not directly related to this particular patch -- when
you include something and change minor stuff along the way, please do it
in two steps. One that includes a patch, and a second version that
changes what you want to change. That makes merging _so_ much easier.
Thanks.

-- 
Jens Axboe


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

* [PATCH] 2.5.8 IDE 40
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (7 preceding siblings ...)
  2002-04-15  7:42 ` [PATCH] 2.5.8 IDE 34 Martin Dalecki
@ 2002-04-22 15:36 ` Martin Dalecki
  2002-04-25 14:32 ` [PATCH] 2.5.10 IDE 41 Martin Dalecki
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-04-22 15:36 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Thu Apr 18 00:08:00 CEST 2002 ide-clean-40

This applies on top of 2.5.8, all patches up to IDE 39 + the laters ide-update
for 2.5.8. from Jens Axboe.

- Make the ide-cd driver usable again in DMA mode by adapting it to the TCQ
   related request handling changes and fixing some other minor stuff related to
   this. This patch is ugly like hell I know. Cleanup will follow separately.
   It was hard enough to make this going agian at all.

[-- Attachment #2: ide-clean-40.diff --]
[-- Type: text/plain, Size: 4372 bytes --]

diff -urN linux-2.5.8/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.8/drivers/ide/ide-cd.c	Mon Apr 22 18:31:37 2002
+++ linux/drivers/ide/ide-cd.c	Mon Apr 22 18:23:43 2002
@@ -535,9 +535,9 @@
 
 	/* stuff the sense request in front of our current request */
 	rq = &info->request_sense_request;
+	ide_init_drive_cmd(rq);
 	rq->cmd[0] = GPCMD_REQUEST_SENSE;
 	rq->cmd[4] = pc->buflen;
-	ide_init_drive_cmd(rq);
 	rq->flags = REQ_SENSE;
 
 	/* FIXME --mdcki */
@@ -558,8 +558,10 @@
 	if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
 		uptodate = 1;
 
+#if 0
 	/* FIXME --mdcki */
 	HWGROUP(drive)->rq->special = NULL;
+#endif
 	ide_end_request(drive, uptodate);
 }
 
@@ -1215,13 +1217,22 @@
 /*
  * Start a read request from the CD-ROM.
  */
-static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
+static ide_startstop_t cdrom_start_read(struct ata_device *drive, struct ata_request *ar, unsigned int block)
 {
 	struct cdrom_info *info = drive->driver_data;
-	struct request *rq = HWGROUP(drive)->rq;
+	struct request *rq = ar->ar_rq;
+
+	if (ar->ar_flags & ATA_AR_QUEUED) {
+//		spin_lock_irqsave(DRIVE_LOCK(drive), flags);
+		blkdev_dequeue_request(rq);
+//		spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
+	}
+
 
 	restore_request(rq);
 
+	rq->special = ar;
+
 	/* Satisfy whatever we can of this request from our cached sector. */
 	if (cdrom_read_from_buffer(drive))
 		return ide_stopped;
@@ -1404,10 +1415,10 @@
 	struct request rq;
 	int retries = 10;
 
-	memcpy(rq.cmd, cmd, CDROM_PACKET_SIZE);
 	/* Start of retry loop. */
 	do {
 		ide_init_drive_cmd(&rq);
+		memcpy(rq.cmd, cmd, CDROM_PACKET_SIZE);
 
 		rq.flags = REQ_PC;
 
@@ -1630,12 +1641,14 @@
  * cdrom driver request routine.
  */
 static ide_startstop_t
-ide_do_rw_cdrom(ide_drive_t *drive, struct request *rq, unsigned long block)
+ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
 	ide_startstop_t action;
 	struct cdrom_info *info = drive->driver_data;
 
 	if (rq->flags & REQ_CMD) {
+	
+
 		if (CDROM_CONFIG_FLAGS(drive)->seeking) {
 			unsigned long elpased = jiffies - info->start_seek;
 			int stat = GET_STAT();
@@ -1652,8 +1665,30 @@
 		if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
 			action = cdrom_start_seek (drive, block);
 		else {
+			unsigned long flags;
+			struct ata_request *ar;
+
+			/*
+			 * get a new command (push ar further down to avoid grabbing lock here
+			 */
+			spin_lock_irqsave(DRIVE_LOCK(drive), flags);
+
+			ar = ata_ar_get(drive);
+
+			/*
+			 * we've reached maximum queue depth, bail
+			 */
+			if (!ar) {
+				spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
+
+				return ide_started;
+			}
+
+			ar->ar_rq = rq;
+			spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
+
 			if (rq_data_dir(rq) == READ)
-				action = cdrom_start_read(drive, block);
+				action = cdrom_start_read(drive, ar, block);
 			else
 				action = cdrom_start_write(drive, rq);
 		}
@@ -2297,7 +2332,7 @@
 	struct request req;
 	int ret;
 
-	ide_init_drive_cmd (&req);
+	ide_init_drive_cmd(&req);
 	req.flags = REQ_SPECIAL;
 	ret = ide_do_drive_cmd(drive, &req, ide_wait);
 
@@ -2927,7 +2962,7 @@
 	owner:			THIS_MODULE,
 	cleanup:		ide_cdrom_cleanup,
 	standby:		NULL,
-	do_request:		ide_do_rw_cdrom,
+	do_request:		ide_cdrom_do_request,
 	end_request:		NULL,
 	ioctl:			ide_cdrom_ioctl,
 	open:			ide_cdrom_open,
diff -urN linux-2.5.8/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.8/drivers/ide/ide-dma.c	Mon Apr 22 18:31:40 2002
+++ linux/drivers/ide/ide-dma.c	Mon Apr 22 13:19:24 2002
@@ -549,8 +549,11 @@
 	/* This can happen with drivers abusing the special request field.
 	 */
 
-	if (!ar)
+	if (!ar) {
+		printk(KERN_ERR "DMA without ATA request\n");
+
 		return 1;
+	}
 
 	if (rq_data_dir(ar->ar_rq) == READ)
 		reading = 1 << 3;
diff -urN linux-2.5.8/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.8/drivers/ide/ide-probe.c	Mon Apr 22 18:31:32 2002
+++ linux/drivers/ide/ide-probe.c	Mon Apr 22 18:08:45 2002
@@ -168,6 +168,9 @@
 		}
 		printk (" drive\n");
 		drive->type = type;
+
+		goto init_queue;
+
 		return;
 	}
 
@@ -198,6 +201,7 @@
 	if (drive->channel->quirkproc)
 		drive->quirk_list = drive->channel->quirkproc(drive);
 
+init_queue:
 	/*
 	 * it's an ata drive, build command list
 	 */

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

* [PATCH] 2.5.10 IDE 41
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (8 preceding siblings ...)
  2002-04-22 15:36 ` [PATCH] 2.5.8 IDE 40 Martin Dalecki
@ 2002-04-25 14:32 ` Martin Dalecki
  2002-04-25 17:39   ` Jens Axboe
  2002-04-30  8:09 ` [PATCH] 2.5.11 IDE 46 Martin Dalecki
                   ` (7 subsequent siblings)
  17 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-04-25 14:32 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Tue Apr 23 00:27:55 CEST 2002 ide-clean-41

- Revoke the TCQ stuff. Well having it for some time showed just nicely what
   has to be done before it can be included cleanly. But it's just not ready
   jet.

   For more explanations please simply track the usage of the special field of
   struct request - *both* in the generic request handling code and in overall
   driver code.

[-- Attachment #2: ide-clean-41.diff --]
[-- Type: text/plain, Size: 85401 bytes --]

diff -urN linux-2.5.10/drivers/ide/Config.help linux/drivers/ide/Config.help
--- linux-2.5.10/drivers/ide/Config.help	2002-04-23 00:29:44.000000000 +0200
+++ linux/drivers/ide/Config.help	2002-04-25 15:35:49.000000000 +0200
@@ -749,35 +749,6 @@
 
   Generally say N here.
 
-CONFIG_BLK_DEV_IDE_TCQ
-  Support for tagged command queueing on ATA disk drives. This enables
-  the IDE layer to have multiple in-flight requests on hardware that
-  supports it. For now this includes the IBM Deskstar series drives,
-  such as the 22GXP, 75GXP, 40GV, 60GXP, and 120GXP (ie any Deskstar made
-  in the last couple of years), and at least some of the Western
-  Digital drives in the Expert series.
-
-  If you have such a drive, say Y here.
-
-CONFIG_BLK_DEV_IDE_TCQ_DEPTH
-  Maximum size of commands to enable per-drive. Any value between 1
-  and 32 is valid, with 32 being the maxium that the hardware supports.
-
-  You probably just want the default of 32 here. If you enter an invalid
-  number, the default value will be used.
-
-CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-  Enabled tagged command queueing unconditionally on drives that report
-  support for it. Regardless of the chosen value here, tagging can be
-  controlled at run time:
-
-  echo "using_tcq:32" > /proc/ide/hdX/settings
-
-  where any value between 1-32 selects chosen queue depth and enables
-  TCQ, and 0 disables it.
-
-  Generally say Y here.
-
 CONFIG_BLK_DEV_IT8172
   Say Y here to support the on-board IDE controller on the Integrated
   Technology Express, Inc. ITE8172 SBC.  Vendor page at
diff -urN linux-2.5.10/drivers/ide/Config.in linux/drivers/ide/Config.in
--- linux-2.5.10/drivers/ide/Config.in	2002-04-23 00:29:45.000000000 +0200
+++ linux/drivers/ide/Config.in	2002-04-25 14:17:08.000000000 +0200
@@ -47,11 +47,6 @@
 	 dep_bool '      Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI
          dep_bool '    Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
 	 define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI
-	 dep_bool '    ATA tagged command queueing' CONFIG_BLK_DEV_IDE_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI
-	 dep_bool '      TCQ on by default' CONFIG_BLK_DEV_IDE_TCQ_DEFAULT $CONFIG_BLK_DEV_IDE_TCQ
-	 if [ "$CONFIG_BLK_DEV_IDE_TCQ" != "n" ]; then
-	    int '      Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 32
-	 fi
 	 dep_bool '    ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
 	 dep_bool '    Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP
 	 dep_bool '    AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI
diff -urN linux-2.5.10/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.10/drivers/ide/ide.c	2002-04-23 00:29:02.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-04-25 17:09:29.000000000 +0200
@@ -368,40 +368,6 @@
 	return 0;	/* no, it is not a flash memory card */
 }
 
-void ide_end_queued_request(ide_drive_t *drive, int uptodate, struct request *rq)
-{
-	unsigned long flags;
-
-	BUG_ON(!(rq->flags & REQ_STARTED));
-	BUG_ON(!rq->special);
-
-	if (!end_that_request_first(rq, uptodate, rq->hard_nr_sectors)) {
-		struct ata_request *ar = rq->special;
-
-		add_blkdev_randomness(major(rq->rq_dev));
-
-		spin_lock_irqsave(&ide_lock, flags);
-
-		if ((jiffies - ar->ar_time > ATA_AR_MAX_TURNAROUND) && drive->queue_depth > 1) {
-			printk(KERN_INFO "%s: exceeded max command turn-around time (%d seconds)\n", drive->name, ATA_AR_MAX_TURNAROUND / HZ);
-			drive->queue_depth >>= 1;
-		}
-
-		if (jiffies - ar->ar_time > drive->tcq->oldest_command)
-			drive->tcq->oldest_command = jiffies - ar->ar_time;
-
-		ata_ar_put(drive, ar);
-		end_that_request_last(rq);
-		/*
-		 * IDE_SET_CUR_TAG(drive, IDE_INACTIVE_TAG) will do this
-		 * too, but it really belongs here. assumes that the
-		 * ended request is the active one.
-		 */
-		HWGROUP(drive)->rq = NULL;
-		spin_unlock_irqrestore(&ide_lock, flags);
-	}
-}
-
 int __ide_end_request(ide_drive_t *drive, int uptodate, int nr_secs)
 {
 	struct request *rq;
@@ -430,17 +396,9 @@
 	}
 
 	if (!end_that_request_first(rq, uptodate, nr_secs)) {
-		struct ata_request *ar = rq->special;
-
 		add_blkdev_randomness(major(rq->rq_dev));
-		/*
-		 * request with ATA_AR_QUEUED set have already been
-		 * dequeued, but doing it twice is ok
-		 */
 		blkdev_dequeue_request(rq);
 		HWGROUP(drive)->rq = NULL;
-		if (ar)
-			ata_ar_put(drive, ar);
 		end_that_request_last(rq);
 		ret = 0;
 	}
@@ -776,11 +734,8 @@
 			args[6] = IN_BYTE(IDE_SELECT_REG);
 		}
 	} else if (rq->flags & REQ_DRIVE_TASKFILE) {
-		struct ata_request *ar = rq->special;
-		struct ata_taskfile *args = &ar->ar_task;
-
+		struct ata_taskfile *args = rq->special;
 		rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT);
-
 		if (args) {
 			args->taskfile.feature = err;
 			args->taskfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
@@ -803,7 +758,6 @@
 				args->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
 			}
 		}
-		ata_ar_put(drive, ar);
 	}
 
 	blkdev_dequeue_request(rq);
@@ -920,11 +874,6 @@
 	struct request *rq;
 	byte err;
 
-	/*
-	 * FIXME: remember to invalidate tcq queue when drive->using_tcq
-	 * and atomic_read(&drive->tcq->queued) /jens
-	 */
-
 	err = ide_dump_status(drive, msg, stat);
 	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
 		return ide_stopped;
@@ -1127,14 +1076,11 @@
 			 */
 
 			if (rq->flags & REQ_DRIVE_TASKFILE) {
-				struct ata_request *ar = rq->special;
-				struct ata_taskfile *args;
+				struct ata_taskfile *args = rq->special;
 
-				if (!ar)
+				if (!(args))
 					goto args_error;
 
-				args = &ar->ar_task;
-
 				ata_taskfile(drive, args, NULL);
 
 				if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
@@ -1258,170 +1204,25 @@
 /*
  * Select the next drive which will be serviced.
  */
-static ide_drive_t *choose_drive(ide_hwgroup_t *hwgroup)
+static inline ide_drive_t *choose_drive(ide_hwgroup_t *hwgroup)
 {
-	ide_drive_t *tmp;
-	ide_drive_t *drive = NULL;
-	unsigned long sleep = 0;
+	ide_drive_t *drive, *best;
 
-	tmp = hwgroup->drive;
+	best = NULL;
+	drive = hwgroup->drive;
 	do {
-		if (!list_empty(&tmp->queue.queue_head)
-		&& (!tmp->PADAM_sleep || time_after_eq(tmp->PADAM_sleep, jiffies))) {
-			if (!drive
-			 || (tmp->PADAM_sleep && (!drive->PADAM_sleep || time_after(drive->PADAM_sleep, tmp->PADAM_sleep)))
-			 || (!drive->PADAM_sleep && time_after(drive->PADAM_service_start + 2 * drive->PADAM_service_time, tmp->PADAM_service_start + 2 * tmp->PADAM_service_time)))
+		if (!list_empty(&drive->queue.queue_head)
+		&& (!drive->PADAM_sleep	|| time_after_eq(drive->PADAM_sleep, jiffies))) {
+			if (!best
+			 || (drive->PADAM_sleep && (!best->PADAM_sleep || time_after(best->PADAM_sleep, drive->PADAM_sleep)))
+			 || (!best->PADAM_sleep && time_after(best->PADAM_service_start + 2 * best->PADAM_service_time, drive->PADAM_service_start + 2 * drive->PADAM_service_time)))
 			{
-				if (!blk_queue_plugged(&tmp->queue))
-					drive = tmp;
+				if (!blk_queue_plugged(&drive->queue))
+					best = drive;
 			}
 		}
-		tmp = tmp->next;
-	} while (tmp != hwgroup->drive);
-
-	if (drive)
-		return drive;
-
-	hwgroup->rq = NULL;
-	drive = hwgroup->drive;
-	do {
-		if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
-			sleep = drive->PADAM_sleep;
 	} while ((drive = drive->next) != hwgroup->drive);
-
-	if (sleep) {
-		/*
-		 * Take a short snooze, and then wake up this hwgroup
-		 * again.  This gives other hwgroups on the same a
-		 * chance to play fairly with us, just in case there
-		 * are big differences in relative throughputs.. don't
-		 * want to hog the cpu too much.
-		 */
-		if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep))
-			sleep = jiffies + WAIT_MIN_SLEEP;
-
-		if (timer_pending(&hwgroup->timer))
-			printk("ide_set_handler: timer already active\n");
-
-		set_bit(IDE_SLEEP, &hwgroup->flags);
-		mod_timer(&hwgroup->timer, sleep);
-		/* we purposely leave hwgroup busy while
-		 * sleeping */
-	} else {
-		/* Ugly, but how can we sleep for the lock
-		 * otherwise? perhaps from tq_disk? */
-		ide_release_lock(&ide_intr_lock);/* for atari only */
-		clear_bit(IDE_BUSY, &hwgroup->flags);
-	}
-
-	return NULL;
-}
-
-/*
- * feed commands to a drive until it barfs. used to be part of ide_do_request.
- * called with ide_lock/DRIVE_LOCK held and busy hwgroup
- */
-static void ide_queue_commands(ide_drive_t *drive, int masked_irq)
-{
-	ide_hwgroup_t *hwgroup = HWGROUP(drive);
-	ide_startstop_t startstop = -1;
-	struct request *rq;
-
-	do {
-		rq = NULL;
-
-		if (!test_bit(IDE_BUSY, &hwgroup->flags))
-			printk("%s: hwgroup not busy while queueing\n", drive->name);
-
-		/*
-		 * abort early if we can't queue another command. for non
-		 * tcq, ide_can_queue is always 1 since we never get here
-		 * unless the drive is idle.
-		 */
-		if (!ide_can_queue(drive)) {
-			if (!ide_pending_commands(drive))
-				clear_bit(IDE_BUSY, &hwgroup->flags);
-			break;
-		}
-
-		drive->PADAM_sleep = 0;
-		drive->PADAM_service_start = jiffies;
-
-		if (test_bit(IDE_DMA, &hwgroup->flags)) {
-			printk("ide_do_request: DMA in progress...\n");
-			break;
-		}
-
-		/*
-		 * there's a small window between where the queue could be
-		 * replugged while we are in here when using tcq (in which
-		 * case the queue is probably empty anyways...), so check
-		 * and leave if appropriate. When not using tcq, this is
-		 * still a severe BUG!
-		 */
-		if (blk_queue_plugged(&drive->queue)) {
-			BUG_ON(!drive->using_tcq);
-			break;
-		}
-
-		if (!(rq = elv_next_request(&drive->queue))) {
-			if (!ide_pending_commands(drive))
-				clear_bit(IDE_BUSY, &hwgroup->flags);
-			hwgroup->rq = NULL;
-			break;
-		}
-
-		/*
-		 * if there are queued commands, we can't start a non-fs
-		 * request (really, a non-queuable command) until the
-		 * queue is empty
-		 */
-		if (!(rq->flags & REQ_CMD) && ide_pending_commands(drive))
-			break;
-
-		hwgroup->rq = rq;
-
-		/*
-		 * Some systems have trouble with IDE IRQs arriving while
-		 * the driver is still setting things up.  So, here we disable
-		 * the IRQ used by this interface while the request is being
-		 * started.  This may look bad at first, but pretty much the
-		 * same thing happens anyway when any interrupt comes in, IDE
-		 * or otherwise -- the kernel masks the IRQ while it is being
-		 * handled.
-		 */
-		if (masked_irq && HWIF(drive)->irq != masked_irq)
-			disable_irq_nosync(HWIF(drive)->irq);
-
-		spin_unlock(&ide_lock);
-		ide__sti();	/* allow other IRQs while we start this request */
-		startstop = start_request(drive, rq);
-
-		spin_lock_irq(&ide_lock);
-		if (masked_irq && HWIF(drive)->irq != masked_irq)
-			enable_irq(HWIF(drive)->irq);
-
-		/*
-		 * command started, we are busy
-		 */
-		if (startstop == ide_started)
-			break;
-
-		/*
-		 * start_request() can return either ide_stopped (no command
-		 * was started), ide_started (command started, don't queue
-		 * more), or ide_released (command started, try and queue
-		 * more).
-		 */
-#if 0
-		if (startstop == ide_stopped)
-			set_bit(IDE_BUSY, &hwgroup->flags);
-#endif
-
-	} while (1);
-
-	if (startstop == ide_started)
-		return;
+	return best;
 }
 
 /*
@@ -1458,34 +1259,86 @@
 {
 	ide_drive_t *drive;
 	struct ata_channel *hwif;
+	ide_startstop_t	startstop;
+	struct request	*rq;
 
 	ide_get_lock(&ide_intr_lock, ide_intr, hwgroup);/* for atari only: POSSIBLY BROKEN HERE(?) */
 
 	__cli();	/* necessary paranoia: ensure IRQs are masked on local CPU */
 
 	while (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) {
-
-		/*
-		 * will clear IDE_BUSY, if appropriate
-		 */
-		if ((drive = choose_drive(hwgroup)) == NULL)
-			break;
-
+		drive = choose_drive(hwgroup);
+		if (drive == NULL) {
+			unsigned long sleep = 0;
+			hwgroup->rq = NULL;
+			drive = hwgroup->drive;
+			do {
+				if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
+					sleep = drive->PADAM_sleep;
+			} while ((drive = drive->next) != hwgroup->drive);
+			if (sleep) {
+				/*
+				 * Take a short snooze, and then wake up this hwgroup again.
+				 * This gives other hwgroups on the same a chance to
+				 * play fairly with us, just in case there are big differences
+				 * in relative throughputs.. don't want to hog the cpu too much.
+				 */
+				if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep))
+					sleep = jiffies + WAIT_MIN_SLEEP;
+#if 1
+				if (timer_pending(&hwgroup->timer))
+					printk("ide_set_handler: timer already active\n");
+#endif
+				set_bit(IDE_SLEEP, &hwgroup->flags);
+				mod_timer(&hwgroup->timer, sleep);
+				/* we purposely leave hwgroup busy while sleeping */
+			} else {
+				/* Ugly, but how can we sleep for the lock otherwise? perhaps from tq_disk? */
+				ide_release_lock(&ide_intr_lock);/* for atari only */
+				clear_bit(IDE_BUSY, &hwgroup->flags);
+			}
+			return;		/* no more work for this hwgroup (for now) */
+		}
 		hwif = drive->channel;
-		if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif && IDE_CONTROL_REG) {
+		if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif && hwif->io_ports[IDE_CONTROL_OFFSET]) {
 			/* set nIEN for previous hwif */
+
 			if (hwif->intrproc)
 				hwif->intrproc(drive);
 			else
-				OUT_BYTE(drive->ctl|2, IDE_CONTROL_REG);
+				OUT_BYTE((drive)->ctl|2, hwif->io_ports[IDE_CONTROL_OFFSET]);
 		}
 		hwgroup->hwif = hwif;
 		hwgroup->drive = drive;
+		drive->PADAM_sleep = 0;
+		drive->PADAM_service_start = jiffies;
+
+		if (blk_queue_plugged(&drive->queue))
+			BUG();
+
+		/*
+		 * just continuing an interrupted request maybe
+		 */
+		rq = hwgroup->rq = elv_next_request(&drive->queue);
 
 		/*
-		 * main queueing loop
+		 * Some systems have trouble with IDE IRQs arriving while
+		 * the driver is still setting things up.  So, here we disable
+		 * the IRQ used by this interface while the request is being started.
+		 * This may look bad at first, but pretty much the same thing
+		 * happens anyway when any interrupt comes in, IDE or otherwise
+		 *  -- the kernel masks the IRQ while it is being handled.
 		 */
-		ide_queue_commands(drive, masked_irq);
+		if (masked_irq && hwif->irq != masked_irq)
+			disable_irq_nosync(hwif->irq);
+		spin_unlock(&ide_lock);
+		ide__sti();	/* allow other IRQs while we start this request */
+		startstop = start_request(drive, rq);
+		spin_lock_irq(&ide_lock);
+		if (masked_irq && hwif->irq != masked_irq)
+			enable_irq(hwif->irq);
+		if (startstop == ide_stopped)
+			clear_bit(IDE_BUSY, &hwgroup->flags);
 	}
 }
 
@@ -1512,39 +1365,21 @@
  * un-busy the hwgroup etc, and clear any pending DMA status. we want to
  * retry the current request in PIO mode instead of risking tossing it
  * all away
- *
- * FIXME: needs a bit of tcq work
  */
 void ide_dma_timeout_retry(ide_drive_t *drive)
 {
 	struct ata_channel *hwif = drive->channel;
-	struct request *rq = NULL;
-	struct ata_request *ar = NULL;
-
-	if (drive->using_tcq) {
-		if (drive->tcq->active_tag != -1) {
-			ar = IDE_CUR_AR(drive);
-			rq = ar->ar_rq;
-		}
-	} else {
-		rq = HWGROUP(drive)->rq;
-		ar = rq->special;
-	}
+	struct request *rq;
 
 	/*
 	 * end current dma transaction
 	 */
-	if (rq)
-		hwif->dmaproc(ide_dma_end, drive);
+	hwif->dmaproc(ide_dma_end, drive);
 
 	/*
 	 * complain a little, later we might remove some of this verbosity
 	 */
-	printk("%s: timeout waiting for DMA", drive->name);
-	if (drive->using_tcq)
-		printk(" queued, active tag %d", drive->tcq->active_tag);
-	printk("\n");
-
+	printk("%s: timeout waiting for DMA\n", drive->name);
 	hwif->dmaproc(ide_dma_timeout, drive);
 
 	/*
@@ -1560,25 +1395,15 @@
 	 * un-busy drive etc (hwgroup->busy is cleared on return) and
 	 * make sure request is sane
 	 */
+	rq = HWGROUP(drive)->rq;
 	HWGROUP(drive)->rq = NULL;
 
-	if (!rq)
-		return;
-
 	rq->errors = 0;
 	if (rq->bio) {
 		rq->sector = rq->bio->bi_sector;
 		rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
 		rq->buffer = NULL;
 	}
-
-	/*
-	 *  this request was not on the queue any more
-	 */
-	if (ar->ar_flags & ATA_AR_QUEUED) {
-		ata_ar_put(drive, ar);
-		_elv_add_request(&drive->queue, rq, 0, 0);
-	}
 }
 
 /*
@@ -1814,16 +1639,13 @@
 	set_recovery_timer(drive->channel);
 	drive->PADAM_service_time = jiffies - drive->PADAM_service_start;
 	if (startstop == ide_stopped) {
-		if (hwgroup->handler == NULL) { /* paranoia */
+		if (hwgroup->handler == NULL) {	/* paranoia */
 			clear_bit(IDE_BUSY, &hwgroup->flags);
-			if (test_bit(IDE_DMA, &hwgroup->flags))
-				printk("ide_intr: illegal clear\n");
 			ide_do_request(hwgroup, hwif->irq);
 		} else {
 			printk("%s: ide_intr: huh? expected NULL handler on exit\n", drive->name);
 		}
-	} else if (startstop == ide_released)
-		ide_queue_commands(drive, hwif->irq);
+	}
 
 out_lock:
 	spin_unlock_irqrestore(&ide_lock, flags);
@@ -1898,7 +1720,6 @@
 	if (drive->channel->chipset == ide_pdc4030 && rq->buffer != NULL)
 		return -ENOSYS;  /* special drive cmds not supported */
 #endif
-	rq->flags |= REQ_STARTED;
 	rq->errors = 0;
 	rq->rq_status = RQ_ACTIVE;
 	rq->rq_dev = mk_kdev(major,(drive->select.b.unit)<<PARTN_BITS);
@@ -2222,7 +2043,6 @@
 		}
 		drive->present = 0;
 		blk_cleanup_queue(&drive->queue);
-		ide_teardown_commandlist(drive);
 	}
 	if (d->present)
 		hwgroup->drive = d;
@@ -2775,86 +2595,6 @@
 	}
 }
 
-int ide_build_commandlist(ide_drive_t *drive)
-{
-#ifdef CONFIG_BLK_DEV_IDEPCI
-	struct pci_dev *pdev = drive->channel->pci_dev;
-#else
-	struct pci_dev *pdev = NULL;
-#endif
-	struct list_head *p;
-	unsigned long flags;
-	struct ata_request *ar;
-	int i, cur;
-
-	spin_lock_irqsave(&ide_lock, flags);
-
-	cur = 0;
-	list_for_each(p, &drive->free_req)
-		cur++;
-
-	/*
-	 * for now, just don't shrink it...
-	 */
-	if (drive->queue_depth <= cur) {
-		spin_unlock_irqrestore(&ide_lock, flags);
-		return 0;
-	}
-
-	for (i = cur; i < drive->queue_depth; i++) {
-		ar = kmalloc(sizeof(*ar), GFP_ATOMIC);
-		if (!ar)
-			break;
-
-		memset(ar, 0, sizeof(*ar));
-		INIT_LIST_HEAD(&ar->ar_queue);
-
-		ar->ar_sg_table = kmalloc(PRD_SEGMENTS * sizeof(struct scatterlist), GFP_ATOMIC);
-		if (!ar->ar_sg_table) {
-			kfree(ar);
-			break;
-		}
-
-		ar->ar_dmatable_cpu = pci_alloc_consistent(pdev, PRD_SEGMENTS * PRD_BYTES, &ar->ar_dmatable);
-		if (!ar->ar_dmatable_cpu) {
-			kfree(ar->ar_sg_table);
-			kfree(ar);
-			break;
-		}
-
-		/*
-		 * pheew, all done, add to list
-		 */
-		list_add_tail(&ar->ar_queue, &drive->free_req);
-		++cur;
-	}
-	drive->queue_depth = cur;
-	spin_unlock_irqrestore(&ide_lock, flags);
-	return 0;
-}
-
-int ide_init_commandlist(ide_drive_t *drive)
-{
-	INIT_LIST_HEAD(&drive->free_req);
-
-	return ide_build_commandlist(drive);
-}
-
-void ide_teardown_commandlist(ide_drive_t *drive)
-{
-	struct pci_dev *pdev= drive->channel->pci_dev;
-	struct list_head *entry;
-
-	list_for_each(entry, &drive->free_req) {
-		struct ata_request *ar = list_ata_entry(entry);
-
-		list_del(&ar->ar_queue);
-		kfree(ar->ar_sg_table);
-		pci_free_consistent(pdev, PRD_SEGMENTS * PRD_BYTES, ar->ar_dmatable_cpu, ar->ar_dmatable);
-		kfree(ar);
-	}
-}
-
 static int ide_check_media_change (kdev_t i_rdev)
 {
 	ide_drive_t *drive;
@@ -3426,9 +3166,6 @@
 
 			drive->channel->dmaproc(ide_dma_off_quietly, drive);
 			drive->channel->dmaproc(ide_dma_check, drive);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-			drive->channel->dmaproc(ide_dma_queued_on, drive);
-#endif /* CONFIG_BLK_DEV_IDE_TCQ_DEFAULT */
 		}
 		/* Only CD-ROMs and tape drives support DSC overlap. */
 		drive->dsc_overlap = (drive->next != drive
diff -urN linux-2.5.10/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.10/drivers/ide/ide-cd.c	2002-04-23 00:28:59.000000000 +0200
+++ linux/drivers/ide/ide-cd.c	2002-04-25 16:05:40.000000000 +0200
@@ -558,10 +558,6 @@
 	if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
 		uptodate = 1;
 
-#if 0
-	/* FIXME --mdcki */
-	HWGROUP(drive)->rq->special = NULL;
-#endif
 	ide_end_request(drive, uptodate);
 }
 
@@ -1217,22 +1213,13 @@
 /*
  * Start a read request from the CD-ROM.
  */
-static ide_startstop_t cdrom_start_read(struct ata_device *drive, struct ata_request *ar, unsigned int block)
+static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
 {
 	struct cdrom_info *info = drive->driver_data;
-	struct request *rq = ar->ar_rq;
-
-	if (ar->ar_flags & ATA_AR_QUEUED) {
-//		spin_lock_irqsave(DRIVE_LOCK(drive), flags);
-		blkdev_dequeue_request(rq);
-//		spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-	}
-
+	struct request *rq = HWGROUP(drive)->rq;
 
 	restore_request(rq);
 
-	rq->special = ar;
-
 	/* Satisfy whatever we can of this request from our cached sector. */
 	if (cdrom_read_from_buffer(drive))
 		return ide_stopped;
@@ -1665,30 +1652,8 @@
 		if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
 			action = cdrom_start_seek (drive, block);
 		else {
-			unsigned long flags;
-			struct ata_request *ar;
-
-			/*
-			 * get a new command (push ar further down to avoid grabbing lock here
-			 */
-			spin_lock_irqsave(DRIVE_LOCK(drive), flags);
-
-			ar = ata_ar_get(drive);
-
-			/*
-			 * we've reached maximum queue depth, bail
-			 */
-			if (!ar) {
-				spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-
-				return ide_started;
-			}
-
-			ar->ar_rq = rq;
-			spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-
 			if (rq_data_dir(rq) == READ)
-				action = cdrom_start_read(drive, ar, block);
+				action = cdrom_start_read(drive, block);
 			else
 				action = cdrom_start_write(drive, rq);
 		}
diff -urN linux-2.5.10/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.10/drivers/ide/ide-disk.c	2002-04-23 00:27:41.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-04-25 17:09:29.000000000 +0200
@@ -88,162 +88,135 @@
 	return 0;	/* lba_capacity value may be bad */
 }
 
-/*
- * Determine the apriopriate hardware command correspnding to the action in
- * question, depending upon the device capabilities and setup.
- */
 static u8 get_command(ide_drive_t *drive, int cmd)
 {
 	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
-	/* Well, calculating the command in this variable may be an
-	 * overoptimization. */
-	u8 command = WIN_NOP;
 
 #if 1
 	lba48bit = drive->addressing;
 #endif
 
-	/*
-	 * 48-bit commands are pretty sanely laid out
-	 */
 	if (lba48bit) {
-		command = cmd == READ ? WIN_READ_EXT : WIN_WRITE_EXT;
-
-		if (drive->using_dma) {
-			command++;		/* WIN_*DMA_EXT */
-			if (drive->using_tcq)
-				command++;	/* WIN_*DMA_QUEUED_EXT */
-		} else if (drive->mult_count)
-			command += 5;		/* WIN_MULT*_EXT */
-
-		return command;
-	}
-
-	/*
-	 * 28-bit commands seem not to be, though...
-	 */
-	if (cmd == READ) {
-		if (drive->using_dma) {
-			if (drive->using_tcq)
-				command = WIN_READDMA_QUEUED;
+		if (cmd == READ) {
+			if (drive->using_dma)
+				return WIN_READDMA_EXT;
+			else if (drive->mult_count)
+				return WIN_MULTREAD_EXT;
 			else
-				command = WIN_READDMA;
-		} else if (drive->mult_count)
-			command = WIN_MULTREAD;
-		else
-			command = WIN_READ;
+				return WIN_READ_EXT;
+		} else if (cmd == WRITE) {
+			if (drive->using_dma)
+				return WIN_WRITEDMA_EXT;
+			else if (drive->mult_count)
+				return WIN_MULTWRITE_EXT;
+			else
+				return WIN_WRITE_EXT;
+		}
 	} else {
-		if (drive->using_dma) {
-			if (drive->using_tcq)
-				command = WIN_WRITEDMA_QUEUED;
+		if (cmd == READ) {
+			if (drive->using_dma)
+				return WIN_READDMA;
+			else if (drive->mult_count)
+				return WIN_MULTREAD;
+			else
+				return WIN_READ;
+		} else if (cmd == WRITE) {
+			if (drive->using_dma)
+				return WIN_WRITEDMA;
+			else if (drive->mult_count)
+				return WIN_MULTWRITE;
 			else
-				command = WIN_WRITEDMA;
-		} else if (drive->mult_count)
-			command = WIN_MULTWRITE;
-		else
-			command = WIN_WRITE;
+				return WIN_WRITE;
+		}
 	}
-
-	return command;
+	return WIN_NOP;
 }
 
-static ide_startstop_t chs_do_request(ide_drive_t *drive, struct ata_request *ar, sector_t block)
+static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
 {
-	struct ata_taskfile *args = &ar->ar_task;
-	struct request *rq = ar->ar_rq;
-	int sectors = rq->nr_sectors;
+	struct hd_drive_task_hdr	taskfile;
+	struct hd_drive_hob_hdr		hobfile;
+	struct ata_taskfile		args;
+	int				sectors;
 
-	unsigned int track = (block / drive->sect);
-	unsigned int sect = (block % drive->sect) + 1;
-	unsigned int head = (track % drive->head);
-	unsigned int cyl = (track / drive->head);
+	unsigned int track	= (block / drive->sect);
+	unsigned int sect	= (block % drive->sect) + 1;
+	unsigned int head	= (track % drive->head);
+	unsigned int cyl	= (track / drive->head);
 
-	memset(&args->taskfile, 0, sizeof(struct hd_drive_task_hdr));
-	memset(&args->hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 
+	sectors = rq->nr_sectors;
 	if (sectors == 256)
 		sectors = 0;
 
-	if (ar->ar_flags & ATA_AR_QUEUED) {
-		unsigned long flags;
+	taskfile.sector_count	= sectors;
 
-		args->taskfile.feature = sectors;
-		args->taskfile.sector_count = ar->ar_tag << 3;
-
-		spin_lock_irqsave(DRIVE_LOCK(drive), flags);
-		blkdev_dequeue_request(rq);
-		spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-	} else
-		args->taskfile.sector_count   = sectors;
-
-	args->taskfile.sector_number = sect;
-	args->taskfile.low_cylinder = cyl;
-	args->taskfile.high_cylinder = (cyl>>8);
-
-	args->taskfile.device_head = head;
-	args->taskfile.device_head |= drive->select.all;
-	args->taskfile.command = get_command(drive, rq_data_dir(rq));
+	taskfile.sector_number	= sect;
+	taskfile.low_cylinder	= cyl;
+	taskfile.high_cylinder	= (cyl>>8);
+
+	taskfile.device_head	= head;
+	taskfile.device_head	|= drive->select.all;
+	taskfile.command	=  get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
 		(rq_data_dir(rq)==READ) ? "read" : "writ");
+	if (lba)	printk("LBAsect=%lld, ", block);
+	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
 	printk("sectors=%ld, ", rq->nr_sectors);
-	printk("CHS=%d/%d/%d, ", cyl, head, sect);
 	printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
 #endif
 
-	ide_cmd_type_parser(args);
-	args->ar = ar;
-	rq->special = ar;
+	args.taskfile = taskfile;
+	args.hobfile = hobfile;
+	ide_cmd_type_parser(&args);
+	rq->special = &args;
 
-	return ata_taskfile(drive, args, rq);
+	return ata_taskfile(drive, &args, rq);
 }
 
-static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct ata_request *ar, sector_t block)
+static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
 {
-	struct ata_taskfile *args = &ar->ar_task;
-	struct request *rq = ar->ar_rq;
-	int sectors = rq->nr_sectors;
+	struct hd_drive_task_hdr	taskfile;
+	struct hd_drive_hob_hdr		hobfile;
+	struct ata_taskfile		args;
+	int				sectors;
 
+	sectors = rq->nr_sectors;
 	if (sectors == 256)
 		sectors = 0;
 
-	memset(&args->taskfile, 0, sizeof(struct hd_drive_task_hdr));
-	memset(&args->hobfile, 0, sizeof(struct hd_drive_hob_hdr));
-
-	if (ar->ar_flags & ATA_AR_QUEUED) {
-		unsigned long flags;
-
-		args->taskfile.feature = sectors;
-		args->taskfile.sector_count = ar->ar_tag << 3;
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 
-		spin_lock_irqsave(DRIVE_LOCK(drive), flags);
-		blkdev_dequeue_request(rq);
-		spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-	} else
-		args->taskfile.sector_count = sectors;
-
-	args->taskfile.sector_number = block;
-	args->taskfile.low_cylinder = (block >>= 8);
-
-	args->taskfile.high_cylinder = (block >>= 8);
-
-	args->taskfile.device_head = ((block >> 8) & 0x0f);
-	args->taskfile.device_head |= drive->select.all;
-	args->taskfile.command = get_command(drive, rq_data_dir(rq));
+	taskfile.sector_count	= sectors;
+	taskfile.sector_number	= block;
+	taskfile.low_cylinder	= (block >>= 8);
+
+	taskfile.high_cylinder	= (block >>= 8);
+
+	taskfile.device_head	= ((block >> 8) & 0x0f);
+	taskfile.device_head	|= drive->select.all;
+	taskfile.command	= get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
 		(rq_data_dir(rq)==READ) ? "read" : "writ");
-	printk("sector=%lx, sectors=%ld, ", block, rq->nr_sectors);
+	if (lba)	printk("LBAsect=%lld, ", block);
+	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
+	printk("sectors=%ld, ", rq->nr_sectors);
 	printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
 #endif
 
-	ide_cmd_type_parser(args);
-	args->ar = ar;
-	rq->special = ar;
+	args.taskfile = taskfile;
+	args.hobfile = hobfile;
+	ide_cmd_type_parser(&args);
+	rq->special = &args;
 
-	return ata_taskfile(drive, args, rq);
+	return ata_taskfile(drive, &args, rq);
 }
 
 /*
@@ -251,58 +224,57 @@
  * 320173056  == 163929 MB or 48bit addressing
  * 1073741822 == 549756 MB or 48bit addressing fake drive
  */
-static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct ata_request *ar, sector_t block)
+
+static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block)
 {
-	struct ata_taskfile *args = &ar->ar_task;
-	struct request *rq = ar->ar_rq;
-	int sectors = rq->nr_sectors;
+	struct hd_drive_task_hdr	taskfile;
+	struct hd_drive_hob_hdr		hobfile;
+	struct ata_taskfile		args;
+	int				sectors;
 
-	memset(&args->taskfile, 0, sizeof(struct hd_drive_task_hdr));
-	memset(&args->hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
+	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 
+	sectors = rq->nr_sectors;
 	if (sectors == 65536)
 		sectors = 0;
 
-	if (ar->ar_flags & ATA_AR_QUEUED) {
-		unsigned long flags;
-
-		args->taskfile.feature = sectors;
-		args->hobfile.feature = sectors >> 8;
-		args->taskfile.sector_count = ar->ar_tag << 3;
-
-		spin_lock_irqsave(DRIVE_LOCK(drive), flags);
-		blkdev_dequeue_request(rq);
-		spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-	} else {
-		args->taskfile.sector_count = sectors;
-		args->hobfile.sector_count = sectors >> 8;
-	}
+	taskfile.sector_count	= sectors;
+	hobfile.sector_count	= sectors >> 8;
 
-	args->taskfile.sector_number = block;
-	args->taskfile.low_cylinder = (block >>= 8);
-	args->taskfile.high_cylinder = (block >>= 8);
-
-	args->hobfile.sector_number = (block >>= 8);
-	args->hobfile.low_cylinder = (block >>= 8);
-	args->hobfile.high_cylinder = (block >>= 8);
-
-	args->taskfile.device_head = drive->select.all;
-	args->hobfile.device_head = args->taskfile.device_head;
-	args->hobfile.control = (drive->ctl|0x80);
-	args->taskfile.command = get_command(drive, rq_data_dir(rq));
+	if (rq->nr_sectors == 65536) {
+		taskfile.sector_count	= 0x00;
+		hobfile.sector_count	= 0x00;
+	}
+
+	taskfile.sector_number	= block;		/* low lba */
+	taskfile.low_cylinder	= (block >>= 8);	/* mid lba */
+	taskfile.high_cylinder	= (block >>= 8);	/* hi  lba */
+
+	hobfile.sector_number	= (block >>= 8);	/* low lba */
+	hobfile.low_cylinder	= (block >>= 8);	/* mid lba */
+	hobfile.high_cylinder	= (block >>= 8);	/* hi  lba */
+
+	taskfile.device_head	= drive->select.all;
+	hobfile.device_head	= taskfile.device_head;
+	hobfile.control		= (drive->ctl|0x80);
+	taskfile.command	= get_command(drive, rq_data_dir(rq));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
 		(rq_data_dir(rq)==READ) ? "read" : "writ");
-	printk("sector=%lx, sectors=%ld, ", block, rq->nr_sectors);
+	if (lba)	printk("LBAsect=%lld, ", block);
+	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
+	printk("sectors=%ld, ", rq->nr_sectors);
 	printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
 #endif
 
-	ide_cmd_type_parser(args);
-	args->ar = ar;
-	rq->special = ar;
+	args.taskfile = taskfile;
+	args.hobfile = hobfile;
+	ide_cmd_type_parser(&args);
+	rq->special = &args;
 
-	return ata_taskfile(drive, args, rq);
+	return ata_taskfile(drive, &args, rq);
 }
 
 /*
@@ -310,11 +282,8 @@
  * otherwise, to address sectors.  It also takes care of issuing special
  * DRIVE_CMDs.
  */
-static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, sector_t block)
+static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
 {
-	unsigned long flags;
-	struct ata_request *ar;
-
 	/*
 	 * Wait until all request have bin finished.
 	 */
@@ -336,49 +305,16 @@
 		return promise_rw_disk(drive, rq, block);
 	}
 
-	/*
-	 * get a new command (push ar further down to avoid grabbing lock here
-	 */
-	spin_lock_irqsave(DRIVE_LOCK(drive), flags);
-
-	ar = ata_ar_get(drive);
-
-	/*
-	 * we've reached maximum queue depth, bail
-	 */
-	if (!ar) {
-		spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-		return ide_started;
-	}
-
-	ar->ar_rq = rq;
-
-	if (drive->using_tcq) {
-		int tag = ide_get_tag(drive);
-
-		BUG_ON(drive->tcq->active_tag != -1);
-
-		/* Set the tag: */
-		ar->ar_flags |= ATA_AR_QUEUED;
-		ar->ar_tag = tag;
-		drive->tcq->ar[tag] = ar;
-		drive->tcq->active_tag = tag;
-		ar->ar_time = jiffies;
-		drive->tcq->queued++;
-	}
-
-	spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-
 	/* 48-bit LBA */
 	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
-		return lba48_do_request(drive, ar, block);
+		return lba48_do_request(drive, rq, block);
 
 	/* 28-bit LBA */
 	if (drive->select.b.lba)
-		return lba28_do_request(drive, ar, block);
+		return lba28_do_request(drive, rq, block);
 
 	/* 28-bit CHS */
-	return chs_do_request(drive, ar, block);
+	return chs_do_request(drive, rq, block);
 }
 
 static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
@@ -861,71 +797,11 @@
 	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-static int proc_idedisk_read_tcq
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
-	ide_drive_t	*drive = (ide_drive_t *) data;
-	char		*out = page;
-	int		len, cmds, i;
-	unsigned long tag_mask = 0, flags, cur_jif = jiffies, max_jif;
-
-	if (!drive->tcq) {
-		len = sprintf(out, "not configured\n");
-		PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
-	}
-
-	spin_lock_irqsave(&ide_lock, flags);
-
-	len = sprintf(out, "TCQ currently on:\t%s\n", drive->using_tcq ? "yes" : "no");
-	len += sprintf(out+len, "Max queue depth:\t%d\n",drive->queue_depth);
-	len += sprintf(out+len, "Max achieved depth:\t%d\n",drive->tcq->max_depth);
-	len += sprintf(out+len, "Max depth since last:\t%d\n",drive->tcq->max_last_depth);
-	len += sprintf(out+len, "Current depth:\t\t%d\n", drive->tcq->queued);
-	max_jif = 0;
-	len += sprintf(out+len, "Active tags:\t\t[ ");
-	for (i = 0, cmds = 0; i < drive->queue_depth; i++) {
-		struct ata_request *ar = IDE_GET_AR(drive, i);
-
-		if (!ar)
-			continue;
-
-		__set_bit(i, &tag_mask);
-		len += sprintf(out+len, "%d, ", i);
-		if (cur_jif - ar->ar_time > max_jif)
-			max_jif = cur_jif - ar->ar_time;
-		cmds++;
-	}
-	len += sprintf(out+len, "]\n");
-
-	len += sprintf(out+len, "Queue:\t\t\treleased [ %d ] - started [ %d ]\n", drive->tcq->immed_rel, drive->tcq->immed_comp);
-
-	if (drive->tcq->queued != cmds)
-		len += sprintf(out+len, "pending request and queue count mismatch (counted: %d)\n", cmds);
-
-	if (tag_mask != drive->tcq->tag_mask)
-		len += sprintf(out+len, "tag masks differ (counted %lx != %lx\n", tag_mask, drive->tcq->tag_mask);
-
-	len += sprintf(out+len, "DMA status:\t\t%srunning\n", test_bit(IDE_DMA, &HWGROUP(drive)->flags) ? "" : "not ");
-
-	len += sprintf(out+len, "Oldest command:\t\t%lu jiffies\n", max_jif);
-	len += sprintf(out+len, "Oldest command ever:\t%lu\n", drive->tcq->oldest_command);
-
-	drive->tcq->max_last_depth = 0;
-
-	spin_unlock_irqrestore(&ide_lock, flags);
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
-}
-#endif
-
 static ide_proc_entry_t idedisk_proc[] = {
 	{ "cache",		S_IFREG|S_IRUGO,	proc_idedisk_read_cache,		NULL },
 	{ "geometry",		S_IFREG|S_IRUGO,	proc_ide_read_geometry,			NULL },
 	{ "smart_values",	S_IFREG|S_IRUSR,	proc_idedisk_read_smart_values,		NULL },
 	{ "smart_thresholds",	S_IFREG|S_IRUSR,	proc_idedisk_read_smart_thresholds,	NULL },
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-	{ "tcq",		S_IFREG|S_IRUSR,	proc_idedisk_read_tcq,	NULL },
-#endif
 	{ NULL, 0, NULL, NULL }
 };
 
@@ -1007,24 +883,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-static int set_using_tcq(ide_drive_t *drive, int arg)
-{
-	if (!drive->driver)
-		return -EPERM;
-	if (!drive->channel->dmaproc)
-		return -EPERM;
-	if (arg == drive->queue_depth && drive->using_tcq)
-		return 0;
-
-	drive->queue_depth = arg ? arg : 1;
-	if (drive->channel->dmaproc(arg ? ide_dma_queued_on : ide_dma_queued_off, drive))
-		return -EIO;
-
-	return 0;
-}
-#endif
-
 static int probe_lba_addressing (ide_drive_t *drive, int arg)
 {
 	drive->addressing =  0;
@@ -1056,9 +914,6 @@
 	ide_add_setting(drive,	"acoustic",		SETTING_RW,					HDIO_GET_ACOUSTIC,	HDIO_SET_ACOUSTIC,	TYPE_BYTE,	0,	254,				1,	1,	&drive->acoustic,		set_acoustic);
 	ide_add_setting(drive,	"failures",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	65535,				1,	1,	&drive->failures,		NULL);
 	ide_add_setting(drive,	"max_failures",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	65535,				1,	1,	&drive->max_failures,		NULL);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-	ide_add_setting(drive,	"using_tcq",		SETTING_RW,					HDIO_GET_QDMA,		HDIO_SET_QDMA,		TYPE_BYTE,	0,	IDE_MAX_TAG,			1,		1,		&drive->using_tcq,		set_using_tcq);
-#endif
 }
 
 static int idedisk_suspend(struct device *dev, u32 state, u32 level)
diff -urN linux-2.5.10/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.10/drivers/ide/ide-dma.c	2002-04-23 00:28:11.000000000 +0200
+++ linux/drivers/ide/ide-dma.c	2002-04-25 16:42:48.000000000 +0200
@@ -209,36 +209,29 @@
 			__ide_end_request(drive, 1, rq->nr_sectors);
 			return ide_stopped;
 		}
-		printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
+		printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n", 
 		       drive->name, dma_stat);
 	}
 	return ide_error(drive, "dma_intr", stat);
 }
 
-int ide_build_sglist(struct ata_channel *hwif, struct request *rq)
+static int ide_build_sglist(struct ata_channel *hwif, struct request *rq)
 {
 	request_queue_t *q = &hwif->drives[DEVICE_NR(rq->rq_dev) & 1].queue;
-	struct ata_request *ar = rq->special;
+	struct scatterlist *sg = hwif->sg_table;
+	int nents;
 
-	if (!(ar->ar_flags & ATA_AR_SETUP)) {
-		ar->ar_flags |= ATA_AR_SETUP;
-		ar->ar_sg_nents = blk_rq_map_sg(q, rq, ar->ar_sg_table);
-	}
+	nents = blk_rq_map_sg(q, rq, hwif->sg_table);
 
-	if (rq->q && ar->ar_sg_nents > rq->nr_phys_segments) {
-		printk("%s: received %d phys segments, build %d\n", __FILE__, rq->nr_phys_segments, ar->ar_sg_nents);
-		return 0;
-	} else if (!ar->ar_sg_nents) {
-		printk("%s: zero segments in request\n", __FILE__);
-		return 0;
-	}
+	if (rq->q && nents > rq->nr_phys_segments)
+		printk("ide-dma: received %d phys segments, build %d\n", rq->nr_phys_segments, nents);
 
 	if (rq_data_dir(rq) == READ)
-		ar->ar_sg_ddir = PCI_DMA_FROMDEVICE;
+		hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
 	else
-		ar->ar_sg_ddir = PCI_DMA_TODEVICE;
+		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
 
-	return pci_map_sg(hwif->pci_dev, ar->ar_sg_table, ar->ar_sg_nents, ar->ar_sg_ddir);
+	return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
 }
 
 /*
@@ -247,17 +240,23 @@
  */
 static int raw_build_sglist(struct ata_channel *ch, struct request *rq)
 {
-	struct ata_request *ar = rq->special;
-	struct scatterlist *sg = ar->ar_sg_table;
-	struct ata_taskfile *args = &ar->ar_task;
+	struct scatterlist *sg = ch->sg_table;
+	int nents = 0;
+	struct ata_taskfile *args = rq->special;
+#if 1
 	unsigned char *virt_addr = rq->buffer;
 	int sector_count = rq->nr_sectors;
-	int nents = 0;
+#else
+        nents = blk_rq_map_sg(rq->q, rq, ch->sg_table);
+
+	if (nents > rq->nr_segments)
+		printk("ide-dma: received %d segments, build %d\n", rq->nr_segments, nents);
+#endif
 
 	if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
-		ar->ar_sg_ddir = PCI_DMA_TODEVICE;
+		ch->sg_dma_direction = PCI_DMA_TODEVICE;
 	else
-		ar->ar_sg_ddir = PCI_DMA_FROMDEVICE;
+		ch->sg_dma_direction = PCI_DMA_FROMDEVICE;
 
 	if (sector_count > 128) {
 		memset(&sg[nents], 0, sizeof(*sg));
@@ -275,18 +274,18 @@
 	sg[nents].length =  sector_count  * SECTOR_SIZE;
 	nents++;
 
-	return pci_map_sg(ch->pci_dev, sg, nents, ar->ar_sg_ddir);
+	return pci_map_sg(ch->pci_dev, sg, nents, ch->sg_dma_direction);
 }
 
 /*
- * Prepare a dma request.
+ * ide_build_dmatable() prepares a dma request.
  * Returns 0 if all went okay, returns 1 otherwise.
- * This may also be invoked from trm290.c
+ * May also be invoked from trm290.c
  */
-int ide_build_dmatable(ide_drive_t *drive, struct request *rq,
-		       ide_dma_action_t func)
+int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
 {
 	struct ata_channel *hwif = drive->channel;
+	unsigned int *table = hwif->dmatable_cpu;
 #ifdef CONFIG_BLK_DEV_TRM290
 	unsigned int is_trm290_chipset = (hwif->chipset == ide_trm290);
 #else
@@ -295,19 +294,16 @@
 	unsigned int count = 0;
 	int i;
 	struct scatterlist *sg;
-	struct ata_request *ar = rq->special;
-	unsigned int *table = ar->ar_dmatable_cpu;
-
-	if (rq->flags & REQ_DRIVE_TASKFILE)
-		ar->ar_sg_nents = raw_build_sglist(hwif, rq);
-	else
-		ar->ar_sg_nents = ide_build_sglist(hwif, rq);
 
-	if (!ar->ar_sg_nents)
+	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
+		hwif->sg_nents = i = raw_build_sglist(hwif, HWGROUP(drive)->rq);
+	} else {
+		hwif->sg_nents = i = ide_build_sglist(hwif, HWGROUP(drive)->rq);
+	}
+	if (!i)
 		return 0;
 
-	sg = ar->ar_sg_table;
-	i = ar->ar_sg_nents;
+	sg = hwif->sg_table;
 	while (i) {
 		u32 cur_addr;
 		u32 cur_len;
@@ -326,7 +322,7 @@
 
 			if (count++ >= PRD_ENTRIES) {
 				printk("ide-dma: req %p\n", HWGROUP(drive)->rq);
-				printk("count %d, sg_nents %d, cur_len %d, cur_addr %u\n", count, ar->ar_sg_nents, cur_len, cur_addr);
+				printk("count %d, sg_nents %d, cur_len %d, cur_addr %u\n", count, hwif->sg_nents, cur_len, cur_addr);
 				BUG();
 			}
 
@@ -337,7 +333,7 @@
 			if (is_trm290_chipset)
 				xcount = ((xcount >> 2) - 1) << 16;
 			if (xcount == 0x0000) {
-		        /*
+		        /* 
 			 * Most chipsets correctly interpret a length of
 			 * 0x0000 as 64KB, but at least one (e.g. CS5530)
 			 * misinterprets it as zero (!). So here we break
@@ -345,8 +341,8 @@
 			 */
 				if (count++ >= PRD_ENTRIES) {
 					pci_unmap_sg(hwif->pci_dev, sg,
-						     ar->ar_sg_nents,
-						     ar->ar_sg_ddir);
+						     hwif->sg_nents,
+						     hwif->sg_dma_direction);
 					return 0;
 				}
 
@@ -372,12 +368,13 @@
 }
 
 /* Teardown mappings after DMA has completed.  */
-void ide_destroy_dmatable(struct ata_device *d)
+void ide_destroy_dmatable (ide_drive_t *drive)
 {
-	struct pci_dev *dev = d->channel->pci_dev;
-	struct ata_request *ar = IDE_CUR_AR(d);
+	struct pci_dev *dev = drive->channel->pci_dev;
+	struct scatterlist *sg = drive->channel->sg_table;
+	int nents = drive->channel->sg_nents;
 
-	pci_unmap_sg(dev, ar->ar_sg_table, ar->ar_sg_nents, ar->ar_sg_ddir);
+	pci_unmap_sg(dev, sg, nents, drive->channel->sg_dma_direction);
 }
 
 /*
@@ -435,7 +432,7 @@
 			printk(", UDMA(133)");	/* UDMA BIOS-enabled! */
 		}
 	} else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
-		  (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
+	  	  (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
 		if ((id->dma_ultra >> 13) & 1) {
 			printk(", UDMA(100)");	/* UDMA BIOS-enabled! */
 		} else if ((id->dma_ultra >> 12) & 1) {
@@ -538,41 +535,6 @@
 }
 
 /*
- * Start DMA engine.
- */
-int ide_start_dma(struct ata_channel *hwif, ide_drive_t *drive, ide_dma_action_t func)
-{
-	unsigned int reading = 0, count;
-	unsigned long dma_base = hwif->dma_base;
-	struct ata_request *ar = IDE_CUR_AR(drive);
-
-	/* This can happen with drivers abusing the special request field.
-	 */
-
-	if (!ar) {
-		printk(KERN_ERR "DMA without ATA request\n");
-
-		return 1;
-	}
-
-	if (rq_data_dir(ar->ar_rq) == READ)
-		reading = 1 << 3;
-
-	if (hwif->rwproc)
-		hwif->rwproc(drive, func);
-
-	if (!(count = ide_build_dmatable(drive, ar->ar_rq, func)))
-		return 1;	/* try PIO instead of DMA */
-
-	ar->ar_flags |= ATA_AR_SETUP;
-	outl(ar->ar_dmatable, dma_base + 4);	/* PRD table */
-	outb(reading, dma_base);		/* specify r/w */
-	outb(inb(dma_base + 2) | 6, dma_base+2);/* clear INTR & ERROR flags */
-	drive->waiting_for_dma = 1;
-	return 0;
-}
-
-/*
  * ide_dmaproc() initiates/aborts DMA read/write operations on a drive.
  *
  * The caller is assumed to have selected the drive and programmed the drive's
@@ -592,10 +554,9 @@
 {
 	struct ata_channel *hwif = drive->channel;
 	unsigned long dma_base = hwif->dma_base;
-	u8 unit = (drive->select.b.unit & 0x01);
-	unsigned int reading = 0, set_high = 1;
-	struct ata_request *ar;
-	u8 dma_stat;
+	byte unit = (drive->select.b.unit & 0x01);
+	unsigned int count, reading = 0, set_high = 1;
+	byte dma_stat;
 
 	switch (func) {
 		case ide_dma_off:
@@ -603,68 +564,54 @@
 		case ide_dma_off_quietly:
 			set_high = 0;
 			outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-			hwif->dmaproc(ide_dma_queued_off, drive);
-#endif
 		case ide_dma_on:
 			ide_toggle_bounce(drive, set_high);
 			drive->using_dma = (func == ide_dma_on);
-			if (drive->using_dma) {
+			if (drive->using_dma)
 				outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-				hwif->dmaproc(ide_dma_queued_on, drive);
-#endif
-			}
 			return 0;
 		case ide_dma_check:
 			return config_drive_for_dma (drive);
-		case ide_dma_begin:
-			if (test_and_set_bit(IDE_DMA, &HWGROUP(drive)->flags))
-				BUG();
-			/* Note that this is done *after* the cmd has
-			 * been issued to the drive, as per the BM-IDE spec.
-			 * The Promise Ultra33 doesn't work correctly when
-			 * we do this part before issuing the drive cmd.
-			 */
-			outb(inb(dma_base)|1, dma_base);		/* start DMA */
-			return 0;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-		case ide_dma_queued_on:
-		case ide_dma_queued_off:
-		case ide_dma_read_queued:
-		case ide_dma_write_queued:
-		case ide_dma_queued_start:
-			return ide_tcq_dmaproc(func, drive);
-#endif
-
 		case ide_dma_read:
 			reading = 1 << 3;
 		case ide_dma_write:
-			ar = IDE_CUR_AR(drive);
-
-			if (ide_start_dma(hwif, drive, func))
-				return 1;
-
+			/* active tuning based on IO direction */
+			if (hwif->rwproc)
+				hwif->rwproc(drive, func);
+
+			if (!(count = ide_build_dmatable(drive, func)))
+				return 1;	/* try PIO instead of DMA */
+			outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
+			outb(reading, dma_base);			/* specify r/w */
+			outb(inb(dma_base+2)|6, dma_base+2);		/* clear INTR & ERROR flags */
+			drive->waiting_for_dma = 1;
 			if (drive->type != ATA_DISK)
 				return 0;
+
 			BUG_ON(HWGROUP(drive)->handler);
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry);	/* issue cmd to drive */
-			if ((ar->ar_rq->flags & REQ_DRIVE_TASKFILE) &&
+			if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
 			    (drive->addressing == 1)) {
-				struct ata_taskfile *args = &ar->ar_task;
+				struct ata_taskfile *args = HWGROUP(drive)->rq->special;
 				OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
 			} else if (drive->addressing) {
 				OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
 			} else {
 				OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 			}
-			return hwif->dmaproc(ide_dma_begin, drive);
+			return drive->channel->dmaproc(ide_dma_begin, drive);
+		case ide_dma_begin:
+			/* Note that this is done *after* the cmd has
+			 * been issued to the drive, as per the BM-IDE spec.
+			 * The Promise Ultra33 doesn't work correctly when
+			 * we do this part before issuing the drive cmd.
+			 */
+			outb(inb(dma_base)|1, dma_base);		/* start DMA */
+			return 0;
 		case ide_dma_end: /* returns 1 on error, 0 otherwise */
-			if (!test_and_clear_bit(IDE_DMA, &HWGROUP(drive)->flags))
-				BUG();
 			drive->waiting_for_dma = 0;
 			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
-			dma_stat = inb(dma_base+2);	/* get DMA status */
+			dma_stat = inb(dma_base+2);		/* get DMA status */
 			outb(dma_stat|6, dma_base+2);	/* clear the INTR & ERROR bits */
 			ide_destroy_dmatable(drive);	/* purge DMA mappings */
 			return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
@@ -687,7 +634,7 @@
 			return 1;
 		case ide_dma_retune:
 		case ide_dma_lostirq:
-			printk(KERN_ERR "%s: chipset supported func only: %d\n", __FUNCTION__, func);
+			printk(KERN_ERR "%s: chipset supported func only: %d\n", __FUNCTION__,  func);
 			return 1;
 		default:
 			printk(KERN_ERR "%s: unsupported func: %d\n", __FUNCTION__, func);
@@ -703,6 +650,17 @@
 	if (!hwif->dma_base)
 		return;
 
+	if (hwif->dmatable_cpu) {
+		pci_free_consistent(hwif->pci_dev,
+				    PRD_ENTRIES * PRD_BYTES,
+				    hwif->dmatable_cpu,
+				    hwif->dmatable_dma);
+		hwif->dmatable_cpu = NULL;
+	}
+	if (hwif->sg_table) {
+		kfree(hwif->sg_table);
+		hwif->sg_table = NULL;
+	}
 	if ((hwif->dma_extra) && (hwif->unit == 0))
 		release_region((hwif->dma_base + 16), hwif->dma_extra);
 	release_region(hwif->dma_base, 8);
@@ -721,6 +679,20 @@
 	}
 	request_region(dma_base, num_ports, hwif->name);
 	hwif->dma_base = dma_base;
+	hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
+						  PRD_ENTRIES * PRD_BYTES,
+						  &hwif->dmatable_dma);
+	if (hwif->dmatable_cpu == NULL)
+		goto dma_alloc_failure;
+
+	hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
+				 GFP_KERNEL);
+	if (hwif->sg_table == NULL) {
+		pci_free_consistent(hwif->pci_dev, PRD_ENTRIES * PRD_BYTES,
+				    hwif->dmatable_cpu, hwif->dmatable_dma);
+		goto dma_alloc_failure;
+	}
+
 	hwif->dmaproc = &ide_dmaproc;
 
 	if (hwif->chipset != ide_trm290) {
@@ -731,4 +703,7 @@
 	}
 	printk("\n");
 	return;
+
+dma_alloc_failure:
+	printk(" -- ERROR, UNABLE TO ALLOCATE DMA TABLES\n");
 }
diff -urN linux-2.5.10/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.10/drivers/ide/ide-probe.c	2002-04-23 00:27:40.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-04-25 16:25:18.000000000 +0200
@@ -168,9 +168,6 @@
 		}
 		printk (" drive\n");
 		drive->type = type;
-
-		goto init_queue;
-
 		return;
 	}
 
@@ -201,22 +198,6 @@
 	if (drive->channel->quirkproc)
 		drive->quirk_list = drive->channel->quirkproc(drive);
 
-init_queue:
-	/*
-	 * it's an ata drive, build command list
-	 */
-	drive->queue_depth = 1;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEPTH
-	drive->queue_depth = CONFIG_BLK_DEV_IDE_TCQ_DEPTH;
-#else
-	drive->queue_depth = drive->id->queue_depth + 1;
-#endif
-	if (drive->queue_depth < 1 || drive->queue_depth > IDE_MAX_TAG)
-		drive->queue_depth = IDE_MAX_TAG;
-
-	if (ide_init_commandlist(drive))
-		goto err_misc;
-
 	return;
 
 err_misc:
diff -urN linux-2.5.10/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.10/drivers/ide/ide-taskfile.c	2002-04-23 00:29:15.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-04-25 16:25:18.000000000 +0200
@@ -308,8 +308,7 @@
 
 static ide_startstop_t pre_task_mulout_intr(ide_drive_t *drive, struct request *rq)
 {
-	struct ata_request *ar = rq->special;
-	struct ata_taskfile *args = &ar->ar_task;
+	struct ata_taskfile *args = rq->special;
 	ide_startstop_t startstop;
 
 	/*
@@ -464,35 +463,11 @@
 		if (args->prehandler != NULL)
 			return args->prehandler(drive, rq);
 	} else {
-		ide_dma_action_t dmaaction;
-		u8 command;
-
-		if (!drive->using_dma)
-			return ide_started;
-
-		command = args->taskfile.command;
-
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-		if (drive->using_tcq) {
-			if (command == WIN_READDMA_QUEUED
-			    || command == WIN_READDMA_QUEUED_EXT
-			    || command == WIN_WRITEDMA_QUEUED
-			    || command == WIN_READDMA_QUEUED_EXT)
-				return ide_start_tag(ide_dma_queued_start, drive, rq->special);
-		}
-#endif
-
-		if (command == WIN_WRITEDMA || command == WIN_WRITEDMA_EXT)
-			dmaaction = ide_dma_write;
-		else if (command == WIN_READDMA || command == WIN_READDMA_EXT)
-			dmaaction = ide_dma_read;
-		else
-			return ide_stopped;
-
-		if (!drive->channel->dmaproc(dmaaction, drive))
-			return ide_started;
-
-		return ide_stopped;
+		/* for dma commands we down set the handler */
+		if (drive->using_dma &&
+		!(drive->channel->dmaproc(((args->taskfile.command == WIN_WRITEDMA)
+					|| (args->taskfile.command == WIN_WRITEDMA_EXT))
+					? ide_dma_write : ide_dma_read, drive)));
 	}
 
 	return ide_started;
@@ -545,30 +520,12 @@
 }
 
 /*
- * Quiet handler for commands without a data phase -- handy instead of
- * task_no_data_intr() for commands we _know_ will fail (such as WIN_NOP)
- */
-ide_startstop_t task_no_data_quiet_intr(ide_drive_t *drive)
-{
-	struct ata_request *ar = IDE_CUR_AR(drive);
-	struct ata_taskfile *args = &ar->ar_task;
-
-	ide__sti();	/* local CPU only */
-
-	if (args)
-		ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
-
-	return ide_stopped;
-}
-
-/*
  * Handler for commands without a data phase
  */
 ide_startstop_t task_no_data_intr (ide_drive_t *drive)
 {
-	struct ata_request *ar = IDE_CUR_AR(drive);
-	struct ata_taskfile *args = &ar->ar_task;
-	u8 stat = GET_STAT();
+	struct ata_taskfile *args = HWGROUP(drive)->rq->special;
+	byte stat		= GET_STAT();
 
 	ide__sti();	/* local CPU only */
 
@@ -628,8 +585,7 @@
 
 static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
 {
-	struct ata_request *ar = rq->special;
-	struct ata_taskfile *args = &ar->ar_task;
+	struct ata_taskfile *args = rq->special;
 	ide_startstop_t startstop;
 
 	if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
@@ -909,7 +865,6 @@
 			return;
 
 		case WIN_NOP:
-			args->handler = task_no_data_quiet_intr;
 			args->command_type = IDE_DRIVE_TASK_NO_DATA;
 			return;
 
@@ -927,7 +882,7 @@
 /*
  * This function is intended to be used prior to invoking ide_do_drive_cmd().
  */
-void init_taskfile_request(struct request *rq)
+static void init_taskfile_request(struct request *rq)
 {
 	memset(rq, 0, sizeof(*rq));
 	rq->flags = REQ_DRIVE_TASKFILE;
@@ -936,29 +891,18 @@
 int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
 {
 	struct request rq;
-	struct ata_request star;
-	int ret;
-
-	ata_ar_init(drive, &star);
 	init_taskfile_request(&rq);
-	rq.buffer = buf;
 
-	memcpy(&star.ar_task, args, sizeof(*args));
+	rq.buffer = buf;
 
 	if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
 		rq.current_nr_sectors = rq.nr_sectors
 			= (args->hobfile.sector_count << 8)
 			| args->taskfile.sector_count;
 
-	rq.special = &star;
+	rq.special = args;
 
-	ret = ide_do_drive_cmd(drive, &rq, ide_wait);
-
-	/*
-	 * copy back status etc
-	 */
-	memcpy(args, &star.ar_task, sizeof(*args));
-	return ret;
+	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
 /*
diff -urN linux-2.5.10/drivers/ide/ide-tcq.c linux/drivers/ide/ide-tcq.c
--- linux-2.5.10/drivers/ide/ide-tcq.c	2002-04-23 00:29:44.000000000 +0200
+++ linux/drivers/ide/ide-tcq.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,689 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 Jens Axboe <axboe@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/*
- * Support for the DMA queued protocol, which enables ATA disk drives to
- * use tagged command queueing.
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ide.h>
-
-#include <asm/delay.h>
-
-/*
- * warning: it will be _very_ verbose if defined
- */
-#undef IDE_TCQ_DEBUG
-
-#ifdef IDE_TCQ_DEBUG
-#define TCQ_PRINTK printk
-#else
-#define TCQ_PRINTK(x...)
-#endif
-
-/*
- * use nIEN or not
- */
-#undef IDE_TCQ_NIEN
-
-/*
- * we are leaving the SERVICE interrupt alone, IBM drives have it
- * on per default and it can't be turned off. Doesn't matter, this
- * is the sane config.
- */
-#undef IDE_TCQ_FIDDLE_SI
-
-ide_startstop_t ide_dmaq_intr(ide_drive_t *drive);
-ide_startstop_t ide_service(ide_drive_t *drive);
-
-static inline void drive_ctl_nien(ide_drive_t *drive, int set)
-{
-#ifdef IDE_TCQ_NIEN
-	if (IDE_CONTROL_REG) {
-		int mask = set ? 0x02 : 0x00;
-
-		OUT_BYTE(drive->ctl | mask, IDE_CONTROL_REG);
-	}
-#endif
-}
-
-/*
- * if we encounter _any_ error doing I/O to one of the tags, we must
- * invalidate the pending queue. clear the software busy queue and requeue
- * on the request queue for restart. issue a WIN_NOP to clear hardware queue
- */
-static void ide_tcq_invalidate_queue(ide_drive_t *drive)
-{
-	request_queue_t *q = &drive->queue;
-	unsigned long flags;
-	struct ata_request *ar;
-	int i;
-
-	printk("%s: invalidating pending queue (%d)\n", drive->name, drive->tcq->queued);
-
-	spin_lock_irqsave(&ide_lock, flags);
-
-	del_timer(&HWGROUP(drive)->timer);
-
-	if (test_bit(IDE_DMA, &HWGROUP(drive)->flags))
-		drive->channel->dmaproc(ide_dma_end, drive);
-
-	/*
-	 * assume oldest commands have the higher tags... doesn't matter
-	 * much. shove requests back into request queue.
-	 */
-	for (i = drive->queue_depth - 1; i; i--) {
-		ar = drive->tcq->ar[i];
-		if (!ar)
-			continue;
-
-		ar->ar_rq->special = NULL;
-		ar->ar_rq->flags &= ~REQ_STARTED;
-		_elv_add_request(q, ar->ar_rq, 0, 0);
-		ata_ar_put(drive, ar);
-	}
-
-	drive->tcq->queued = 0;
-	drive->using_tcq = 0;
-	drive->queue_depth = 1;
-	clear_bit(IDE_BUSY, &HWGROUP(drive)->flags);
-	clear_bit(IDE_DMA, &HWGROUP(drive)->flags);
-	HWGROUP(drive)->handler = NULL;
-
-	/*
-	 * do some internal stuff -- we really need this command to be
-	 * executed before any new commands are started. issue a NOP
-	 * to clear internal queue on drive
-	 */
-	ar = ata_ar_get(drive);
-
-	memset(&ar->ar_task, 0, sizeof(ar->ar_task));
-	AR_TASK_CMD(ar) = WIN_NOP;
-	ide_cmd_type_parser(&ar->ar_task);
-	ar->ar_rq = &HWGROUP(drive)->wrq;
-	init_taskfile_request(ar->ar_rq);
-	ar->ar_rq->rq_dev = mk_kdev(drive->channel->major, (drive->select.b.unit)<<PARTN_BITS);
-	ar->ar_rq->special = ar;
-	_elv_add_request(q, ar->ar_rq, 0, 0);
-
-	/*
-	 * make sure that nIEN is cleared
-	 */
-	drive_ctl_nien(drive, 0);
-
-	/*
-	 * start doing stuff again
-	 */
-	q->request_fn(q);
-	spin_unlock_irqrestore(&ide_lock, flags);
-	printk("ide_tcq_invalidate_queue: done\n");
-}
-
-void ide_tcq_intr_timeout(unsigned long data)
-{
-	ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
-	unsigned long flags;
-	ide_drive_t *drive;
-
-	printk("ide_tcq_intr_timeout: timeout waiting for interrupt...\n");
-
-	spin_lock_irqsave(&ide_lock, flags);
-
-	if (test_and_set_bit(IDE_BUSY, &hwgroup->flags))
-		printk("ide_tcq_intr_timeout: hwgroup not busy\n");
-	if (hwgroup->handler == NULL)
-		printk("ide_tcq_intr_timeout: missing isr!\n");
-	if ((drive = hwgroup->drive) == NULL)
-		printk("ide_tcq_intr_timeout: missing drive!\n");
-
-	spin_unlock_irqrestore(&ide_lock, flags);
-
-	/*
-	 * if pending commands, try service before giving up
-	 */
-	if (ide_pending_commands(drive) && (GET_STAT() & SERVICE_STAT))
-		if (ide_service(drive) == ide_started)
-			return;
-
-	if (drive)
-		ide_tcq_invalidate_queue(drive);
-}
-
-void ide_tcq_set_intr(ide_hwgroup_t *hwgroup, ide_handler_t *handler)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&ide_lock, flags);
-
-	/*
-	 * always just bump the timer for now, the timeout handling will
-	 * have to be changed to be per-command
-	 */
-	hwgroup->timer.function = ide_tcq_intr_timeout;
-	hwgroup->timer.data = (unsigned long) hwgroup;
-	mod_timer(&hwgroup->timer, jiffies + 5 * HZ);
-
-	hwgroup->handler = handler;
-	spin_unlock_irqrestore(&ide_lock, flags);
-}
-
-/*
- * wait 400ns, then poll for busy_mask to clear from alt status
- */
-#define IDE_TCQ_WAIT	(10000)
-int ide_tcq_wait_altstat(ide_drive_t *drive, byte *stat, byte busy_mask)
-{
-	int i = 0;
-
-	udelay(1);
-
-	while ((*stat = GET_ALTSTAT()) & busy_mask) {
-		udelay(10);
-
-		if (unlikely(i++ > IDE_TCQ_WAIT))
-			return 1;
-	}
-
-	return 0;
-}
-
-/*
- * issue SERVICE command to drive -- drive must have been selected first,
- * and it must have reported a need for service (status has SERVICE_STAT set)
- *
- * Also, nIEN must be set as not to need protection against ide_dmaq_intr
- */
-ide_startstop_t ide_service(ide_drive_t *drive)
-{
-	struct ata_request *ar;
-	byte feat, stat;
-	int tag, ret;
-
-	TCQ_PRINTK("%s: started service\n", drive->name);
-
-	/*
-	 * could be called with IDE_DMA in-progress from invalidate
-	 * handler, refuse to do anything
-	 */
-	if (test_bit(IDE_DMA, &HWGROUP(drive)->flags))
-		return ide_stopped;
-
-	/*
-	 * need to select the right drive first...
-	 */
-	if (drive != HWGROUP(drive)->drive) {
-		SELECT_DRIVE(drive->channel, drive);
-		udelay(10);
-	}
-
-	drive_ctl_nien(drive, 1);
-
-	/*
-	 * send SERVICE, wait 400ns, wait for BUSY_STAT to clear
-	 */
-	OUT_BYTE(WIN_QUEUED_SERVICE, IDE_COMMAND_REG);
-
-	if (ide_tcq_wait_altstat(drive, &stat, BUSY_STAT)) {
-		printk("ide_service: BUSY clear took too long\n");
-		ide_dump_status(drive, "ide_service", stat);
-		ide_tcq_invalidate_queue(drive);
-		return ide_stopped;
-	}
-
-	drive_ctl_nien(drive, 0);
-
-	/*
-	 * FIXME, invalidate queue
-	 */
-	if (stat & ERR_STAT) {
-		ide_dump_status(drive, "ide_service", stat);
-		ide_tcq_invalidate_queue(drive);
-		return ide_stopped;
-	}
-
-	/*
-	 * should not happen, a buggy device could introduce loop
-	 */
-	if ((feat = GET_FEAT()) & NSEC_REL) {
-		printk("%s: release in service\n", drive->name);
-		IDE_SET_CUR_TAG(drive, IDE_INACTIVE_TAG);
-		return ide_stopped;
-	}
-
-	tag = feat >> 3;
-	IDE_SET_CUR_TAG(drive, tag);
-
-	TCQ_PRINTK("ide_service: stat %x, feat %x\n", stat, feat);
-
-	if ((ar = IDE_CUR_TAG(drive)) == NULL) {
-		printk("ide_service: missing request for tag %d\n", tag);
-		return ide_stopped;
-	}
-
-	HWGROUP(drive)->rq = ar->ar_rq;
-
-	/*
-	 * we'll start a dma read or write, device will trigger
-	 * interrupt to indicate end of transfer, release is not allowed
-	 */
-	if (rq_data_dir(ar->ar_rq) == READ) {
-		TCQ_PRINTK("ide_service: starting READ %x\n", stat);
-		ret = drive->channel->dmaproc(ide_dma_read_queued, drive);
-	} else {
-		TCQ_PRINTK("ide_service: starting WRITE %x\n", stat);
-		ret = drive->channel->dmaproc(ide_dma_write_queued, drive);
-	}
-
-	/*
-	 * dmaproc set intr handler
-	 */
-	return !ret ? ide_started : ide_stopped;
-}
-
-ide_startstop_t ide_check_service(ide_drive_t *drive)
-{
-	byte stat;
-
-	TCQ_PRINTK("%s: ide_check_service\n", drive->name);
-
-	if (!ide_pending_commands(drive))
-		return ide_stopped;
-
-	if ((stat = GET_STAT()) & SERVICE_STAT)
-		return ide_service(drive);
-
-	/*
-	 * we have pending commands, wait for interrupt
-	 */
-	ide_tcq_set_intr(HWGROUP(drive), ide_dmaq_intr);
-	return ide_started;
-}
-
-ide_startstop_t ide_dmaq_complete(ide_drive_t *drive, byte stat)
-{
-	struct ata_request *ar = IDE_CUR_TAG(drive);
-	byte dma_stat;
-
-	/*
-	 * transfer was in progress, stop DMA engine
-	 */
-	dma_stat = drive->channel->dmaproc(ide_dma_end, drive);
-
-	/*
-	 * must be end of I/O, check status and complete as necessary
-	 */
-	if (unlikely(!OK_STAT(stat, READY_STAT, drive->bad_wstat | DRQ_STAT))) {
-		printk("ide_dmaq_intr: %s: error status %x\n", drive->name, stat);
-		ide_dump_status(drive, "ide_dmaq_intr", stat);
-		ide_tcq_invalidate_queue(drive);
-		return ide_stopped;
-	}
-
-	if (dma_stat)
-		printk("%s: bad DMA status (dma_stat=%x)\n", drive->name, dma_stat);
-
-	TCQ_PRINTK("ide_dmaq_intr: ending %p, tag %d\n", ar, ar->ar_tag);
-	ide_end_queued_request(drive, !dma_stat, ar->ar_rq);
-
-	/*
-	 * we completed this command, set tcq inactive and check if we
-	 * can service a new command
-	 */
-	IDE_SET_CUR_TAG(drive, IDE_INACTIVE_TAG);
-	return ide_check_service(drive);
-}
-
-/*
- * intr handler for queued dma operations. this can be entered for two
- * reasons:
- *
- * 1) device has completed dma transfer
- * 2) service request to start a command
- *
- * if the drive has an active tag, we first complete that request before
- * processing any pending SERVICE.
- */
-ide_startstop_t ide_dmaq_intr(ide_drive_t *drive)
-{
-	byte stat = GET_STAT();
-
-	TCQ_PRINTK("ide_dmaq_intr: stat=%x, tag %d\n", stat, drive->tcq->active_tag);
-
-	/*
-	 * if a command completion interrupt is pending, do that first and
-	 * check service afterwards
-	 */
-	if (drive->tcq->active_tag != IDE_INACTIVE_TAG)
-		return ide_dmaq_complete(drive, stat);
-
-	/*
-	 * service interrupt
-	 */
-	if (stat & SERVICE_STAT) {
-		TCQ_PRINTK("ide_dmaq_intr: SERV (stat=%x)\n", stat);
-		return ide_service(drive);
-	}
-
-	printk("ide_dmaq_intr: stat=%x, not expected\n", stat);
-	return ide_check_service(drive);
-}
-
-/*
- * check if the ata adapter this drive is attached to supports the
- * NOP auto-poll for multiple tcq enabled drives on one channel
- */
-static int ide_tcq_check_autopoll(ide_drive_t *drive)
-{
-	struct ata_channel *ch = HWIF(drive);
-	struct ata_taskfile args;
-	ide_drive_t *next;
-
-	/*
-	 * only need to probe if both drives on a channel support tcq
-	 */
-	next = drive->next;
-	if (next == drive || !next->using_tcq)
-		return 0;
-
-	memset(&args, 0, sizeof(args));
-
-	args.taskfile.feature = 0x01;
-	args.taskfile.command = WIN_NOP;
-	ide_cmd_type_parser(&args);
-
-	/*
-	 * do taskfile and check ABRT bit -- intelligent adapters will not
-	 * pass NOP with sub-code 0x01 to device, so the command will not
-	 * fail there
-	 */
-	ide_raw_taskfile(drive, &args, NULL);
-	if (args.taskfile.feature & ABRT_ERR)
-		return 1;
-
-	ch->auto_poll = 1;
-	printk("%s: NOP Auto-poll enabled\n", ch->name);
-	return 0;
-}
-
-/*
- * configure the drive for tcq
- */
-static int ide_tcq_configure(ide_drive_t *drive)
-{
-	int tcq_mask = 1 << 1 | 1 << 14;
-	int tcq_bits = tcq_mask | 1 << 15;
-	struct ata_taskfile args;
-
-	/*
-	 * bit 14 and 1 must be set in word 83 of the device id to indicate
-	 * support for dma queued protocol, and bit 15 must be cleared
-	 */
-	if ((drive->id->command_set_2 & tcq_bits) ^ tcq_mask)
-		return -EIO;
-
-	memset(&args, 0, sizeof(args));
-	args.taskfile.feature = SETFEATURES_EN_WCACHE;
-	args.taskfile.command = WIN_SETFEATURES;
-	ide_cmd_type_parser(&args);
-
-	if (ide_raw_taskfile(drive, &args, NULL)) {
-		printk("%s: failed to enable write cache\n", drive->name);
-		return 1;
-	}
-
-	/*
-	 * disable RELease interrupt, it's quicker to poll this after
-	 * having sent the command opcode
-	 */
-	memset(&args, 0, sizeof(args));
-	args.taskfile.feature = SETFEATURES_DIS_RI;
-	args.taskfile.command = WIN_SETFEATURES;
-	ide_cmd_type_parser(&args);
-
-	if (ide_raw_taskfile(drive, &args, NULL)) {
-		printk("%s: disabling release interrupt fail\n", drive->name);
-		return 1;
-	}
-
-#ifdef IDE_TCQ_FIDDLE_SI
-	/*
-	 * enable SERVICE interrupt
-	 */
-	memset(&args, 0, sizeof(args));
-	args.taskfile.feature = SETFEATURES_EN_SI;
-	args.taskfile.command = WIN_SETFEATURES;
-	ide_cmd_type_parser(&args);
-
-	if (ide_raw_taskfile(drive, &args, NULL)) {
-		printk("%s: enabling service interrupt fail\n", drive->name);
-		return 1;
-	}
-#endif
-
-	if (!drive->tcq) {
-		drive->tcq = kmalloc(sizeof(ide_tag_info_t), GFP_ATOMIC);
-		if (!drive->tcq)
-			return -ENOMEM;
-
-		memset(drive->tcq, 0, sizeof(ide_tag_info_t));
-		drive->tcq->active_tag = IDE_INACTIVE_TAG;
-	}
-
-	return 0;
-}
-
-/*
- * for now assume that command list is always as big as we need and don't
- * attempt to shrink it on tcq disable
- */
-static int ide_enable_queued(ide_drive_t *drive, int on)
-{
-	int depth = drive->using_tcq ? drive->queue_depth : 0;
-
-	/*
-	 * disable or adjust queue depth
-	 */
-	if (!on) {
-		if (drive->using_tcq)
-			printk("%s: TCQ disabled\n", drive->name);
-		drive->using_tcq = 0;
-		return 0;
-	}
-
-	if (ide_tcq_configure(drive)) {
-		drive->using_tcq = 0;
-		return 1;
-	}
-
-	/*
-	 * possibly expand command list
-	 */
-	if (ide_build_commandlist(drive))
-		return 1;
-
-	/*
-	 * check auto-poll support
-	 */
-	ide_tcq_check_autopoll(drive);
-
-	if (depth != drive->queue_depth)
-		printk("%s: tagged command queueing enabled, command queue depth %d\n", drive->name, drive->queue_depth);
-
-	drive->using_tcq = 1;
-
-	/*
-	 * clear stats
-	 */
-	drive->tcq->max_depth = 0;
-	return 0;
-}
-
-int ide_tcq_wait_dataphase(ide_drive_t *drive)
-{
-	ide_startstop_t foo;
-
-	if (ide_wait_stat(&foo, drive, READY_STAT | DRQ_STAT, BUSY_STAT, WAIT_READY)) {
-		printk("%s: timeout waiting for data phase\n", drive->name);
-		return 1;
-	}
-
-	return 0;
-}
-
-int ide_tcq_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
-{
-	struct ata_channel *hwif = drive->channel;
-	unsigned int reading = 0, enable_tcq = 1;
-	struct ata_request *ar;
-	byte stat, feat;
-
-	switch (func) {
-		/*
-		 * invoked from a SERVICE interrupt, command etc already known.
-		 * just need to start the dma engine for this tag
-		 */
-		case ide_dma_read_queued:
-			reading = 1 << 3;
-		case ide_dma_write_queued:
-			TCQ_PRINTK("ide_dma: setting up queued %d\n", drive->tcq->active_tag);
-			BUG_ON(drive->tcq->active_tag == IDE_INACTIVE_TAG);
-
-			if (!test_bit(IDE_BUSY, &HWGROUP(drive)->flags))
-				printk("queued_rw: IDE_BUSY not set\n");
-
-			if (ide_tcq_wait_dataphase(drive))
-				return ide_stopped;
-
-			if (ide_start_dma(hwif, drive, func))
-				return 1;
-
-			ide_tcq_set_intr(HWGROUP(drive), ide_dmaq_intr);
-			return hwif->dmaproc(ide_dma_begin, drive);
-
-			/*
-			 * start a queued command from scratch
-			 */
-		case ide_dma_queued_start:
-			BUG_ON(drive->tcq->active_tag == IDE_INACTIVE_TAG);
-			ar = IDE_CUR_TAG(drive);
-
-			/*
-			 * set nIEN, tag start operation will enable again when
-			 * it is safe
-			 */
-			drive_ctl_nien(drive, 1);
-
-			OUT_BYTE(AR_TASK_CMD(ar), IDE_COMMAND_REG);
-
-			if (ide_tcq_wait_altstat(drive, &stat, BUSY_STAT)) {
-				ide_dump_status(drive, "queued start", stat);
-				ide_tcq_invalidate_queue(drive);
-				return ide_stopped;
-			}
-
-			drive_ctl_nien(drive, 0);
-
-			if (stat & ERR_STAT) {
-				ide_dump_status(drive, "tcq_start", stat);
-				return ide_stopped;
-			}
-
-			/*
-			 * drive released the bus, clear active tag and
-			 * check for service
-			 */
-			if ((feat = GET_FEAT()) & NSEC_REL) {
-				IDE_SET_CUR_TAG(drive, IDE_INACTIVE_TAG);
-				drive->tcq->immed_rel++;
-
-				ide_tcq_set_intr(HWGROUP(drive), ide_dmaq_intr);
-
-				TCQ_PRINTK("REL in queued_start\n");
-
-				if ((stat = GET_STAT()) & SERVICE_STAT)
-					return ide_service(drive);
-
-				return ide_released;
-			}
-
-			drive->tcq->immed_comp++;
-
-			if (ide_tcq_wait_dataphase(drive))
-				return ide_stopped;
-
-			if (ide_start_dma(hwif, drive, func))
-				return ide_stopped;
-
-			TCQ_PRINTK("IMMED in queued_start\n");
-
-			/*
-			 * need to arm handler before starting dma engine,
-			 * transfer could complete right away
-			 */
-			ide_tcq_set_intr(HWGROUP(drive), ide_dmaq_intr);
-
-			if (hwif->dmaproc(ide_dma_begin, drive))
-				return ide_stopped;
-
-			/*
-			 * wait for SERVICE or completion interrupt
-			 */
-			return ide_started;
-
-		case ide_dma_queued_off:
-			enable_tcq = 0;
-		case ide_dma_queued_on:
-			if (enable_tcq && !drive->using_dma)
-				return 1;
-			return ide_enable_queued(drive, enable_tcq);
-		default:
-			break;
-	}
-
-	return 1;
-}
-
-int ide_build_sglist (struct ata_channel *hwif, struct request *rq);
-ide_startstop_t ide_start_tag(ide_dma_action_t func, ide_drive_t *drive,
-			      struct ata_request *ar)
-{
-	ide_startstop_t startstop;
-
-	TCQ_PRINTK("%s: ide_start_tag: begin tag %p/%d, rq %p\n", drive->name,ar,ar->ar_tag, ar->ar_rq);
-
-	/*
-	 * do this now, no need to run that with interrupts disabled
-	 */
-	if (!ide_build_sglist(drive->channel, ar->ar_rq))
-		return ide_stopped;
-
-	IDE_SET_CUR_TAG(drive, ar->ar_tag);
-	HWGROUP(drive)->rq = ar->ar_rq;
-
-	startstop = ide_tcq_dmaproc(func, drive);
-
-	if (unlikely(startstop == ide_stopped)) {
-		IDE_SET_CUR_TAG(drive, IDE_INACTIVE_TAG);
-		HWGROUP(drive)->rq = NULL;
-	}
-
-	return startstop;
-}
diff -urN linux-2.5.10/drivers/ide/Makefile linux/drivers/ide/Makefile
--- linux-2.5.10/drivers/ide/Makefile	2002-04-23 00:29:30.000000000 +0200
+++ linux/drivers/ide/Makefile	2002-04-25 14:17:08.000000000 +0200
@@ -44,7 +44,6 @@
 ide-obj-$(CONFIG_BLK_DEV_HT6560B)	+= ht6560b.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)	+= icside.o
 ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI)	+= ide-dma.o
-ide-obj-$(CONFIG_BLK_DEV_IDE_TCQ)	+= ide-tcq.o
 ide-obj-$(CONFIG_BLK_DEV_IDEPCI)	+= ide-pci.o
 ide-obj-$(CONFIG_BLK_DEV_ISAPNP)	+= ide-pnp.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ide-pmac.o
diff -urN linux-2.5.10/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.5.10/drivers/ide/pdc202xx.c	2002-04-23 00:29:48.000000000 +0200
+++ linux/drivers/ide/pdc202xx.c	2002-04-25 15:39:33.000000000 +0200
@@ -1057,12 +1057,6 @@
 		case ide_dma_timeout:
 			if (drive->channel->resetproc != NULL)
 				drive->channel->resetproc(drive);
-		/*
-		 * we cannot support queued operations on promise, so fail to
-		 * to enable it...
-		 */
-		case ide_dma_queued_on:
-			return 1;
 		default:
 			break;
 	}
diff -urN linux-2.5.10/include/linux/hdreg.h linux/include/linux/hdreg.h
--- linux-2.5.10/include/linux/hdreg.h	2002-04-23 00:29:02.000000000 +0200
+++ linux/include/linux/hdreg.h	2002-04-25 15:39:33.000000000 +0200
@@ -34,7 +34,6 @@
 #define ECC_STAT		0x04	/* Corrected error */
 #define DRQ_STAT		0x08
 #define SEEK_STAT		0x10
-#define SERVICE_STAT		SEEK_STAT
 #define WRERR_STAT		0x20
 #define READY_STAT		0x40
 #define BUSY_STAT		0x80
@@ -51,13 +50,6 @@
 #define ICRC_ERR		0x80	/* new meaning:  CRC error during transfer */
 
 /*
- * bits of NSECTOR reg
- */
-#define NSEC_CD			0x1
-#define NSEC_IO			0x2
-#define NSEC_REL		0x4
-
-/*
  * Command Header sizes for IOCTL commands
  *	HDIO_DRIVE_CMD and HDIO_DRIVE_TASK
  */
diff -urN linux-2.5.10/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.10/include/linux/ide.h	2002-04-23 00:28:11.000000000 +0200
+++ linux/include/linux/ide.h	2002-04-25 16:28:19.000000000 +0200
@@ -273,45 +273,6 @@
 	} b;
 } special_t;
 
-#define IDE_MAX_TAG		(32)		/* spec says 32 max */
-#define IDE_INACTIVE_TAG	(-1)
-
-struct ata_request;
-typedef struct ide_tag_info_s {
-	unsigned long tag_mask;			/* next tag bit mask */
-	struct ata_request *ar[IDE_MAX_TAG];	/* in-progress requests */
-	int active_tag;				/* current active tag */
-
-	int queued;				/* current depth */
-
-	/*
-	 * stats ->
-	 */
-	int max_depth;				/* max depth ever */
-
-	int max_last_depth;			/* max since last check */
-
-	/*
-	 * Either the command completed immediately after being started
-	 * (immed_comp), or the device did a bus release before dma was
-	 * started (immed_rel).
-	 */
-	int immed_rel;
-	int immed_comp;
-	unsigned long oldest_command;
-} ide_tag_info_t;
-
-#define IDE_GET_AR(drive, tag)	((drive)->tcq->ar[(tag)])
-#define IDE_CUR_TAG(drive)	(IDE_GET_AR((drive), (drive)->tcq->active_tag))
-#define IDE_SET_CUR_TAG(drive, tag)	\
-	do {						\
-		((drive)->tcq->active_tag = (tag));	\
-		if ((tag) == IDE_INACTIVE_TAG)		\
-			HWGROUP((drive))->rq = NULL;	\
-	} while (0);
-
-#define IDE_CUR_AR(drive)	(HWGROUP((drive))->rq->special)
-
 struct ide_settings_s;
 /* structure describing an ATA/ATAPI device */
 typedef
@@ -326,11 +287,9 @@
 	 * could move this to the channel and many sync problems would
 	 * magically just go away.
 	 */
-	request_queue_t	queue;		/* per device request queue */
-
-	struct list_head free_req;	/* free ata requests */
+	request_queue_t	queue;	/* per device request queue */
 
-	struct ata_device *next;	/* circular list of hwgroup drives */
+	struct ata_device	*next;	/* circular list of hwgroup drives */
 
 	/* Those are directly injected jiffie values. They should go away and
 	 * we should use generic timers instead!!!
@@ -343,7 +302,6 @@
 
 	special_t	special;	/* special action flags */
 	byte     using_dma;		/* disk is using dma for read/write */
-	byte	 using_tcq;		/* disk is using queued dma operations*/
 	byte	 retry_pio;		/* retrying dma capable host in pio */
 	byte	 state;			/* retry state */
 	byte     dsc_overlap;		/* flag: DSC overlap */
@@ -412,8 +370,6 @@
 	unsigned int	failures;	/* current failure count */
 	unsigned int	max_failures;	/* maximum allowed failure count */
 	struct device	device;		/* global device tree handle */
-	unsigned int	queue_depth;
-	ide_tag_info_t	*tcq;
 } ide_drive_t;
 
 /*
@@ -432,10 +388,7 @@
 		ide_dma_off,	ide_dma_off_quietly,	ide_dma_test_irq,
 		ide_dma_bad_drive,			ide_dma_good_drive,
 		ide_dma_verbose,			ide_dma_retune,
-		ide_dma_lostirq,			ide_dma_timeout,
-		ide_dma_read_queued,			ide_dma_write_queued,
-		ide_dma_queued_start,			ide_dma_queued_on,
-		ide_dma_queued_off,
+		ide_dma_lostirq,			ide_dma_timeout
 } ide_dma_action_t;
 
 typedef int (ide_dmaproc_t)(ide_dma_action_t, ide_drive_t *);
@@ -494,6 +447,11 @@
 	void (*atapi_write)(ide_drive_t *, void *, unsigned int);
 
 	ide_dmaproc_t	*dmaproc;	/* dma read/write/abort routine */
+	unsigned int	*dmatable_cpu;	/* dma physical region descriptor table (cpu view) */
+	dma_addr_t	dmatable_dma;	/* dma physical region descriptor table (dma view) */
+	struct scatterlist *sg_table;	/* Scatter-gather list used to build the above */
+	int sg_nents;			/* Current number of entries in it */
+	int sg_dma_direction;		/* dma transfer direction */
 	unsigned long	dma_base;	/* base addr for dma ports */
 	unsigned	dma_extra;	/* extra addr for dma ports */
 	unsigned long	config_data;	/* for use by chipset-specific code */
@@ -517,7 +475,7 @@
 	byte		io_32bit;	/* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
 	unsigned no_unmask	   : 1;	/* disallow setting unmask bit */
 	byte		unmask;		/* flag: okay to unmask other irqs */
-	unsigned	auto_poll  : 1; /* supports nop auto-poll */
+
 #if (DISK_RECOVERY_TIME > 0)
 	unsigned long	last_time;	/* time when previous rq was done */
 #endif
@@ -538,7 +496,7 @@
 typedef enum {
 	ide_stopped,	/* no drive operation was started */
 	ide_started,	/* a drive operation was started, and a handler was set */
-	ide_released,	/* started, handler set, bus released */
+	ide_released	/* started and released bus */
 } ide_startstop_t;
 
 /*
@@ -559,19 +517,21 @@
 #define IDE_DMA		2	/* DMA in progress */
 
 typedef struct hwgroup_s {
-	ide_handler_t		*handler;	/* irq handler, if active */
-	unsigned long		flags;		/* BUSY, SLEEPING */
-	ide_drive_t		*drive;		/* current drive */
-	struct ata_channel	*hwif;		/* ptr to current hwif in linked-list */
+	ide_handler_t		*handler;/* irq handler, if active */
+	unsigned long		flags;	/* BUSY, SLEEPING */
+	ide_drive_t		*drive;	/* current drive */
+	struct ata_channel	*hwif;	/* ptr to current hwif in linked-list */
 
-	struct request		*rq;		/* current request */
+	struct request		*rq;	/* current request */
 
-	struct timer_list	timer;		/* failsafe timer */
-	struct request		wrq;		/* local copy of current write rq */
+	struct timer_list	timer;	/* failsafe timer */
+	struct request		wrq;	/* local copy of current write rq */
 	unsigned long		poll_timeout;	/* timeout value during long polls */
 	ide_expiry_t		*expiry;	/* queried upon timeouts */
 } ide_hwgroup_t;
 
+/* structure attached to the request for IDE_TASK_CMDS */
+
 /*
  * configurable drive settings
  */
@@ -708,7 +668,6 @@
 
 extern int __ide_end_request(ide_drive_t *drive, int uptodate, int nr_secs);
 extern int ide_end_request(ide_drive_t *drive, int uptodate);
-extern void ide_end_queued_request(ide_drive_t *drive, int, struct request *);
 
 /*
  * This is used on exit from the driver, to designate the next irq handler
@@ -804,33 +763,8 @@
 	int			command_type;
 	ide_pre_handler_t	*prehandler;
 	ide_handler_t		*handler;
-	struct ata_request	*ar;
-};
-
-/*
- * Merge this with the above struct soon.
- */
-struct ata_request {
-	struct request		*ar_rq;		/* real request */
-	struct ata_device	*ar_drive;	/* associated drive */
-	unsigned long		ar_flags;	/* ATA_AR_* flags */
-	int			ar_tag;		/* tag number, if any */
-	struct list_head	ar_queue;	/* pending list */
-	struct ata_taskfile	ar_task;	/* associated taskfile */
-	unsigned long		ar_time;
-
-	/* DMA stuff, PCI layer */
-	struct scatterlist	*ar_sg_table;
-	int			ar_sg_nents;
-	int			ar_sg_ddir;
-
-	/* CPU related DMA stuff  */
-	unsigned int		*ar_dmatable_cpu;
-	dma_addr_t		ar_dmatable;
 };
 
-#define AR_TASK_CMD(ar)	((ar)->ar_task.taskfile.command)
-
 extern void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount);
 extern void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount);
 
@@ -930,24 +864,22 @@
 extern int ide_unregister_subdriver(ide_drive_t *drive);
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
-# define ON_BOARD		1
-# define NEVER_BOARD		0
-# ifdef CONFIG_BLK_DEV_OFFBOARD
-#  define OFF_BOARD		ON_BOARD
-# else
-#  define OFF_BOARD		NEVER_BOARD
-# endif
+#define ON_BOARD		1
+#define NEVER_BOARD		0
+#ifdef CONFIG_BLK_DEV_OFFBOARD
+# define OFF_BOARD		ON_BOARD
+#else
+# define OFF_BOARD		NEVER_BOARD
+#endif
 
-/* FIXME: This should go away possible. */
-extern void __init ide_scan_pcibus(int scan_direction);
+void __init ide_scan_pcibus(int scan_direction);
 #endif
 #ifdef CONFIG_BLK_DEV_IDEDMA
-extern int ide_build_dmatable(ide_drive_t *drive, struct request *rq, ide_dma_action_t func);
-extern void ide_destroy_dmatable(ide_drive_t *drive);
-extern int ide_start_dma(struct ata_channel *, ide_drive_t *, ide_dma_action_t);
-extern ide_startstop_t ide_dma_intr(ide_drive_t *drive);
-extern int check_drive_lists(ide_drive_t *drive, int good_bad);
-extern int ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
+int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func);
+void ide_destroy_dmatable (ide_drive_t *drive);
+ide_startstop_t ide_dma_intr (ide_drive_t *drive);
+int check_drive_lists (ide_drive_t *drive, int good_bad);
+int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
 extern void ide_release_dma(struct ata_channel *hwif);
 extern void ide_setup_dma(struct ata_channel *hwif,
 		unsigned long dmabase, unsigned int num_ports) __init;
@@ -960,112 +892,4 @@
 extern int drive_is_ready(ide_drive_t *drive);
 extern void revalidate_drives(void);
 
-/*
- * Tagged Command Queueing:
- */
-
-/*
- * ata_request flag bits
- */
-#define ATA_AR_QUEUED	1	/* was queued */
-#define ATA_AR_SETUP	2	/* dma table mapped */
-#define ATA_AR_POOL	4	/* originated from drive pool */
-
-/*
- * if turn-around time is longer than this, halve queue depth
- */
-#define ATA_AR_MAX_TURNAROUND	(3 * HZ)
-
-#define list_ata_entry(entry) list_entry((entry), struct ata_request, ar_queue)
-
-static inline void ata_ar_init(ide_drive_t *drive, struct ata_request *ar)
-{
-	ar->ar_rq = NULL;
-	ar->ar_drive = drive;
-	ar->ar_flags = 0;
-	ar->ar_tag = 0;
-	memset(&ar->ar_task, 0, sizeof(ar->ar_task));
-	ar->ar_sg_nents = 0;
-	ar->ar_sg_ddir = 0;
-}
-
-/*
- * Return a free command, automatically add it to busy list.
- */
-static inline struct ata_request *ata_ar_get(ide_drive_t *drive)
-{
-	struct ata_request *ar = NULL;
-
-	if (drive->tcq && drive->tcq->queued >= drive->queue_depth)
-		return NULL;
-
-	if (!list_empty(&drive->free_req)) {
-		ar = list_ata_entry(drive->free_req.next);
-
-		list_del(&ar->ar_queue);
-		ata_ar_init(drive, ar);
-		ar->ar_flags |= ATA_AR_POOL;
-	}
-
-	return ar;
-}
-
-static inline void ata_ar_put(ide_drive_t *drive, struct ata_request *ar)
-{
-	if (ar->ar_flags & ATA_AR_POOL)
-		list_add(&ar->ar_queue, &drive->free_req);
-
-	if (ar->ar_flags & ATA_AR_QUEUED) {
-		/* clear the tag */
-		drive->tcq->ar[ar->ar_tag] = NULL;
-		__clear_bit(ar->ar_tag, &drive->tcq->tag_mask);
-		drive->tcq->queued--;
-	}
-
-	ar->ar_rq = NULL;
-}
-
-static inline int ide_get_tag(ide_drive_t *drive)
-{
-	int tag = ffz(drive->tcq->tag_mask);
-
-	BUG_ON(drive->tcq->tag_mask == 0xffffffff);
-
-	__set_bit(tag, &drive->tcq->tag_mask);
-
-	if (tag + 1 > drive->tcq->max_depth)
-		drive->tcq->max_depth = tag + 1;
-	if (tag + 1 > drive->tcq->max_last_depth)
-		drive->tcq->max_last_depth = tag + 1;
-
-	return tag;
-}
-
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-static inline int ide_pending_commands(ide_drive_t *drive)
-{
-	if (!drive->tcq)
-		return 0;
-
-	return drive->tcq->queued;
-}
-
-static inline int ide_can_queue(ide_drive_t *drive)
-{
-	if (!drive->tcq)
-		return 1;
-
-	return drive->tcq->queued < drive->queue_depth;
-}
-#else
-#define ide_pending_commands(drive)	(0)
-#define ide_can_queue(drive)		(1)
-#endif
-
-int ide_build_commandlist(ide_drive_t *);
-int ide_init_commandlist(ide_drive_t *);
-void ide_teardown_commandlist(ide_drive_t *);
-int ide_tcq_dmaproc(ide_dma_action_t, ide_drive_t *);
-ide_startstop_t ide_start_tag(ide_dma_action_t, ide_drive_t *, struct ata_request *);
-
-#endif
+#endif /* _IDE_H */

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

* Re: [PATCH] 2.5.10 IDE 41
  2002-04-25 17:39   ` Jens Axboe
@ 2002-04-25 17:18     ` Martin Dalecki
  2002-04-29  8:21       ` Jens Axboe
  0 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-04-25 17:18 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, Kernel Mailing List

Uz.ytkownik Jens Axboe napisa?:
> On Thu, Apr 25 2002, Martin Dalecki wrote:
> 
>>Tue Apr 23 00:27:55 CEST 2002 ide-clean-41
>>
>>- Revoke the TCQ stuff. Well having it for some time showed just nicely what
>>  has to be done before it can be included cleanly. But it's just not ready
>>  jet.
> 
> 
> Again, you charge ahead instead of just getting it fixed... It's not a
> lot of work!

Unless you actually try too ;-).

> If you want to disable the TCQ stuff until this is fixed, fine, I have
> no objection to that. Completely ripping it out is a silly decision.

Again: what's the problem? - You still have it there at hand.
Nothing is lost.

> First you blast ahead and include even before I ask you or sent it to
> Linus myself, now you remove it without my consent as well. A bit of
> consistency would get you a long way.


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

* Re: [PATCH] 2.5.10 IDE 41
  2002-04-25 14:32 ` [PATCH] 2.5.10 IDE 41 Martin Dalecki
@ 2002-04-25 17:39   ` Jens Axboe
  2002-04-25 17:18     ` Martin Dalecki
  0 siblings, 1 reply; 39+ messages in thread
From: Jens Axboe @ 2002-04-25 17:39 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, Kernel Mailing List

On Thu, Apr 25 2002, Martin Dalecki wrote:
> Tue Apr 23 00:27:55 CEST 2002 ide-clean-41
> 
> - Revoke the TCQ stuff. Well having it for some time showed just nicely what
>   has to be done before it can be included cleanly. But it's just not ready
>   jet.

Again, you charge ahead instead of just getting it fixed... It's not a
lot of work!

If you want to disable the TCQ stuff until this is fixed, fine, I have
no objection to that. Completely ripping it out is a silly decision.
First you blast ahead and include even before I ask you or sent it to
Linus myself, now you remove it without my consent as well. A bit of
consistency would get you a long way.

-- 
Jens Axboe


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

* Re: [PATCH] 2.5.10 IDE 41
  2002-04-25 17:18     ` Martin Dalecki
@ 2002-04-29  8:21       ` Jens Axboe
  0 siblings, 0 replies; 39+ messages in thread
From: Jens Axboe @ 2002-04-29  8:21 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, Kernel Mailing List

On Thu, Apr 25 2002, Martin Dalecki wrote:
> >If you want to disable the TCQ stuff until this is fixed, fine, I have
> >no objection to that. Completely ripping it out is a silly decision.
> 
> Again: what's the problem? - You still have it there at hand.
> Nothing is lost.

That's bullshit, lots of time is needlessly lost because merging with
the ide tree is such a huge pain these days.

-- 
Jens Axboe


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

* [PATCH] 2.5.11 IDE 46
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (9 preceding siblings ...)
  2002-04-25 14:32 ` [PATCH] 2.5.10 IDE 41 Martin Dalecki
@ 2002-04-30  8:09 ` Martin Dalecki
  2002-04-30  8:11 ` Linux 2.5.7 Martin Dalecki
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-04-30  8:09 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List, axboe

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


- Remove the specific CONFIG_IDEDMA_PCI_WIP in favor of using the generic
   CONFIG_EXPERIMENTAL tag. (Pointed out by Vojtech Pavlik).

- Change the signature of the IRQ handler to take the request directly as a
   parameter. This doesn't blow the code up but makes it much more obvious and
   finally it's reducing the number of side effects of the hwgroup->rq field.

- A second sharp look after the above change allowed us to remove the wrq field
   from the hwgroup struct. It's just not used at all.

- Change the signature of the end_request member of struct ata_operations to
   take the request as a second argument. Similar for __ide_end_request()
   and ide_end_request().

- Remove BUG_ON() items just before ide_set_handler(). The check in
   ide_set_handler is clever enough now.

- Remove the rq subfield from ide-scsi packet structure. We have now the
   request context always in place. Same for floppy.

- Let the timer expiry function take the request as a direct argument.

Yes I know those changes are extensive. But they are a necessary step
in between for the following purposes:

- Consolidate the whole ATA/ATAPI stuff on passing a single unified request
   handling object. Because after eliminating those side effects it's far easier
   to see what's passed where.

- Minimizing the amount of side effects in the overall code. That's a good
   thing anyway and it *doesn't* cost us neither performance nor space, since
   the stack depths are small anyway here.

- Minimizing the usage of hwgroup - which should go away if possible.

I apologize for the size of this patch, but those changes belong logically
mostly all together.

[-- Attachment #2: ide-clean-46.diff.gz --]
[-- Type: application/x-gzip, Size: 29893 bytes --]

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

* Re: Linux 2.5.7
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (10 preceding siblings ...)
  2002-04-30  8:09 ` [PATCH] 2.5.11 IDE 46 Martin Dalecki
@ 2002-04-30  8:11 ` Martin Dalecki
  2002-04-30  8:45 ` [PATCH] 2.5.11 IDE 47 Martin Dalecki
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-04-30  8:11 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List, axboe

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

- Rewrite choose_drive() to iterate explicitely over the channels and devices
   on them. It is not performance critical to iterate over this typically quite
   small array of disks and allows us to let them act on the natural entity,
   namely the channel as well as to remove the drive->next field from struct
   ata_device.  Make the device eviction code in ide_do_request() more
   intelliglible.  Add some comments explaining the reasoning behind the code
   there.

- Now finally since the code for choosing the drive which will be serviced next
   is intelliglibly it became obvious that the attempt to choose the next drive
   based on the duration of the last request was entierly bogous. (Because for
   example wakeups can take a long time, but this doesn't indicate that the
   drive is slow.) Remove this criterium and the corresponding accounting
   therefore. Threat all drives fairly right now.

Surprise surprise the overall system throughput increased :-).

[-- Attachment #2: ide-clean-47.diff --]
[-- Type: text/plain, Size: 28750 bytes --]

diff -urN linux-2.5.11/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.11/drivers/ide/ide.c	2002-04-30 03:48:19.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-04-30 03:41:06.000000000 +0200
@@ -285,7 +285,7 @@
 	hwif->bus_state = BUSSTATE_ON;
 
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		ide_drive_t *drive = &hwif->drives[unit];
+		struct ata_device *drive = &hwif->drives[unit];
 
 		drive->type			= ATA_DISK;
 		drive->select.all		= (unit<<4)|0xa0;
@@ -507,19 +507,21 @@
 /*
  * This is called exactly *once* for each channel.
  */
-void ide_geninit(struct ata_channel *hwif)
+void ide_geninit(struct ata_channel *ch)
 {
 	unsigned int unit;
-	struct gendisk *gd = hwif->gd;
+	struct gendisk *gd = ch->gd;
 
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		ide_drive_t *drive = &hwif->drives[unit];
+		struct ata_device *drive = &ch->drives[unit];
 
 		if (!drive->present)
 			continue;
+
 		if (drive->type != ATA_DISK && drive->type != ATA_FLOPPY)
 			continue;
-		register_disk(gd,mk_kdev(hwif->major,unit<<PARTN_BITS),
+
+		register_disk(gd,mk_kdev(ch->major,unit<<PARTN_BITS),
 #ifdef CONFIG_BLK_DEV_ISAPNP
 			(drive->forced_geom && drive->noprobe) ? 1 :
 #endif
@@ -1189,30 +1191,89 @@
 }
 
 /*
- * Select the next drive which will be serviced.
+ * Select the next device which will be serviced.
  */
-static struct ata_device *choose_drive(struct ata_device *cur)
+static struct ata_device *choose_urgent_device(struct ata_channel *channel)
 {
-	struct ata_device *drive = cur;
 	struct ata_device *best = NULL;
+	int i;
 
-	do {
-		if (!list_empty(&drive->queue.queue_head)
-		&& (!drive->PADAM_sleep	|| time_after_eq(drive->PADAM_sleep, jiffies))) {
-			if (!best
-			 || (drive->PADAM_sleep && (!best->PADAM_sleep || time_after(best->PADAM_sleep, drive->PADAM_sleep)))
-			 || (!best->PADAM_sleep && time_after(best->PADAM_service_start + 2 * best->PADAM_service_time, drive->PADAM_service_start + 2 * drive->PADAM_service_time)))
+	for (i = 0; i < MAX_HWIFS; ++i) {
+		int unit;
+		struct ata_channel *ch = &ide_hwifs[i];
+
+		if (!ch->present)
+			continue;
+
+		if (ch->hwgroup != channel->hwgroup)
+			continue;
+
+		for (unit = 0; unit < MAX_DRIVES; ++unit) {
+			struct ata_device *drive = &ch->drives[unit];
+
+			if (!drive->present)
+				continue;
+
+			/* There are no request pending for this device.
+			 */
+			if (list_empty(&drive->queue.queue_head))
+				continue;
+
+			/* This device still want's to remain idle.
+			 */
+			if (drive->PADAM_sleep && time_after(jiffies, drive->PADAM_sleep))
+				continue;
+
+			/* Take this device, if there is no device choosen thus far or
+			 * it's more urgent.
+			 */
+			if (!best || (drive->PADAM_sleep && (!best->PADAM_sleep || time_after(best->PADAM_sleep, drive->PADAM_sleep))))
 			{
 				if (!blk_queue_plugged(&drive->queue))
 					best = drive;
 			}
 		}
-		drive = drive->next;
-	} while (drive != cur);
+	}
+
 	return best;
 }
 
 /*
+ * Determine the longes sleep time for the devices in our hwgroup.
+ */
+static unsigned long longest_sleep(struct ata_channel *channel)
+{
+	unsigned long sleep = 0;
+	int i;
+
+	for (i = 0; i < MAX_HWIFS; ++i) {
+		int unit;
+		struct ata_channel *ch = &ide_hwifs[i];
+
+		if (!ch->present)
+			continue;
+
+		if (ch->hwgroup != channel->hwgroup)
+			continue;
+
+		for (unit = 0; unit < MAX_DRIVES; ++unit) {
+			struct ata_device *drive = &ch->drives[unit];
+
+			if (!drive->present)
+				continue;
+
+			/* This device is sleeping and waiting to be serviced
+			 * later than any other device we checked thus far.
+			 */
+			if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
+				sleep = drive->PADAM_sleep;
+		}
+	}
+
+	return sleep;
+}
+
+/*
  * Issue a new request to a drive from hwgroup.
  * Caller must have already done spin_lock_irqsave(&ide_lock, ...)
  *
@@ -1242,42 +1303,33 @@
  * will start the next request from the queue.  If no more work remains,
  * the driver will clear the hwgroup->flags IDE_BUSY flag and exit.
  */
-static void ide_do_request(struct ata_channel *ch, int masked_irq)
+static void ide_do_request(struct ata_channel *channel, int masked_irq)
 {
-	ide_hwgroup_t *hwgroup = ch->hwgroup;
-	struct ata_device *drive;
-	ide_startstop_t	startstop;
-	struct request	*rq;
-
+	ide_hwgroup_t *hwgroup = channel->hwgroup;
 	ide_get_lock(&irq_lock, ata_irq_request, hwgroup);/* for atari only: POSSIBLY BROKEN HERE(?) */
 
 	__cli();	/* necessary paranoia: ensure IRQs are masked on local CPU */
 
 	while (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) {
-		drive = choose_drive(hwgroup->drive);
+		struct ata_channel *ch;
+		ide_startstop_t	startstop;
+		struct ata_device *drive = choose_urgent_device(channel);
 
 		if (drive == NULL) {
 			unsigned long sleep = 0;
 
 			hwgroup->rq = NULL;
-
-			drive = hwgroup->drive;
-			do {
-				if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
-					sleep = drive->PADAM_sleep;
-
-				drive = drive->next;
-			} while (drive!= hwgroup->drive);
+			sleep = longest_sleep(channel);
 
 			if (sleep) {
+
 				/*
-				 * Take a short snooze, and then wake up this
-				 * hwgroup again.  This gives other hwgroups on
-				 * the same a chance to play fairly with us,
-				 * just in case there are big differences in
+				 * Take a short snooze, and then wake up again.
+				 * Just in case there are big differences in
 				 * relative throughputs.. don't want to hog the
 				 * cpu too much.
 				 */
+
 				if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep))
 					sleep = jiffies + WAIT_MIN_SLEEP;
 #if 1
@@ -1293,29 +1345,35 @@
 				ide_release_lock(&irq_lock);/* for atari only */
 				clear_bit(IDE_BUSY, &hwgroup->flags);
 			}
-			return;		/* no more work for this hwgroup (for now) */
+
+			return;
 		}
 		ch = drive->channel;
 
-		if (hwgroup->drive->channel->sharing_irq && ch != hwgroup->drive->channel && ch->io_ports[IDE_CONTROL_OFFSET]) {
+		if (hwgroup->XXX_drive->channel->sharing_irq && ch != hwgroup->XXX_drive->channel && ch->io_ports[IDE_CONTROL_OFFSET]) {
 			/* set nIEN for previous channel */
+			/* FIXME: check this! It appears to act on the current channel! */
 
 			if (ch->intrproc)
 				ch->intrproc(drive);
 			else
 				OUT_BYTE((drive)->ctl|2, ch->io_ports[IDE_CONTROL_OFFSET]);
 		}
-		hwgroup->drive = drive;
+
+		/* Remember the last drive we where acting on.
+		 */
+		hwgroup->XXX_drive = drive;
+
+		/* Reset wait timeout.
+		 */
 		drive->PADAM_sleep = 0;
-		drive->PADAM_service_start = jiffies;
 
 		if (blk_queue_plugged(&drive->queue))
 			BUG();
 
-		/*
-		 * just continuing an interrupted request maybe
+		/* Just continuing an interrupted request maybe.
 		 */
-		rq = hwgroup->rq = elv_next_request(&drive->queue);
+		hwgroup->rq = elv_next_request(&drive->queue);
 
 		/*
 		 * Some systems have trouble with IDE IRQs arriving while the
@@ -1331,7 +1389,7 @@
 			disable_irq_nosync(ch->irq);
 		spin_unlock(&ide_lock);
 		ide__sti();	/* allow other IRQs while we start this request */
-		startstop = start_request(drive, rq);
+		startstop = start_request(drive, hwgroup->rq);
 		spin_lock_irq(&ide_lock);
 		if (masked_irq && ch->irq != masked_irq)
 			enable_irq(ch->irq);
@@ -1432,7 +1490,7 @@
 		if (test_and_clear_bit(IDE_SLEEP, &hwgroup->flags))
 			clear_bit(IDE_BUSY, &hwgroup->flags);
 	} else {
-		struct ata_device *drive = hwgroup->drive;
+		struct ata_device *drive = hwgroup->XXX_drive;
 		if (!drive) {
 			printk("ide_timer_expiry: hwgroup->drive was NULL\n");
 			hwgroup->handler = NULL;
@@ -1483,7 +1541,6 @@
 					startstop = ide_error(drive, "irq timeout", GET_STAT());
 			}
 			set_recovery_timer(ch);
-			drive->PADAM_service_time = jiffies - drive->PADAM_service_start;
 			enable_irq(ch->irq);
 			spin_lock_irq(&ide_lock);
 			if (startstop == ide_stopped)
@@ -1491,7 +1548,7 @@
 		}
 	}
 
-	ide_do_request(hwgroup->drive->channel, 0);
+	ide_do_request(hwgroup->XXX_drive->channel, 0);
 
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
@@ -1525,15 +1582,15 @@
 
 	for (i = 0; i < MAX_HWIFS; ++i) {
 		u8 stat;
-		struct ata_channel *tmp = &ide_hwifs[i];
+		struct ata_channel *ch = &ide_hwifs[i];
 
-		if (!tmp->present)
+		if (!ch->present)
 			continue;
 
-		if (tmp->irq != irq)
+		if (ch->irq != irq)
 			continue;
 
-		stat = IN_BYTE(tmp->io_ports[IDE_STATUS_OFFSET]);
+		stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
 		if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
 			/* Try to not flood the console with msgs */
 			static unsigned long last_msgtime;
@@ -1543,7 +1600,7 @@
 			if (time_after(jiffies, last_msgtime + HZ)) {
 				last_msgtime = jiffies;
 				printk("%s: unexpected interrupt, status=0x%02x, count=%d\n",
-						tmp->name, stat, count);
+						ch->name, stat, count);
 			}
 		}
 	}
@@ -1601,14 +1658,7 @@
 		}
 		goto out_lock;
 	}
-	drive = hwgroup->drive;
-	if (!drive) {
-		/*
-		 * This should NEVER happen, and there isn't much we could do
-		 * about it here.
-		 */
-		goto out_lock;
-	}
+	drive = hwgroup->XXX_drive;
 	if (!drive_is_ready(drive)) {
 		/*
 		 * This happens regularly when we share a PCI IRQ with another device.
@@ -1640,7 +1690,6 @@
 	 * won't allow another of the same (on any CPU) until we return.
 	 */
 	set_recovery_timer(drive->channel);
-	drive->PADAM_service_time = jiffies - drive->PADAM_service_start;
 	if (startstop == ide_stopped) {
 		if (hwgroup->handler == NULL) {	/* paranoia */
 			clear_bit(IDE_BUSY, &hwgroup->flags);
@@ -1668,7 +1717,7 @@
 		if (hwif->present && major == hwif->major) {
 			int unit = DEVICE_NR(i_rdev);
 			if (unit < MAX_DRIVES) {
-				ide_drive_t *drive = &hwif->drives[unit];
+				struct ata_device *drive = &hwif->drives[unit];
 				if (drive->present)
 					return drive;
 			}
@@ -1800,46 +1849,44 @@
  */
 void revalidate_drives(void)
 {
-	struct ata_channel *hwif;
-	ide_drive_t *drive;
-	int h;
+	int i;
 
-	for (h = 0; h < MAX_HWIFS; ++h) {
+	for (i = 0; i < MAX_HWIFS; ++i) {
 		int unit;
-		hwif = &ide_hwifs[h];
+		struct ata_channel *ch = &ide_hwifs[i];
+
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			drive = &ide_hwifs[h].drives[unit];
+			struct ata_device *drive = &ch->drives[unit];
+
 			if (drive->revalidate) {
 				drive->revalidate = 0;
 				if (!initializing)
-					ide_revalidate_disk(mk_kdev(hwif->major, unit<<PARTN_BITS));
+					ide_revalidate_disk(mk_kdev(ch->major, unit<<PARTN_BITS));
 			}
 		}
 	}
 }
 
-static void ide_probe_module(void)
-{
-	ideprobe_init();
-	revalidate_drives();
-}
-
 static void ide_driver_module (void)
 {
-	int index;
+	int i;
+
+	/* Don't reinit the probe if there is already one channel detected. */
 
-	for (index = 0; index < MAX_HWIFS; ++index)
-		if (ide_hwifs[index].present)
-			goto search;
-	ide_probe_module();
-search:
+	for (i = 0; i < MAX_HWIFS; ++i) {
+		if (ide_hwifs[i].present)
+			goto revalidate;
+	}
 
+	ideprobe_init();
+
+revalidate:
 	revalidate_drives();
 }
 
 static int ide_open(struct inode * inode, struct file * filp)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 
 	if ((drive = get_info_ptr(inode->i_rdev)) == NULL)
 		return -ENXIO;
@@ -1901,7 +1948,7 @@
  */
 static int ide_release(struct inode * inode, struct file * file)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 
 	if (!(drive = get_info_ptr(inode->i_rdev)))
 		return 0;
@@ -1977,7 +2024,7 @@
 void ide_unregister(struct ata_channel *ch)
 {
 	struct gendisk *gd;
-	ide_drive_t *drive, *d;
+	struct ata_device *d;
 	ide_hwgroup_t *hwgroup;
 	int unit, i;
 	unsigned long flags;
@@ -1986,15 +2033,20 @@
 	int n = 0;
 
 	spin_lock_irqsave(&ide_lock, flags);
+
 	if (!ch->present)
 		goto abort;
+
 	put_device(&ch->dev);
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		drive = &ch->drives[unit];
+		struct ata_device * drive = &ch->drives[unit];
+
 		if (!drive->present)
 			continue;
+
 		if (drive->busy || drive->usage)
 			goto abort;
+
 		if (ata_ops(drive)) {
 			if (ata_ops(drive)->cleanup) {
 				if (ata_ops(drive)->cleanup(drive))
@@ -2010,9 +2062,11 @@
 	 */
 	spin_unlock_irqrestore(&ide_lock, flags);
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		drive = &ch->drives[unit];
+		struct ata_device * drive = &ch->drives[unit];
+
 		if (!drive->present)
 			continue;
+
 		minor = drive->select.b.unit << PARTN_BITS;
 		for (p = 0; p < (1<<PARTN_BITS); ++p) {
 			if (drive->part[p].nr_sects > 0) {
@@ -2029,25 +2083,24 @@
 	hwif_unregister(ch);
 
 	/*
-	 * Remove us from the hwgroup, and free the hwgroup if we were the only
-	 * member.
+	 * Remove us from the hwgroup
 	 */
 
 	hwgroup = ch->hwgroup;
-	d = hwgroup->drive;
+	d = hwgroup->XXX_drive;
 	for (i = 0; i < MAX_DRIVES; ++i) {
-		drive = &ch->drives[i];
+		struct ata_device *drive = &ch->drives[i];
+
 		if (drive->de) {
 			devfs_unregister (drive->de);
 			drive->de = NULL;
 		}
 		if (!drive->present)
 			continue;
-		while (hwgroup->drive->next != drive)
-			hwgroup->drive = hwgroup->drive->next;
-		hwgroup->drive->next = drive->next;
-		if (hwgroup->drive == drive)
-			hwgroup->drive = NULL;
+
+		if (hwgroup->XXX_drive == drive)
+			hwgroup->XXX_drive = NULL;
+
 		if (drive->id != NULL) {
 			kfree(drive->id);
 			drive->id = NULL;
@@ -2056,8 +2109,10 @@
 		blk_cleanup_queue(&drive->queue);
 	}
 	if (d->present)
-		hwgroup->drive = d;
+		hwgroup->XXX_drive = d;
 
+	/* Free the hwgroup if we were the only member.
+	 */
 	n = 0;
 	for (i = 0; i < MAX_HWIFS; ++i) {
 		struct ata_channel *tmp = &ide_hwifs[i];
@@ -2215,10 +2270,12 @@
 	hwif->chipset = hw->chipset;
 
 	if (!initializing) {
-		ide_probe_module();
+		ideprobe_init();
+		revalidate_drives();
 #ifdef CONFIG_PROC_FS
 		create_proc_ide_interfaces();
 #endif
+		/* FIXME: Do we really have to call it second time here?! */
 		ide_driver_module();
 	}
 
@@ -3121,25 +3178,29 @@
 }
 
 /*
- * Lookup IDE devices, which requested a particular driver
+ * Lookup ATA devices, which requested a particular driver.
  */
 ide_drive_t *ide_scan_devices(byte type, const char *name, struct ata_operations *driver, int n)
 {
 	unsigned int unit, index, i;
 
 	for (index = 0, i = 0; index < MAX_HWIFS; ++index) {
-		struct ata_channel *hwif = &ide_hwifs[index];
-		if (!hwif->present)
+		struct ata_channel *ch = &ide_hwifs[index];
+
+		if (!ch->present)
 			continue;
+
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			ide_drive_t *drive = &hwif->drives[unit];
+			struct ata_device *drive = &ch->drives[unit];
 			char *req = drive->driver_req;
+
 			if (*req && !strstr(name, req))
 				continue;
 			if (drive->present && drive->type == type && drive->driver == driver && ++i > n)
 				return drive;
 		}
 	}
+
 	return NULL;
 }
 
@@ -3179,9 +3240,21 @@
 			drive->channel->udma(ide_dma_off_quietly, drive, NULL);
 			drive->channel->udma(ide_dma_check, drive, NULL);
 		}
-		/* Only CD-ROMs and tape drives support DSC overlap. */
-		drive->dsc_overlap = (drive->next != drive
-				&& (drive->type == ATA_ROM || drive->type == ATA_TAPE));
+
+		/* Only CD-ROMs and tape drives support DSC overlap.  But only
+		 * if they are alone on a channel. */
+		if (drive->type == ATA_ROM || drive->type == ATA_TAPE) {
+			int single = 0;
+			int unit;
+
+			for (unit = 0; unit < MAX_DRIVES; ++unit)
+				if (drive->channel->drives[unit].present)
+					++single;
+
+			drive->dsc_overlap = (single == 1);
+		} else
+			drive->dsc_overlap = 0;
+
 	}
 	drive->revalidate = 1;
 	drive->suspend_reset = 0;
@@ -3319,9 +3392,7 @@
 
 static int ide_notify_reboot (struct notifier_block *this, unsigned long event, void *x)
 {
-	struct ata_channel *hwif;
-	ide_drive_t *drive;
-	int i, unit;
+	int i;
 
 	switch (event) {
 		case SYS_HALT:
@@ -3335,12 +3406,15 @@
 	printk("flushing ide devices: ");
 
 	for (i = 0; i < MAX_HWIFS; i++) {
-		hwif = &ide_hwifs[i];
-		if (!hwif->present)
+		int unit;
+		struct ata_channel *ch = &ide_hwifs[i];
+
+		if (!ch->present)
 			continue;
 
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			drive = &hwif->drives[unit];
+			struct ata_device *drive = &ch->drives[unit];
+
 			if (!drive->present)
 				continue;
 
diff -urN linux-2.5.11/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.11/drivers/ide/ide-probe.c	2002-04-29 05:11:17.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-04-30 03:30:13.000000000 +0200
@@ -438,10 +438,11 @@
  * This routine only knows how to look for drive units 0 and 1
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
-static void probe_hwif(struct ata_channel *ch)
+static void channel_probe(struct ata_channel *ch)
 {
 	unsigned int unit;
 	unsigned long flags;
+	int error;
 
 	if (ch->noprobe)
 		return;
@@ -454,96 +455,97 @@
 	/*
 	 * Check for the presence of a channel by probing for drives on it.
 	 */
-
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		struct ata_device *drive = &ch->drives[unit];
 
 		probe_for_drive(drive);
 
-		if (drive->present && !ch->present) {
+		/* drive found, there is a channel it is attached too. */
+		if (drive->present)
 			ch->present = 1;
-		}
 	}
 
-	if (ch->present) {
-		int error = 0;
+	if (!ch->present)
+		goto not_found;
 
-		if (((unsigned long)ch->io_ports[IDE_DATA_OFFSET] | 7) ==
-				((unsigned long)ch->io_ports[IDE_STATUS_OFFSET])) {
-			error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 8, ch->name);
-			ch->straight8 = 1;
-		} else {
-			if (ch->io_ports[IDE_DATA_OFFSET])
-				error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_ERROR_OFFSET])
-				error += !request_region(ch->io_ports[IDE_ERROR_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_NSECTOR_OFFSET])
-				error += !request_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_SECTOR_OFFSET])
-				error += !request_region(ch->io_ports[IDE_SECTOR_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_LCYL_OFFSET])
-				error += !request_region(ch->io_ports[IDE_LCYL_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_HCYL_OFFSET])
-				error += !request_region(ch->io_ports[IDE_HCYL_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_SELECT_OFFSET])
-				error += !request_region(ch->io_ports[IDE_SELECT_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_STATUS_OFFSET])
-				error += !request_region(ch->io_ports[IDE_STATUS_OFFSET], 1, ch->name);
+	error = 0;
 
-		}
-		if (ch->io_ports[IDE_CONTROL_OFFSET])
-			error += !request_region(ch->io_ports[IDE_CONTROL_OFFSET], 1, ch->name);
+	if (((unsigned long)ch->io_ports[IDE_DATA_OFFSET] | 7) ==
+			((unsigned long)ch->io_ports[IDE_STATUS_OFFSET])) {
+		error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 8, ch->name);
+		ch->straight8 = 1;
+	} else {
+		if (ch->io_ports[IDE_DATA_OFFSET])
+			error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_ERROR_OFFSET])
+			error += !request_region(ch->io_ports[IDE_ERROR_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_NSECTOR_OFFSET])
+			error += !request_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_SECTOR_OFFSET])
+			error += !request_region(ch->io_ports[IDE_SECTOR_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_LCYL_OFFSET])
+			error += !request_region(ch->io_ports[IDE_LCYL_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_HCYL_OFFSET])
+			error += !request_region(ch->io_ports[IDE_HCYL_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_SELECT_OFFSET])
+			error += !request_region(ch->io_ports[IDE_SELECT_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_STATUS_OFFSET])
+			error += !request_region(ch->io_ports[IDE_STATUS_OFFSET], 1, ch->name);
+
+	}
+	if (ch->io_ports[IDE_CONTROL_OFFSET])
+		error += !request_region(ch->io_ports[IDE_CONTROL_OFFSET], 1, ch->name);
 #if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
-		if (ch->io_ports[IDE_IRQ_OFFSET])
-			error += !request_region(ch->io_ports[IDE_IRQ_OFFSET], 1, ch->name);
+	if (ch->io_ports[IDE_IRQ_OFFSET])
+		error += !request_region(ch->io_ports[IDE_IRQ_OFFSET], 1, ch->name);
 #endif
 
-		/* Some neccessary register area was already used. Skip this
-		 * device.
-		 */
-		if (
+	/* Some neccessary register area was already used. Skip this device.
+	 */
+
+	if (
 #if CONFIG_BLK_DEV_PDC4030
-				(ch->chipset != ide_pdc4030 || ch->unit == 0) &&
+			(ch->chipset != ide_pdc4030 || ch->unit == 0) &&
 #endif
-				error) {
-			/* FIXME: We should be dealing properly with partial IO
-			 * region allocations here.
-			 */
-			ch->present = 0;
-			printk("%s: error: ports already in use!\n", ch->name);
+			error) {
 
-		}
+		/* FIXME: We should be dealing properly with partial IO region
+		 * allocations here.
+		 */
+
+		ch->present = 0;
+		printk("%s: error: ports already in use!\n", ch->name);
 	}
 
-	if (ch->present) {
-		/* Register this hardware interface within the global device tree.
-		 */
-		sprintf(ch->dev.bus_id, "%04x", ch->io_ports[IDE_DATA_OFFSET]);
-		sprintf(ch->dev.name, "ide");
-		ch->dev.driver_data = ch;
+	if (!ch->present)
+		goto not_found;
+
+	/* Register this hardware interface within the global device tree.
+	 */
+	sprintf(ch->dev.bus_id, "%04x", ch->io_ports[IDE_DATA_OFFSET]);
+	sprintf(ch->dev.name, "ide");
+	ch->dev.driver_data = ch;
 #ifdef CONFIG_BLK_DEV_IDEPCI
-		if (ch->pci_dev)
-			ch->dev.parent = &ch->pci_dev->dev;
-		else
+	if (ch->pci_dev)
+		ch->dev.parent = &ch->pci_dev->dev;
+	else
 #endif
-			ch->dev.parent = NULL; /* Would like to do = &device_legacy */
+		ch->dev.parent = NULL; /* Would like to do = &device_legacy */
 
-		device_register(&ch->dev);
+	device_register(&ch->dev);
 
-		if (ch->io_ports[IDE_CONTROL_OFFSET] && ch->reset) {
-			unsigned long timeout = jiffies + WAIT_WORSTCASE;
-			byte stat;
-
-			printk("%s: reset\n", ch->name);
-			OUT_BYTE(12, ch->io_ports[IDE_CONTROL_OFFSET]);
-			udelay(10);
-			OUT_BYTE(8, ch->io_ports[IDE_CONTROL_OFFSET]);
-			do {
-				ide_delay_50ms();
-				stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
-			} while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies));
-
-		}
+	if (ch->io_ports[IDE_CONTROL_OFFSET] && ch->reset) {
+		unsigned long timeout = jiffies + WAIT_WORSTCASE;
+		byte stat;
+
+		printk("%s: reset\n", ch->name);
+		OUT_BYTE(12, ch->io_ports[IDE_CONTROL_OFFSET]);
+		udelay(10);
+		OUT_BYTE(8, ch->io_ports[IDE_CONTROL_OFFSET]);
+		do {
+			ide_delay_50ms();
+			stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
+		} while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies));
 	}
 
 	__restore_flags(flags);	/* local CPU only */
@@ -551,16 +553,19 @@
 	/*
 	 * Now setup the PIO transfer modes of the drives on this channel.
 	 */
-	if (ch->present) {
-		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			struct ata_device *drive = &ch->drives[unit];
-
-			if (drive->present && (drive->autotune == 1)) {
-				if (drive->channel->tuneproc)
-					drive->channel->tuneproc(drive, 255);	/* auto-tune PIO mode */
-			}
+	for (unit = 0; unit < MAX_DRIVES; ++unit) {
+		struct ata_device *drive = &ch->drives[unit];
+
+		if (drive->present && (drive->autotune == 1)) {
+			if (drive->channel->tuneproc)
+				drive->channel->tuneproc(drive, 255);	/* auto-tune PIO mode */
 		}
 	}
+
+	return;
+
+not_found:
+	__restore_flags(flags);
 }
 
 /*
@@ -682,12 +687,7 @@
 			spin_unlock_irqrestore(&ide_lock, flags);
 			return 1;
 		}
-		memset(hwgroup, 0, sizeof(ide_hwgroup_t));
-		hwgroup->rq       = NULL;
-		hwgroup->handler  = NULL;
-		hwgroup->drive    = NULL;
-		hwgroup->flags	  = 0;
-
+		memset(hwgroup, 0, sizeof(*hwgroup));
 		init_timer(&hwgroup->timer);
 		hwgroup->timer.function = &ide_timer_expiry;
 		hwgroup->timer.data = (unsigned long) hwgroup;
@@ -716,21 +716,17 @@
 	}
 
 	/*
-	 * Everything is okay.
+	 * Everything is okay. Tag us as member of this hardware group.
 	 */
 	ch->hwgroup = hwgroup;
-
 	for (i = 0; i < MAX_DRIVES; ++i) {
 		struct ata_device *drive = &ch->drives[i];
 
 		if (!drive->present)
 			continue;
 
-		if (!hwgroup->drive)
-			hwgroup->drive = drive;
-
-		drive->next = hwgroup->drive->next;
-		hwgroup->drive->next = drive;
+		if (!hwgroup->XXX_drive)
+			hwgroup->XXX_drive = drive;
 
 		init_device_queue(drive);
 	}
@@ -833,58 +829,65 @@
 	return;
 }
 
-static int hwif_init(struct ata_channel *hwif)
+static void channel_init(struct ata_channel *ch)
 {
-	if (!hwif->present)
-		return 0;
-	if (!hwif->irq) {
-		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET])))
-		{
-			printk("%s: DISABLED, NO IRQ\n", hwif->name);
-			return (hwif->present = 0);
+	if (!ch->present)
+		return;
+
+	/* we set it back to 1 if all is ok below */
+	ch->present = 0;
+
+	if (!ch->irq) {
+		if (!(ch->irq = ide_default_irq(ch->io_ports[IDE_DATA_OFFSET]))) {
+			printk("%s: DISABLED, NO IRQ\n", ch->name);
+
+			return;
 		}
 	}
 #ifdef CONFIG_BLK_DEV_HD
-	if (hwif->irq == HD_IRQ && hwif->io_ports[IDE_DATA_OFFSET] != HD_DATA) {
-		printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", hwif->name);
-		return (hwif->present = 0);
+	if (ch->irq == HD_IRQ && ch->io_ports[IDE_DATA_OFFSET] != HD_DATA) {
+		printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", ch->name);
+
+		return;
 	}
 #endif
 
-	hwif->present = 0; /* we set it back to 1 if all is ok below */
+	if (devfs_register_blkdev (ch->major, ch->name, ide_fops)) {
+		printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", ch->name, ch->major);
 
-	if (devfs_register_blkdev (hwif->major, hwif->name, ide_fops)) {
-		printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major);
-		return (hwif->present = 0);
+		return;
 	}
 
-	if (init_irq(hwif)) {
-		int i = hwif->irq;
+	if (init_irq(ch)) {
+		int irq = ch->irq;
 		/*
-		 *	It failed to initialise. Find the default IRQ for 
-		 *	this port and try that.
+		 * It failed to initialise. Find the default IRQ for
+		 * this port and try that.
 		 */
-		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {
-			printk("%s: Disabled unable to get IRQ %d.\n", hwif->name, i);
-			(void) unregister_blkdev (hwif->major, hwif->name);
-			return (hwif->present = 0);
+		if (!(ch->irq = ide_default_irq(ch->io_ports[IDE_DATA_OFFSET]))) {
+			printk(KERN_INFO "%s: disabled; unable to get IRQ %d.\n", ch->name, irq);
+			(void) unregister_blkdev (ch->major, ch->name);
+
+			return;
 		}
-		if (init_irq(hwif)) {
-			printk("%s: probed IRQ %d and default IRQ %d failed.\n",
-				hwif->name, i, hwif->irq);
-			(void) unregister_blkdev (hwif->major, hwif->name);
-			return (hwif->present = 0);
+		if (init_irq(ch)) {
+			printk(KERN_INFO "%s: probed IRQ %d and default IRQ %d failed.\n",
+				ch->name, irq, ch->irq);
+			(void) unregister_blkdev(ch->major, ch->name);
+
+			return;
 		}
-		printk("%s: probed IRQ %d failed, using default.\n",
-			hwif->name, hwif->irq);
+		printk(KERN_INFO "%s: probed IRQ %d failed, using default.\n", ch->name, ch->irq);
 	}
 
-	init_gendisk(hwif);
-	blk_dev[hwif->major].data = hwif;
-	blk_dev[hwif->major].queue = ide_get_queue;
-	hwif->present = 1;	/* success */
+	init_gendisk(ch);
+	blk_dev[ch->major].data = ch;
+	blk_dev[ch->major].queue = ide_get_queue;
 
-	return hwif->present;
+	/* all went well, flag this channel entry as valid */
+	ch->present = 1;
+
+	return;
 }
 
 int ideprobe_init (void)
@@ -901,9 +904,9 @@
 	 */
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[index])
-			probe_hwif(&ide_hwifs[index]);
+			channel_probe(&ide_hwifs[index]);
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[index])
-			hwif_init(&ide_hwifs[index]);
+			channel_init(&ide_hwifs[index]);
 	return 0;
 }
diff -urN linux-2.5.11/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.11/include/linux/ide.h	2002-04-30 03:48:19.000000000 +0200
+++ linux/include/linux/ide.h	2002-04-30 03:30:21.000000000 +0200
@@ -283,16 +283,10 @@
 	 */
 	request_queue_t	queue;	/* per device request queue */
 
-	struct ata_device	*next;	/* circular list of hwgroup drives */
-
 	/* Those are directly injected jiffie values. They should go away and
 	 * we should use generic timers instead!!!
 	 */
-
-	unsigned long PADAM_sleep;		/* sleep until this time */
-	unsigned long PADAM_service_start;	/* time we started last request */
-	unsigned long PADAM_service_time;	/* service time of last request */
-	unsigned long PADAM_timeout;		/* max time to wait for irq */
+	unsigned long PADAM_sleep;	/* sleep until this time */
 
 	/* Flags requesting/indicating one of the following special commands
 	 * executed on the request queue.
@@ -512,7 +506,7 @@
 typedef struct hwgroup_s {
 	ide_startstop_t (*handler)(struct ata_device *, struct request *);	/* irq handler, if active */
 	unsigned long flags;		/* BUSY, SLEEPING */
-	struct ata_device *drive;	/* current drive */
+	struct ata_device *XXX_drive;	/* current drive */
 	struct request *rq;		/* current request */
 	struct timer_list timer;	/* failsafe timer */
 	unsigned long poll_timeout;	/* timeout value during long polls */

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

* [PATCH] 2.5.11 IDE 47
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (11 preceding siblings ...)
  2002-04-30  8:11 ` Linux 2.5.7 Martin Dalecki
@ 2002-04-30  8:45 ` Martin Dalecki
  2002-04-30 15:16 ` [PATCH] 2.5.11 IDE 48 Martin Dalecki
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-04-30  8:45 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List, axboe

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

- Rewrite choose_drive() to iterate explicitely over the channels and devices
    on them. It is not performance critical to iterate over this typically quite
    small array of disks and allows us to let them act on the natural entity,
    namely the channel as well as to remove the drive->next field from struct
    ata_device.  Make the device eviction code in ide_do_request() more
    intelliglible.  Add some comments explaining the reasoning behind the code
    there.

- Now finally since the code for choosing the drive which will be serviced next
    is intelliglibly it became obvious that the attempt to choose the next drive
    based on the duration of the last request was entierly bogous. (Because for
    example wakeups can take a long time, but this doesn't indicate that the
    drive is slow.) Remove this criterium and the corresponding accounting
    therefore. Threat all drives fairly right now.

Surprise surprise the overall system throughput increased :-).

ps. (just corrected the subject line...)

[-- Attachment #2: ide-clean-47.diff --]
[-- Type: text/plain, Size: 28751 bytes --]

diff -urN linux-2.5.11/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.11/drivers/ide/ide.c	2002-04-30 03:48:19.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-04-30 03:41:06.000000000 +0200
@@ -285,7 +285,7 @@
 	hwif->bus_state = BUSSTATE_ON;
 
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		ide_drive_t *drive = &hwif->drives[unit];
+		struct ata_device *drive = &hwif->drives[unit];
 
 		drive->type			= ATA_DISK;
 		drive->select.all		= (unit<<4)|0xa0;
@@ -507,19 +507,21 @@
 /*
  * This is called exactly *once* for each channel.
  */
-void ide_geninit(struct ata_channel *hwif)
+void ide_geninit(struct ata_channel *ch)
 {
 	unsigned int unit;
-	struct gendisk *gd = hwif->gd;
+	struct gendisk *gd = ch->gd;
 
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		ide_drive_t *drive = &hwif->drives[unit];
+		struct ata_device *drive = &ch->drives[unit];
 
 		if (!drive->present)
 			continue;
+
 		if (drive->type != ATA_DISK && drive->type != ATA_FLOPPY)
 			continue;
-		register_disk(gd,mk_kdev(hwif->major,unit<<PARTN_BITS),
+
+		register_disk(gd,mk_kdev(ch->major,unit<<PARTN_BITS),
 #ifdef CONFIG_BLK_DEV_ISAPNP
 			(drive->forced_geom && drive->noprobe) ? 1 :
 #endif
@@ -1189,30 +1191,89 @@
 }
 
 /*
- * Select the next drive which will be serviced.
+ * Select the next device which will be serviced.
  */
-static struct ata_device *choose_drive(struct ata_device *cur)
+static struct ata_device *choose_urgent_device(struct ata_channel *channel)
 {
-	struct ata_device *drive = cur;
 	struct ata_device *best = NULL;
+	int i;
 
-	do {
-		if (!list_empty(&drive->queue.queue_head)
-		&& (!drive->PADAM_sleep	|| time_after_eq(drive->PADAM_sleep, jiffies))) {
-			if (!best
-			 || (drive->PADAM_sleep && (!best->PADAM_sleep || time_after(best->PADAM_sleep, drive->PADAM_sleep)))
-			 || (!best->PADAM_sleep && time_after(best->PADAM_service_start + 2 * best->PADAM_service_time, drive->PADAM_service_start + 2 * drive->PADAM_service_time)))
+	for (i = 0; i < MAX_HWIFS; ++i) {
+		int unit;
+		struct ata_channel *ch = &ide_hwifs[i];
+
+		if (!ch->present)
+			continue;
+
+		if (ch->hwgroup != channel->hwgroup)
+			continue;
+
+		for (unit = 0; unit < MAX_DRIVES; ++unit) {
+			struct ata_device *drive = &ch->drives[unit];
+
+			if (!drive->present)
+				continue;
+
+			/* There are no request pending for this device.
+			 */
+			if (list_empty(&drive->queue.queue_head))
+				continue;
+
+			/* This device still want's to remain idle.
+			 */
+			if (drive->PADAM_sleep && time_after(jiffies, drive->PADAM_sleep))
+				continue;
+
+			/* Take this device, if there is no device choosen thus far or
+			 * it's more urgent.
+			 */
+			if (!best || (drive->PADAM_sleep && (!best->PADAM_sleep || time_after(best->PADAM_sleep, drive->PADAM_sleep))))
 			{
 				if (!blk_queue_plugged(&drive->queue))
 					best = drive;
 			}
 		}
-		drive = drive->next;
-	} while (drive != cur);
+	}
+
 	return best;
 }
 
 /*
+ * Determine the longes sleep time for the devices in our hwgroup.
+ */
+static unsigned long longest_sleep(struct ata_channel *channel)
+{
+	unsigned long sleep = 0;
+	int i;
+
+	for (i = 0; i < MAX_HWIFS; ++i) {
+		int unit;
+		struct ata_channel *ch = &ide_hwifs[i];
+
+		if (!ch->present)
+			continue;
+
+		if (ch->hwgroup != channel->hwgroup)
+			continue;
+
+		for (unit = 0; unit < MAX_DRIVES; ++unit) {
+			struct ata_device *drive = &ch->drives[unit];
+
+			if (!drive->present)
+				continue;
+
+			/* This device is sleeping and waiting to be serviced
+			 * later than any other device we checked thus far.
+			 */
+			if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
+				sleep = drive->PADAM_sleep;
+		}
+	}
+
+	return sleep;
+}
+
+/*
  * Issue a new request to a drive from hwgroup.
  * Caller must have already done spin_lock_irqsave(&ide_lock, ...)
  *
@@ -1242,42 +1303,33 @@
  * will start the next request from the queue.  If no more work remains,
  * the driver will clear the hwgroup->flags IDE_BUSY flag and exit.
  */
-static void ide_do_request(struct ata_channel *ch, int masked_irq)
+static void ide_do_request(struct ata_channel *channel, int masked_irq)
 {
-	ide_hwgroup_t *hwgroup = ch->hwgroup;
-	struct ata_device *drive;
-	ide_startstop_t	startstop;
-	struct request	*rq;
-
+	ide_hwgroup_t *hwgroup = channel->hwgroup;
 	ide_get_lock(&irq_lock, ata_irq_request, hwgroup);/* for atari only: POSSIBLY BROKEN HERE(?) */
 
 	__cli();	/* necessary paranoia: ensure IRQs are masked on local CPU */
 
 	while (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) {
-		drive = choose_drive(hwgroup->drive);
+		struct ata_channel *ch;
+		ide_startstop_t	startstop;
+		struct ata_device *drive = choose_urgent_device(channel);
 
 		if (drive == NULL) {
 			unsigned long sleep = 0;
 
 			hwgroup->rq = NULL;
-
-			drive = hwgroup->drive;
-			do {
-				if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
-					sleep = drive->PADAM_sleep;
-
-				drive = drive->next;
-			} while (drive!= hwgroup->drive);
+			sleep = longest_sleep(channel);
 
 			if (sleep) {
+
 				/*
-				 * Take a short snooze, and then wake up this
-				 * hwgroup again.  This gives other hwgroups on
-				 * the same a chance to play fairly with us,
-				 * just in case there are big differences in
+				 * Take a short snooze, and then wake up again.
+				 * Just in case there are big differences in
 				 * relative throughputs.. don't want to hog the
 				 * cpu too much.
 				 */
+
 				if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep))
 					sleep = jiffies + WAIT_MIN_SLEEP;
 #if 1
@@ -1293,29 +1345,35 @@
 				ide_release_lock(&irq_lock);/* for atari only */
 				clear_bit(IDE_BUSY, &hwgroup->flags);
 			}
-			return;		/* no more work for this hwgroup (for now) */
+
+			return;
 		}
 		ch = drive->channel;
 
-		if (hwgroup->drive->channel->sharing_irq && ch != hwgroup->drive->channel && ch->io_ports[IDE_CONTROL_OFFSET]) {
+		if (hwgroup->XXX_drive->channel->sharing_irq && ch != hwgroup->XXX_drive->channel && ch->io_ports[IDE_CONTROL_OFFSET]) {
 			/* set nIEN for previous channel */
+			/* FIXME: check this! It appears to act on the current channel! */
 
 			if (ch->intrproc)
 				ch->intrproc(drive);
 			else
 				OUT_BYTE((drive)->ctl|2, ch->io_ports[IDE_CONTROL_OFFSET]);
 		}
-		hwgroup->drive = drive;
+
+		/* Remember the last drive we where acting on.
+		 */
+		hwgroup->XXX_drive = drive;
+
+		/* Reset wait timeout.
+		 */
 		drive->PADAM_sleep = 0;
-		drive->PADAM_service_start = jiffies;
 
 		if (blk_queue_plugged(&drive->queue))
 			BUG();
 
-		/*
-		 * just continuing an interrupted request maybe
+		/* Just continuing an interrupted request maybe.
 		 */
-		rq = hwgroup->rq = elv_next_request(&drive->queue);
+		hwgroup->rq = elv_next_request(&drive->queue);
 
 		/*
 		 * Some systems have trouble with IDE IRQs arriving while the
@@ -1331,7 +1389,7 @@
 			disable_irq_nosync(ch->irq);
 		spin_unlock(&ide_lock);
 		ide__sti();	/* allow other IRQs while we start this request */
-		startstop = start_request(drive, rq);
+		startstop = start_request(drive, hwgroup->rq);
 		spin_lock_irq(&ide_lock);
 		if (masked_irq && ch->irq != masked_irq)
 			enable_irq(ch->irq);
@@ -1432,7 +1490,7 @@
 		if (test_and_clear_bit(IDE_SLEEP, &hwgroup->flags))
 			clear_bit(IDE_BUSY, &hwgroup->flags);
 	} else {
-		struct ata_device *drive = hwgroup->drive;
+		struct ata_device *drive = hwgroup->XXX_drive;
 		if (!drive) {
 			printk("ide_timer_expiry: hwgroup->drive was NULL\n");
 			hwgroup->handler = NULL;
@@ -1483,7 +1541,6 @@
 					startstop = ide_error(drive, "irq timeout", GET_STAT());
 			}
 			set_recovery_timer(ch);
-			drive->PADAM_service_time = jiffies - drive->PADAM_service_start;
 			enable_irq(ch->irq);
 			spin_lock_irq(&ide_lock);
 			if (startstop == ide_stopped)
@@ -1491,7 +1548,7 @@
 		}
 	}
 
-	ide_do_request(hwgroup->drive->channel, 0);
+	ide_do_request(hwgroup->XXX_drive->channel, 0);
 
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
@@ -1525,15 +1582,15 @@
 
 	for (i = 0; i < MAX_HWIFS; ++i) {
 		u8 stat;
-		struct ata_channel *tmp = &ide_hwifs[i];
+		struct ata_channel *ch = &ide_hwifs[i];
 
-		if (!tmp->present)
+		if (!ch->present)
 			continue;
 
-		if (tmp->irq != irq)
+		if (ch->irq != irq)
 			continue;
 
-		stat = IN_BYTE(tmp->io_ports[IDE_STATUS_OFFSET]);
+		stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
 		if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
 			/* Try to not flood the console with msgs */
 			static unsigned long last_msgtime;
@@ -1543,7 +1600,7 @@
 			if (time_after(jiffies, last_msgtime + HZ)) {
 				last_msgtime = jiffies;
 				printk("%s: unexpected interrupt, status=0x%02x, count=%d\n",
-						tmp->name, stat, count);
+						ch->name, stat, count);
 			}
 		}
 	}
@@ -1601,14 +1658,7 @@
 		}
 		goto out_lock;
 	}
-	drive = hwgroup->drive;
-	if (!drive) {
-		/*
-		 * This should NEVER happen, and there isn't much we could do
-		 * about it here.
-		 */
-		goto out_lock;
-	}
+	drive = hwgroup->XXX_drive;
 	if (!drive_is_ready(drive)) {
 		/*
 		 * This happens regularly when we share a PCI IRQ with another device.
@@ -1640,7 +1690,6 @@
 	 * won't allow another of the same (on any CPU) until we return.
 	 */
 	set_recovery_timer(drive->channel);
-	drive->PADAM_service_time = jiffies - drive->PADAM_service_start;
 	if (startstop == ide_stopped) {
 		if (hwgroup->handler == NULL) {	/* paranoia */
 			clear_bit(IDE_BUSY, &hwgroup->flags);
@@ -1668,7 +1717,7 @@
 		if (hwif->present && major == hwif->major) {
 			int unit = DEVICE_NR(i_rdev);
 			if (unit < MAX_DRIVES) {
-				ide_drive_t *drive = &hwif->drives[unit];
+				struct ata_device *drive = &hwif->drives[unit];
 				if (drive->present)
 					return drive;
 			}
@@ -1800,46 +1849,44 @@
  */
 void revalidate_drives(void)
 {
-	struct ata_channel *hwif;
-	ide_drive_t *drive;
-	int h;
+	int i;
 
-	for (h = 0; h < MAX_HWIFS; ++h) {
+	for (i = 0; i < MAX_HWIFS; ++i) {
 		int unit;
-		hwif = &ide_hwifs[h];
+		struct ata_channel *ch = &ide_hwifs[i];
+
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			drive = &ide_hwifs[h].drives[unit];
+			struct ata_device *drive = &ch->drives[unit];
+
 			if (drive->revalidate) {
 				drive->revalidate = 0;
 				if (!initializing)
-					ide_revalidate_disk(mk_kdev(hwif->major, unit<<PARTN_BITS));
+					ide_revalidate_disk(mk_kdev(ch->major, unit<<PARTN_BITS));
 			}
 		}
 	}
 }
 
-static void ide_probe_module(void)
-{
-	ideprobe_init();
-	revalidate_drives();
-}
-
 static void ide_driver_module (void)
 {
-	int index;
+	int i;
+
+	/* Don't reinit the probe if there is already one channel detected. */
 
-	for (index = 0; index < MAX_HWIFS; ++index)
-		if (ide_hwifs[index].present)
-			goto search;
-	ide_probe_module();
-search:
+	for (i = 0; i < MAX_HWIFS; ++i) {
+		if (ide_hwifs[i].present)
+			goto revalidate;
+	}
 
+	ideprobe_init();
+
+revalidate:
 	revalidate_drives();
 }
 
 static int ide_open(struct inode * inode, struct file * filp)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 
 	if ((drive = get_info_ptr(inode->i_rdev)) == NULL)
 		return -ENXIO;
@@ -1901,7 +1948,7 @@
  */
 static int ide_release(struct inode * inode, struct file * file)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 
 	if (!(drive = get_info_ptr(inode->i_rdev)))
 		return 0;
@@ -1977,7 +2024,7 @@
 void ide_unregister(struct ata_channel *ch)
 {
 	struct gendisk *gd;
-	ide_drive_t *drive, *d;
+	struct ata_device *d;
 	ide_hwgroup_t *hwgroup;
 	int unit, i;
 	unsigned long flags;
@@ -1986,15 +2033,20 @@
 	int n = 0;
 
 	spin_lock_irqsave(&ide_lock, flags);
+
 	if (!ch->present)
 		goto abort;
+
 	put_device(&ch->dev);
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		drive = &ch->drives[unit];
+		struct ata_device * drive = &ch->drives[unit];
+
 		if (!drive->present)
 			continue;
+
 		if (drive->busy || drive->usage)
 			goto abort;
+
 		if (ata_ops(drive)) {
 			if (ata_ops(drive)->cleanup) {
 				if (ata_ops(drive)->cleanup(drive))
@@ -2010,9 +2062,11 @@
 	 */
 	spin_unlock_irqrestore(&ide_lock, flags);
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		drive = &ch->drives[unit];
+		struct ata_device * drive = &ch->drives[unit];
+
 		if (!drive->present)
 			continue;
+
 		minor = drive->select.b.unit << PARTN_BITS;
 		for (p = 0; p < (1<<PARTN_BITS); ++p) {
 			if (drive->part[p].nr_sects > 0) {
@@ -2029,25 +2083,24 @@
 	hwif_unregister(ch);
 
 	/*
-	 * Remove us from the hwgroup, and free the hwgroup if we were the only
-	 * member.
+	 * Remove us from the hwgroup
 	 */
 
 	hwgroup = ch->hwgroup;
-	d = hwgroup->drive;
+	d = hwgroup->XXX_drive;
 	for (i = 0; i < MAX_DRIVES; ++i) {
-		drive = &ch->drives[i];
+		struct ata_device *drive = &ch->drives[i];
+
 		if (drive->de) {
 			devfs_unregister (drive->de);
 			drive->de = NULL;
 		}
 		if (!drive->present)
 			continue;
-		while (hwgroup->drive->next != drive)
-			hwgroup->drive = hwgroup->drive->next;
-		hwgroup->drive->next = drive->next;
-		if (hwgroup->drive == drive)
-			hwgroup->drive = NULL;
+
+		if (hwgroup->XXX_drive == drive)
+			hwgroup->XXX_drive = NULL;
+
 		if (drive->id != NULL) {
 			kfree(drive->id);
 			drive->id = NULL;
@@ -2056,8 +2109,10 @@
 		blk_cleanup_queue(&drive->queue);
 	}
 	if (d->present)
-		hwgroup->drive = d;
+		hwgroup->XXX_drive = d;
 
+	/* Free the hwgroup if we were the only member.
+	 */
 	n = 0;
 	for (i = 0; i < MAX_HWIFS; ++i) {
 		struct ata_channel *tmp = &ide_hwifs[i];
@@ -2215,10 +2270,12 @@
 	hwif->chipset = hw->chipset;
 
 	if (!initializing) {
-		ide_probe_module();
+		ideprobe_init();
+		revalidate_drives();
 #ifdef CONFIG_PROC_FS
 		create_proc_ide_interfaces();
 #endif
+		/* FIXME: Do we really have to call it second time here?! */
 		ide_driver_module();
 	}
 
@@ -3121,25 +3178,29 @@
 }
 
 /*
- * Lookup IDE devices, which requested a particular driver
+ * Lookup ATA devices, which requested a particular driver.
  */
 ide_drive_t *ide_scan_devices(byte type, const char *name, struct ata_operations *driver, int n)
 {
 	unsigned int unit, index, i;
 
 	for (index = 0, i = 0; index < MAX_HWIFS; ++index) {
-		struct ata_channel *hwif = &ide_hwifs[index];
-		if (!hwif->present)
+		struct ata_channel *ch = &ide_hwifs[index];
+
+		if (!ch->present)
 			continue;
+
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			ide_drive_t *drive = &hwif->drives[unit];
+			struct ata_device *drive = &ch->drives[unit];
 			char *req = drive->driver_req;
+
 			if (*req && !strstr(name, req))
 				continue;
 			if (drive->present && drive->type == type && drive->driver == driver && ++i > n)
 				return drive;
 		}
 	}
+
 	return NULL;
 }
 
@@ -3179,9 +3240,21 @@
 			drive->channel->udma(ide_dma_off_quietly, drive, NULL);
 			drive->channel->udma(ide_dma_check, drive, NULL);
 		}
-		/* Only CD-ROMs and tape drives support DSC overlap. */
-		drive->dsc_overlap = (drive->next != drive
-				&& (drive->type == ATA_ROM || drive->type == ATA_TAPE));
+
+		/* Only CD-ROMs and tape drives support DSC overlap.  But only
+		 * if they are alone on a channel. */
+		if (drive->type == ATA_ROM || drive->type == ATA_TAPE) {
+			int single = 0;
+			int unit;
+
+			for (unit = 0; unit < MAX_DRIVES; ++unit)
+				if (drive->channel->drives[unit].present)
+					++single;
+
+			drive->dsc_overlap = (single == 1);
+		} else
+			drive->dsc_overlap = 0;
+
 	}
 	drive->revalidate = 1;
 	drive->suspend_reset = 0;
@@ -3319,9 +3392,7 @@
 
 static int ide_notify_reboot (struct notifier_block *this, unsigned long event, void *x)
 {
-	struct ata_channel *hwif;
-	ide_drive_t *drive;
-	int i, unit;
+	int i;
 
 	switch (event) {
 		case SYS_HALT:
@@ -3335,12 +3406,15 @@
 	printk("flushing ide devices: ");
 
 	for (i = 0; i < MAX_HWIFS; i++) {
-		hwif = &ide_hwifs[i];
-		if (!hwif->present)
+		int unit;
+		struct ata_channel *ch = &ide_hwifs[i];
+
+		if (!ch->present)
 			continue;
 
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			drive = &hwif->drives[unit];
+			struct ata_device *drive = &ch->drives[unit];
+
 			if (!drive->present)
 				continue;
 
diff -urN linux-2.5.11/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.11/drivers/ide/ide-probe.c	2002-04-29 05:11:17.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-04-30 03:30:13.000000000 +0200
@@ -438,10 +438,11 @@
  * This routine only knows how to look for drive units 0 and 1
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
-static void probe_hwif(struct ata_channel *ch)
+static void channel_probe(struct ata_channel *ch)
 {
 	unsigned int unit;
 	unsigned long flags;
+	int error;
 
 	if (ch->noprobe)
 		return;
@@ -454,96 +455,97 @@
 	/*
 	 * Check for the presence of a channel by probing for drives on it.
 	 */
-
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		struct ata_device *drive = &ch->drives[unit];
 
 		probe_for_drive(drive);
 
-		if (drive->present && !ch->present) {
+		/* drive found, there is a channel it is attached too. */
+		if (drive->present)
 			ch->present = 1;
-		}
 	}
 
-	if (ch->present) {
-		int error = 0;
+	if (!ch->present)
+		goto not_found;
 
-		if (((unsigned long)ch->io_ports[IDE_DATA_OFFSET] | 7) ==
-				((unsigned long)ch->io_ports[IDE_STATUS_OFFSET])) {
-			error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 8, ch->name);
-			ch->straight8 = 1;
-		} else {
-			if (ch->io_ports[IDE_DATA_OFFSET])
-				error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_ERROR_OFFSET])
-				error += !request_region(ch->io_ports[IDE_ERROR_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_NSECTOR_OFFSET])
-				error += !request_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_SECTOR_OFFSET])
-				error += !request_region(ch->io_ports[IDE_SECTOR_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_LCYL_OFFSET])
-				error += !request_region(ch->io_ports[IDE_LCYL_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_HCYL_OFFSET])
-				error += !request_region(ch->io_ports[IDE_HCYL_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_SELECT_OFFSET])
-				error += !request_region(ch->io_ports[IDE_SELECT_OFFSET], 1, ch->name);
-			if (ch->io_ports[IDE_STATUS_OFFSET])
-				error += !request_region(ch->io_ports[IDE_STATUS_OFFSET], 1, ch->name);
+	error = 0;
 
-		}
-		if (ch->io_ports[IDE_CONTROL_OFFSET])
-			error += !request_region(ch->io_ports[IDE_CONTROL_OFFSET], 1, ch->name);
+	if (((unsigned long)ch->io_ports[IDE_DATA_OFFSET] | 7) ==
+			((unsigned long)ch->io_ports[IDE_STATUS_OFFSET])) {
+		error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 8, ch->name);
+		ch->straight8 = 1;
+	} else {
+		if (ch->io_ports[IDE_DATA_OFFSET])
+			error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_ERROR_OFFSET])
+			error += !request_region(ch->io_ports[IDE_ERROR_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_NSECTOR_OFFSET])
+			error += !request_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_SECTOR_OFFSET])
+			error += !request_region(ch->io_ports[IDE_SECTOR_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_LCYL_OFFSET])
+			error += !request_region(ch->io_ports[IDE_LCYL_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_HCYL_OFFSET])
+			error += !request_region(ch->io_ports[IDE_HCYL_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_SELECT_OFFSET])
+			error += !request_region(ch->io_ports[IDE_SELECT_OFFSET], 1, ch->name);
+		if (ch->io_ports[IDE_STATUS_OFFSET])
+			error += !request_region(ch->io_ports[IDE_STATUS_OFFSET], 1, ch->name);
+
+	}
+	if (ch->io_ports[IDE_CONTROL_OFFSET])
+		error += !request_region(ch->io_ports[IDE_CONTROL_OFFSET], 1, ch->name);
 #if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
-		if (ch->io_ports[IDE_IRQ_OFFSET])
-			error += !request_region(ch->io_ports[IDE_IRQ_OFFSET], 1, ch->name);
+	if (ch->io_ports[IDE_IRQ_OFFSET])
+		error += !request_region(ch->io_ports[IDE_IRQ_OFFSET], 1, ch->name);
 #endif
 
-		/* Some neccessary register area was already used. Skip this
-		 * device.
-		 */
-		if (
+	/* Some neccessary register area was already used. Skip this device.
+	 */
+
+	if (
 #if CONFIG_BLK_DEV_PDC4030
-				(ch->chipset != ide_pdc4030 || ch->unit == 0) &&
+			(ch->chipset != ide_pdc4030 || ch->unit == 0) &&
 #endif
-				error) {
-			/* FIXME: We should be dealing properly with partial IO
-			 * region allocations here.
-			 */
-			ch->present = 0;
-			printk("%s: error: ports already in use!\n", ch->name);
+			error) {
 
-		}
+		/* FIXME: We should be dealing properly with partial IO region
+		 * allocations here.
+		 */
+
+		ch->present = 0;
+		printk("%s: error: ports already in use!\n", ch->name);
 	}
 
-	if (ch->present) {
-		/* Register this hardware interface within the global device tree.
-		 */
-		sprintf(ch->dev.bus_id, "%04x", ch->io_ports[IDE_DATA_OFFSET]);
-		sprintf(ch->dev.name, "ide");
-		ch->dev.driver_data = ch;
+	if (!ch->present)
+		goto not_found;
+
+	/* Register this hardware interface within the global device tree.
+	 */
+	sprintf(ch->dev.bus_id, "%04x", ch->io_ports[IDE_DATA_OFFSET]);
+	sprintf(ch->dev.name, "ide");
+	ch->dev.driver_data = ch;
 #ifdef CONFIG_BLK_DEV_IDEPCI
-		if (ch->pci_dev)
-			ch->dev.parent = &ch->pci_dev->dev;
-		else
+	if (ch->pci_dev)
+		ch->dev.parent = &ch->pci_dev->dev;
+	else
 #endif
-			ch->dev.parent = NULL; /* Would like to do = &device_legacy */
+		ch->dev.parent = NULL; /* Would like to do = &device_legacy */
 
-		device_register(&ch->dev);
+	device_register(&ch->dev);
 
-		if (ch->io_ports[IDE_CONTROL_OFFSET] && ch->reset) {
-			unsigned long timeout = jiffies + WAIT_WORSTCASE;
-			byte stat;
-
-			printk("%s: reset\n", ch->name);
-			OUT_BYTE(12, ch->io_ports[IDE_CONTROL_OFFSET]);
-			udelay(10);
-			OUT_BYTE(8, ch->io_ports[IDE_CONTROL_OFFSET]);
-			do {
-				ide_delay_50ms();
-				stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
-			} while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies));
-
-		}
+	if (ch->io_ports[IDE_CONTROL_OFFSET] && ch->reset) {
+		unsigned long timeout = jiffies + WAIT_WORSTCASE;
+		byte stat;
+
+		printk("%s: reset\n", ch->name);
+		OUT_BYTE(12, ch->io_ports[IDE_CONTROL_OFFSET]);
+		udelay(10);
+		OUT_BYTE(8, ch->io_ports[IDE_CONTROL_OFFSET]);
+		do {
+			ide_delay_50ms();
+			stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
+		} while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies));
 	}
 
 	__restore_flags(flags);	/* local CPU only */
@@ -551,16 +553,19 @@
 	/*
 	 * Now setup the PIO transfer modes of the drives on this channel.
 	 */
-	if (ch->present) {
-		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			struct ata_device *drive = &ch->drives[unit];
-
-			if (drive->present && (drive->autotune == 1)) {
-				if (drive->channel->tuneproc)
-					drive->channel->tuneproc(drive, 255);	/* auto-tune PIO mode */
-			}
+	for (unit = 0; unit < MAX_DRIVES; ++unit) {
+		struct ata_device *drive = &ch->drives[unit];
+
+		if (drive->present && (drive->autotune == 1)) {
+			if (drive->channel->tuneproc)
+				drive->channel->tuneproc(drive, 255);	/* auto-tune PIO mode */
 		}
 	}
+
+	return;
+
+not_found:
+	__restore_flags(flags);
 }
 
 /*
@@ -682,12 +687,7 @@
 			spin_unlock_irqrestore(&ide_lock, flags);
 			return 1;
 		}
-		memset(hwgroup, 0, sizeof(ide_hwgroup_t));
-		hwgroup->rq       = NULL;
-		hwgroup->handler  = NULL;
-		hwgroup->drive    = NULL;
-		hwgroup->flags	  = 0;
-
+		memset(hwgroup, 0, sizeof(*hwgroup));
 		init_timer(&hwgroup->timer);
 		hwgroup->timer.function = &ide_timer_expiry;
 		hwgroup->timer.data = (unsigned long) hwgroup;
@@ -716,21 +716,17 @@
 	}
 
 	/*
-	 * Everything is okay.
+	 * Everything is okay. Tag us as member of this hardware group.
 	 */
 	ch->hwgroup = hwgroup;
-
 	for (i = 0; i < MAX_DRIVES; ++i) {
 		struct ata_device *drive = &ch->drives[i];
 
 		if (!drive->present)
 			continue;
 
-		if (!hwgroup->drive)
-			hwgroup->drive = drive;
-
-		drive->next = hwgroup->drive->next;
-		hwgroup->drive->next = drive;
+		if (!hwgroup->XXX_drive)
+			hwgroup->XXX_drive = drive;
 
 		init_device_queue(drive);
 	}
@@ -833,58 +829,65 @@
 	return;
 }
 
-static int hwif_init(struct ata_channel *hwif)
+static void channel_init(struct ata_channel *ch)
 {
-	if (!hwif->present)
-		return 0;
-	if (!hwif->irq) {
-		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET])))
-		{
-			printk("%s: DISABLED, NO IRQ\n", hwif->name);
-			return (hwif->present = 0);
+	if (!ch->present)
+		return;
+
+	/* we set it back to 1 if all is ok below */
+	ch->present = 0;
+
+	if (!ch->irq) {
+		if (!(ch->irq = ide_default_irq(ch->io_ports[IDE_DATA_OFFSET]))) {
+			printk("%s: DISABLED, NO IRQ\n", ch->name);
+
+			return;
 		}
 	}
 #ifdef CONFIG_BLK_DEV_HD
-	if (hwif->irq == HD_IRQ && hwif->io_ports[IDE_DATA_OFFSET] != HD_DATA) {
-		printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", hwif->name);
-		return (hwif->present = 0);
+	if (ch->irq == HD_IRQ && ch->io_ports[IDE_DATA_OFFSET] != HD_DATA) {
+		printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", ch->name);
+
+		return;
 	}
 #endif
 
-	hwif->present = 0; /* we set it back to 1 if all is ok below */
+	if (devfs_register_blkdev (ch->major, ch->name, ide_fops)) {
+		printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", ch->name, ch->major);
 
-	if (devfs_register_blkdev (hwif->major, hwif->name, ide_fops)) {
-		printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major);
-		return (hwif->present = 0);
+		return;
 	}
 
-	if (init_irq(hwif)) {
-		int i = hwif->irq;
+	if (init_irq(ch)) {
+		int irq = ch->irq;
 		/*
-		 *	It failed to initialise. Find the default IRQ for 
-		 *	this port and try that.
+		 * It failed to initialise. Find the default IRQ for
+		 * this port and try that.
 		 */
-		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {
-			printk("%s: Disabled unable to get IRQ %d.\n", hwif->name, i);
-			(void) unregister_blkdev (hwif->major, hwif->name);
-			return (hwif->present = 0);
+		if (!(ch->irq = ide_default_irq(ch->io_ports[IDE_DATA_OFFSET]))) {
+			printk(KERN_INFO "%s: disabled; unable to get IRQ %d.\n", ch->name, irq);
+			(void) unregister_blkdev (ch->major, ch->name);
+
+			return;
 		}
-		if (init_irq(hwif)) {
-			printk("%s: probed IRQ %d and default IRQ %d failed.\n",
-				hwif->name, i, hwif->irq);
-			(void) unregister_blkdev (hwif->major, hwif->name);
-			return (hwif->present = 0);
+		if (init_irq(ch)) {
+			printk(KERN_INFO "%s: probed IRQ %d and default IRQ %d failed.\n",
+				ch->name, irq, ch->irq);
+			(void) unregister_blkdev(ch->major, ch->name);
+
+			return;
 		}
-		printk("%s: probed IRQ %d failed, using default.\n",
-			hwif->name, hwif->irq);
+		printk(KERN_INFO "%s: probed IRQ %d failed, using default.\n", ch->name, ch->irq);
 	}
 
-	init_gendisk(hwif);
-	blk_dev[hwif->major].data = hwif;
-	blk_dev[hwif->major].queue = ide_get_queue;
-	hwif->present = 1;	/* success */
+	init_gendisk(ch);
+	blk_dev[ch->major].data = ch;
+	blk_dev[ch->major].queue = ide_get_queue;
 
-	return hwif->present;
+	/* all went well, flag this channel entry as valid */
+	ch->present = 1;
+
+	return;
 }
 
 int ideprobe_init (void)
@@ -901,9 +904,9 @@
 	 */
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[index])
-			probe_hwif(&ide_hwifs[index]);
+			channel_probe(&ide_hwifs[index]);
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[index])
-			hwif_init(&ide_hwifs[index]);
+			channel_init(&ide_hwifs[index]);
 	return 0;
 }
diff -urN linux-2.5.11/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.11/include/linux/ide.h	2002-04-30 03:48:19.000000000 +0200
+++ linux/include/linux/ide.h	2002-04-30 03:30:21.000000000 +0200
@@ -283,16 +283,10 @@
 	 */
 	request_queue_t	queue;	/* per device request queue */
 
-	struct ata_device	*next;	/* circular list of hwgroup drives */
-
 	/* Those are directly injected jiffie values. They should go away and
 	 * we should use generic timers instead!!!
 	 */
-
-	unsigned long PADAM_sleep;		/* sleep until this time */
-	unsigned long PADAM_service_start;	/* time we started last request */
-	unsigned long PADAM_service_time;	/* service time of last request */
-	unsigned long PADAM_timeout;		/* max time to wait for irq */
+	unsigned long PADAM_sleep;	/* sleep until this time */
 
 	/* Flags requesting/indicating one of the following special commands
 	 * executed on the request queue.
@@ -512,7 +506,7 @@
 typedef struct hwgroup_s {
 	ide_startstop_t (*handler)(struct ata_device *, struct request *);	/* irq handler, if active */
 	unsigned long flags;		/* BUSY, SLEEPING */
-	struct ata_device *drive;	/* current drive */
+	struct ata_device *XXX_drive;	/* current drive */
 	struct request *rq;		/* current request */
 	struct timer_list timer;	/* failsafe timer */
 	unsigned long poll_timeout;	/* timeout value during long polls */


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

* [PATCH] 2.5.11 IDE 48
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (12 preceding siblings ...)
  2002-04-30  8:45 ` [PATCH] 2.5.11 IDE 47 Martin Dalecki
@ 2002-04-30 15:16 ` Martin Dalecki
  2002-05-02  8:39 ` [PATCH] 2.5.12 IDE 49 Martin Dalecki
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-04-30 15:16 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List, axboe

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

So dear Jens, here it comes in it's whole glory.
I hope it will make your life easier.

It's fixing the "performance" degradation partially,
becouse we don't miss that many jiffies in choose_urgent_device()
anymore. However choose_urgent_device has to be fixed for
the off by one error to don't loop for a whole 1/100 second before
submitting the next request.

Tue Apr 30 13:23:13 CEST 2002 ide-clean-48

- Include small declaration bits for Jens. (WIN_NOP fix in esp.)

- Fix ide-pmac to conform to the recent API changes.

- Prepare and improve the handling of the request queue. It sucks now as many
   request as possible. This is improving the performance.

[-- Attachment #2: ide-clean-48.diff --]
[-- Type: text/plain, Size: 21257 bytes --]

diff -urN linux-2.5.11/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.11/drivers/ide/ide.c	2002-04-30 18:05:44.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-04-30 17:52:45.000000000 +0200
@@ -1190,12 +1190,49 @@
 	drive->PADAM_sleep = timeout + jiffies;
 }
 
+
+/*
+ * Determine the longes sleep time for the devices in our hwgroup.
+ */
+static unsigned long longest_sleep(struct ata_channel *channel)
+{
+	unsigned long sleep = 0;
+	int i;
+
+	for (i = 0; i < MAX_HWIFS; ++i) {
+		int unit;
+		struct ata_channel *ch = &ide_hwifs[i];
+
+		if (!ch->present)
+			continue;
+
+		if (ch->hwgroup != channel->hwgroup)
+			continue;
+
+		for (unit = 0; unit < MAX_DRIVES; ++unit) {
+			struct ata_device *drive = &ch->drives[unit];
+
+			if (!drive->present)
+				continue;
+
+			/* This device is sleeping and waiting to be serviced
+			 * later than any other device we checked thus far.
+			 */
+			if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
+				sleep = drive->PADAM_sleep;
+		}
+	}
+
+	return sleep;
+}
+
 /*
  * Select the next device which will be serviced.
  */
 static struct ata_device *choose_urgent_device(struct ata_channel *channel)
 {
-	struct ata_device *best = NULL;
+	struct ata_device *choice = NULL;
+	unsigned long sleep = 0;
 	int i;
 
 	for (i = 0; i < MAX_HWIFS; ++i) {
@@ -1227,54 +1264,152 @@
 			/* Take this device, if there is no device choosen thus far or
 			 * it's more urgent.
 			 */
-			if (!best || (drive->PADAM_sleep && (!best->PADAM_sleep || time_after(best->PADAM_sleep, drive->PADAM_sleep))))
+			if (!choice || (drive->PADAM_sleep && (!choice->PADAM_sleep || time_after(choice->PADAM_sleep, drive->PADAM_sleep))))
 			{
 				if (!blk_queue_plugged(&drive->queue))
-					best = drive;
+					choice = drive;
 			}
 		}
 	}
 
-	return best;
+	if (choice)
+		return choice;
+
+	channel->hwgroup->rq = NULL;
+	sleep = longest_sleep(channel);
+
+	if (sleep) {
+
+		/*
+		 * Take a short snooze, and then wake up again.  Just in case
+		 * there are big differences in relative throughputs.. don't
+		 * want to hog the cpu too much.
+		 */
+
+		if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep))
+		    sleep = jiffies + WAIT_MIN_SLEEP;
+#if 1
+		if (timer_pending(&channel->hwgroup->timer))
+			printk(KERN_ERR "ide_set_handler: timer already active\n");
+#endif
+		set_bit(IDE_SLEEP, &channel->hwgroup->flags);
+		mod_timer(&channel->hwgroup->timer, sleep);
+		/* we purposely leave hwgroup busy while sleeping */
+	} else {
+		/* Ugly, but how can we sleep for the lock otherwise? perhaps
+		 * from tq_disk? */
+		ide_release_lock(&irq_lock);/* for atari only */
+		clear_bit(IDE_BUSY, &channel->hwgroup->flags);
+	}
+
+	return NULL;
 }
 
+
+/* Place holders for later expansion of functionality.
+ */
+#define ata_pending_commands(drive)	(0)
+#define ata_can_queue(drive)		(1)
+
 /*
- * Determine the longes sleep time for the devices in our hwgroup.
+ * Feed commands to a drive until it barfs.  Called with ide_lock/DRIVE_LOCK
+ * held and busy channel.
  */
-static unsigned long longest_sleep(struct ata_channel *channel)
+
+static void queue_commands(struct ata_device *drive, int masked_irq)
 {
-	unsigned long sleep = 0;
-	int i;
+	ide_hwgroup_t *hwgroup = drive->channel->hwgroup;
+	ide_startstop_t startstop = -1;
 
-	for (i = 0; i < MAX_HWIFS; ++i) {
-		int unit;
-		struct ata_channel *ch = &ide_hwifs[i];
+	for (;;) {
+		struct request *rq = NULL;
 
-		if (!ch->present)
-			continue;
+		if (!test_bit(IDE_BUSY, &hwgroup->flags))
+			printk(KERN_ERR"%s: hwgroup not busy while queueing\n", drive->name);
 
-		if (ch->hwgroup != channel->hwgroup)
-			continue;
+		/* Abort early if we can't queue another command. for non
+		 * tcq, ata_can_queue is always 1 since we never get here
+		 * unless the drive is idle.
+		 */
+		if (!ata_can_queue(drive)) {
+			if (!ata_pending_commands(drive))
+				clear_bit(IDE_BUSY, &hwgroup->flags);
+			break;
+		}
 
-		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			struct ata_device *drive = &ch->drives[unit];
+		drive->PADAM_sleep = 0;
 
-			if (!drive->present)
-				continue;
+		if (test_bit(IDE_DMA, &hwgroup->flags)) {
+			printk("ide_do_request: DMA in progress...\n");
+			break;
+		}
 
-			/* This device is sleeping and waiting to be serviced
-			 * later than any other device we checked thus far.
-			 */
-			if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
-				sleep = drive->PADAM_sleep;
+		/* There's a small window between where the queue could be
+		 * replugged while we are in here when using tcq (in which
+		 * case the queue is probably empty anyways...), so check
+		 * and leave if appropriate. When not using tcq, this is
+		 * still a severe BUG!
+		 */
+		if (blk_queue_plugged(&drive->queue)) {
+			BUG();
+			break;
 		}
-	}
 
-	return sleep;
+		if (!(rq = elv_next_request(&drive->queue))) {
+			if (!ata_pending_commands(drive))
+				clear_bit(IDE_BUSY, &hwgroup->flags);
+			hwgroup->rq = NULL;
+			break;
+		}
+
+		/* If there are queued commands, we can't start a non-fs
+		 * request (really, a non-queuable command) until the
+		 * queue is empty.
+		 */
+		if (!(rq->flags & REQ_CMD) && ata_pending_commands(drive))
+			break;
+
+		hwgroup->rq = rq;
+
+		/* Some systems have trouble with IDE IRQs arriving while the
+		 * driver is still setting things up.  So, here we disable the
+		 * IRQ used by this interface while the request is being
+		 * started.  This may look bad at first, but pretty much the
+		 * same thing happens anyway when any interrupt comes in, IDE
+		 * or otherwise -- the kernel masks the IRQ while it is being
+		 * handled.
+		 */
+
+		if (masked_irq && drive->channel->irq != masked_irq)
+			disable_irq_nosync(drive->channel->irq);
+
+		spin_unlock(&ide_lock);
+		ide__sti();	/* allow other IRQs while we start this request */
+		startstop = start_request(drive, rq);
+
+		spin_lock_irq(&ide_lock);
+		if (masked_irq && drive->channel->irq != masked_irq)
+			enable_irq(drive->channel->irq);
+
+		/* command started, we are busy */
+		if (startstop == ide_started)
+			break;
+
+		/* start_request() can return either ide_stopped (no command
+		 * was started), ide_started (command started, don't queue
+		 * more), or ide_released (command started, try and queue
+		 * more).
+		 */
+#if 0
+		if (startstop == ide_stopped)
+			set_bit(IDE_BUSY, &hwgroup->flags);
+#endif
+
+	}
 }
 
 /*
- * Issue a new request to a drive from hwgroup.
+ * Issue a new request.
  * Caller must have already done spin_lock_irqsave(&ide_lock, ...)
  *
  * A hwgroup is a serialized group of IDE interfaces.  Usually there is
@@ -1312,42 +1447,14 @@
 
 	while (!test_and_set_bit(IDE_BUSY, &hwgroup->flags)) {
 		struct ata_channel *ch;
-		ide_startstop_t	startstop;
-		struct ata_device *drive = choose_urgent_device(channel);
-
-		if (drive == NULL) {
-			unsigned long sleep = 0;
+		struct ata_device *drive;
 
-			hwgroup->rq = NULL;
-			sleep = longest_sleep(channel);
-
-			if (sleep) {
-
-				/*
-				 * Take a short snooze, and then wake up again.
-				 * Just in case there are big differences in
-				 * relative throughputs.. don't want to hog the
-				 * cpu too much.
-				 */
+		/* this will clear IDE_BUSY, if appropriate */
+		drive = choose_urgent_device(channel);
 
-				if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep))
-					sleep = jiffies + WAIT_MIN_SLEEP;
-#if 1
-				if (timer_pending(&hwgroup->timer))
-					printk("ide_set_handler: timer already active\n");
-#endif
-				set_bit(IDE_SLEEP, &hwgroup->flags);
-				mod_timer(&hwgroup->timer, sleep);
-				/* we purposely leave hwgroup busy while sleeping */
-			} else {
-				/* Ugly, but how can we sleep for the lock
-				 * otherwise? perhaps from tq_disk? */
-				ide_release_lock(&irq_lock);/* for atari only */
-				clear_bit(IDE_BUSY, &hwgroup->flags);
-			}
+		if (!drive)
+			break;
 
-			return;
-		}
 		ch = drive->channel;
 
 		if (hwgroup->XXX_drive->channel->sharing_irq && ch != hwgroup->XXX_drive->channel && ch->io_ports[IDE_CONTROL_OFFSET]) {
@@ -1364,51 +1471,10 @@
 		 */
 		hwgroup->XXX_drive = drive;
 
-		/* Reset wait timeout.
-		 */
-		drive->PADAM_sleep = 0;
-
-		if (blk_queue_plugged(&drive->queue))
-			BUG();
-
-		/* Just continuing an interrupted request maybe.
-		 */
-		hwgroup->rq = elv_next_request(&drive->queue);
-
-		/*
-		 * Some systems have trouble with IDE IRQs arriving while the
-		 * driver is still setting things up.  So, here we disable the
-		 * IRQ used by this interface while the request is being
-		 * started.  This may look bad at first, but pretty much the
-		 * same thing happens anyway when any interrupt comes in, IDE
-		 * or otherwise -- the kernel masks the IRQ while it is being
-		 * handled.
-		 */
-
-		if (masked_irq && ch->irq != masked_irq)
-			disable_irq_nosync(ch->irq);
-		spin_unlock(&ide_lock);
-		ide__sti();	/* allow other IRQs while we start this request */
-		startstop = start_request(drive, hwgroup->rq);
-		spin_lock_irq(&ide_lock);
-		if (masked_irq && ch->irq != masked_irq)
-			enable_irq(ch->irq);
-		if (startstop == ide_stopped)
-			clear_bit(IDE_BUSY, &hwgroup->flags);
+		queue_commands(drive, masked_irq);
 	}
 }
 
-/*
- * Returns the queue which corresponds to a given device.
- */
-request_queue_t *ide_get_queue(kdev_t dev)
-{
-	struct ata_channel *ch = (struct ata_channel *)blk_dev[major(dev)].data;
-
-	/* FIXME: ALLERT: This discriminates between master and slave! */
-	return &ch->drives[DEVICE_NR(dev) & 1].queue;
-}
-
 void do_ide_request(request_queue_t *q)
 {
 	ide_do_request(q->queuedata, 0);
@@ -1419,20 +1485,20 @@
  * retry the current request in PIO mode instead of risking tossing it
  * all away
  */
-static void dma_timeout_retry(ide_drive_t *drive, struct request *rq)
+static void dma_timeout_retry(struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
+	struct ata_channel *ch = drive->channel;
 
 	/*
 	 * end current dma transaction
 	 */
-	hwif->udma(ide_dma_end, drive, rq);
+	ch->udma(ide_dma_end, drive, rq);
 
 	/*
 	 * complain a little, later we might remove some of this verbosity
 	 */
 	printk("%s: timeout waiting for DMA\n", drive->name);
-	hwif->udma(ide_dma_timeout, drive, rq);
+	ch->udma(ide_dma_timeout, drive, rq);
 
 	/*
 	 * Disable dma for now, but remember that we did so because of
@@ -1441,7 +1507,7 @@
 	 */
 	drive->retry_pio++;
 	drive->state = DMA_PIO_RETRY;
-	hwif->udma(ide_dma_off_quietly, drive, rq);
+	ch->udma(ide_dma_off_quietly, drive, rq);
 
 	/*
 	 * un-busy drive etc (hwgroup->busy is cleared on return) and
@@ -1713,11 +1779,11 @@
 	int h;
 
 	for (h = 0; h < MAX_HWIFS; ++h) {
-		struct ata_channel *hwif = &ide_hwifs[h];
-		if (hwif->present && major == hwif->major) {
+		struct ata_channel *ch = &ide_hwifs[h];
+		if (ch->present && major == ch->major) {
 			int unit = DEVICE_NR(i_rdev);
 			if (unit < MAX_DRIVES) {
-				struct ata_device *drive = &hwif->drives[unit];
+				struct ata_device *drive = &ch->drives[unit];
 				if (drive->present)
 					return drive;
 			}
@@ -2029,7 +2095,7 @@
 	int unit, i;
 	unsigned long flags;
 	unsigned int p, minor;
-	struct ata_channel old_hwif;
+	struct ata_channel old;
 	int n = 0;
 
 	spin_lock_irqsave(&ide_lock, flags);
@@ -2156,40 +2222,41 @@
 	 * it.
 	 */
 
-	old_hwif = *ch;
+	old = *ch;
 	init_hwif_data(ch, ch->index);
-	ch->hwgroup = old_hwif.hwgroup;
-	ch->tuneproc = old_hwif.tuneproc;
-	ch->speedproc = old_hwif.speedproc;
-	ch->selectproc = old_hwif.selectproc;
-	ch->resetproc = old_hwif.resetproc;
-	ch->intrproc = old_hwif.intrproc;
-	ch->maskproc = old_hwif.maskproc;
-	ch->quirkproc = old_hwif.quirkproc;
-	ch->rwproc	= old_hwif.rwproc;
-	ch->ata_read = old_hwif.ata_read;
-	ch->ata_write = old_hwif.ata_write;
-	ch->atapi_read = old_hwif.atapi_read;
-	ch->atapi_write = old_hwif.atapi_write;
-	ch->udma = old_hwif.udma;
-	ch->busproc = old_hwif.busproc;
-	ch->bus_state = old_hwif.bus_state;
-	ch->dma_base = old_hwif.dma_base;
-	ch->dma_extra = old_hwif.dma_extra;
-	ch->config_data = old_hwif.config_data;
-	ch->select_data = old_hwif.select_data;
-	ch->proc = old_hwif.proc;
+	ch->hwgroup = old.hwgroup;
+	ch->tuneproc = old.tuneproc;
+	ch->speedproc = old.speedproc;
+	ch->selectproc = old.selectproc;
+	ch->resetproc = old.resetproc;
+	ch->intrproc = old.intrproc;
+	ch->maskproc = old.maskproc;
+	ch->quirkproc = old.quirkproc;
+	ch->rwproc	= old.rwproc;
+	ch->ata_read = old.ata_read;
+	ch->ata_write = old.ata_write;
+	ch->atapi_read = old.atapi_read;
+	ch->atapi_write = old.atapi_write;
+	ch->udma = old.udma;
+	ch->busproc = old.busproc;
+	ch->bus_state = old.bus_state;
+	ch->dma_base = old.dma_base;
+	ch->dma_extra = old.dma_extra;
+	ch->config_data = old.config_data;
+	ch->select_data = old.select_data;
+	ch->proc = old.proc;
+	/* FIXME: most propably this is always right:! */
 #ifndef CONFIG_BLK_DEV_IDECS
-	ch->irq = old_hwif.irq;
+	ch->irq = old.irq;
 #endif
-	ch->major = old_hwif.major;
-	ch->chipset = old_hwif.chipset;
-	ch->autodma = old_hwif.autodma;
-	ch->udma_four = old_hwif.udma_four;
+	ch->major = old.major;
+	ch->chipset = old.chipset;
+	ch->autodma = old.autodma;
+	ch->udma_four = old.udma_four;
 #ifdef CONFIG_BLK_DEV_IDEPCI
-	ch->pci_dev = old_hwif.pci_dev;
+	ch->pci_dev = old.pci_dev;
 #endif
-	ch->straight8 = old_hwif.straight8;
+	ch->straight8 = old.straight8;
 
 abort:
 	spin_unlock_irqrestore(&ide_lock, flags);
@@ -3352,7 +3419,6 @@
 EXPORT_SYMBOL(ide_lock);
 EXPORT_SYMBOL(drive_is_flashcard);
 EXPORT_SYMBOL(ide_timer_expiry);
-EXPORT_SYMBOL(ide_get_queue);
 EXPORT_SYMBOL(ide_add_generic_settings);
 EXPORT_SYMBOL(do_ide_request);
 /*
diff -urN linux-2.5.11/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.11/drivers/ide/ide-pmac.c	2002-04-30 18:05:41.000000000 +0200
+++ linux/drivers/ide/ide-pmac.c	2002-04-30 14:32:06.000000000 +0200
@@ -27,6 +27,7 @@
  *    symbols or by storing hooks at arch level).
  *
  */
+
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -77,8 +78,8 @@
 	struct scatterlist*		sg_table;
 	int				sg_nents;
 	int				sg_dma_direction;
-#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
-	
+#endif
+
 } pmac_ide[MAX_HWIFS] __pmacdata;
 
 static int pmac_ide_count;
@@ -255,11 +256,11 @@
 #define IDE_WAKEUP_DELAY_MS	2000
 
 static void pmac_ide_setup_dma(struct device_node *np, int ix);
-static int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
-static int pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr);
-static int pmac_ide_tune_chipset(ide_drive_t *drive, byte speed);
-static void pmac_ide_tuneproc(ide_drive_t *drive, byte pio);
-static void pmac_ide_selectproc(ide_drive_t *drive);
+static int pmac_ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq);
+static int pmac_ide_build_dmatable(struct ata_device *drive, struct request *rq, int ix, int wr);
+static int pmac_ide_tune_chipset(struct ata_device *drive, byte speed);
+static void pmac_ide_tuneproc(struct ata_device *drive, byte pio);
+static void pmac_ide_selectproc(struct ata_device *drive);
 
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
@@ -322,7 +323,7 @@
 	ide_hwifs[ix].selectproc = pmac_ide_selectproc;
 	ide_hwifs[ix].speedproc = &pmac_ide_tune_chipset;
 	if (pmac_ide[ix].dma_regs && pmac_ide[ix].dma_table_cpu) {
-		ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc;
+		ide_hwifs[ix].udma = pmac_ide_dmaproc;
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO
 		if (!noautodma)
 			ide_hwifs[ix].autodma = 1;
@@ -405,7 +406,7 @@
 {
 	int result = 1;
 	unsigned long flags;
-	struct ata_channel *hwif = HWIF(drive);
+	struct ata_channel *hwif = drive->channel;
 	
 	disable_irq(hwif->irq);	/* disable_irq_nosync ?? */
 	udelay(1);
@@ -431,7 +432,7 @@
 	if (result)
 		printk(KERN_ERR "pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n");
 out:
-	SELECT_MASK(HWIF(drive), drive, 0);
+	SELECT_MASK(drive->channel, drive, 0);
 	if (result == 0) {
 		drive->id->dma_ultra &= ~0xFF00;
 		drive->id->dma_mword &= ~0x0F00;
@@ -1024,7 +1025,7 @@
 				    	pmif->dma_table_cpu, pmif->dma_table_dma);
 		return;
 	}
-	ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc;
+	ide_hwifs[ix].udma = pmac_ide_dmaproc;
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO
 	if (!noautodma)
 		ide_hwifs[ix].autodma = 1;
@@ -1092,11 +1093,10 @@
  * for a transfer and sets the DBDMA channel to point to it.
  */
 static int
-pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr)
+pmac_ide_build_dmatable(struct ata_device *drive, struct request *rq, int ix, int wr)
 {
 	struct dbdma_cmd *table;
 	int i, count = 0;
-	struct request *rq = HWGROUP(drive)->rq;
 	volatile struct dbdma_regs *dma = pmac_ide[ix].dma_regs;
 	struct scatterlist *sg;
 
@@ -1166,7 +1166,7 @@
 static void
 pmac_ide_destroy_dmatable (ide_drive_t *drive, int ix)
 {
-	struct pci_dev *dev = HWIF(drive)->pci_dev;
+	struct pci_dev *dev = drive->channel->pci_dev;
 	struct scatterlist *sg = pmac_ide[ix].sg_table;
 	int nents = pmac_ide[ix].sg_nents;
 
@@ -1326,17 +1326,17 @@
 {
 	dma64_addr_t addr = BLK_BOUNCE_HIGH;
 
-	if (on && drive->type == ATA_DISK && HWIF(drive)->highmem) {
+	if (on && drive->type == ATA_DISK && drive->channel->highmem) {
 		if (!PCI_DMA_BUS_IS_PHYS)
 			addr = BLK_BOUNCE_ANY;
 		else
-			addr = HWIF(drive)->pci_dev->dma_mask;
+			addr = drive->channel->pci_dev->dma_mask;
 	}
 
 	blk_queue_bounce_limit(&drive->queue, addr);
 }
 
-int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
+static int pmac_ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
 	int ix, dstat, reading, ata4;
 	volatile struct dbdma_regs *dma;
@@ -1369,10 +1369,10 @@
 	case ide_dma_write:
 		/* this almost certainly isn't needed since we don't
 		   appear to have a rwproc */
-		if (HWIF(drive)->rwproc)
-			HWIF(drive)->rwproc(drive, func);
+		if (drive->channel->rwproc)
+			drive->channel->rwproc(drive, func);
 		reading = (func == ide_dma_read);
-		if (!pmac_ide_build_dmatable(drive, ix, !reading))
+		if (!pmac_ide_build_dmatable(drive, rq, ix, !reading))
 			return 1;
 		/* Apple adds 60ns to wrDataSetup on reads */
 		if (ata4 && (pmac_ide[ix].timings[unit] & TR_66_UDMA_EN)) {
@@ -1385,9 +1385,9 @@
 		if (drive->type != ATA_DISK)
 			return 0;
 		ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
-		if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) &&
+		if ((rq->flags & REQ_DRIVE_ACB) &&
 		    (drive->addressing == 1)) {
-			struct ata_taskfile *args = HWGROUP(drive)->rq->special;
+			struct ata_taskfile *args = rq->special;
 			OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
 		} else if (drive->addressing) {
 			OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
diff -urN linux-2.5.11/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.11/drivers/ide/ide-probe.c	2002-04-30 18:05:44.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-04-30 17:55:04.000000000 +0200
@@ -829,6 +829,20 @@
 	return;
 }
 
+/*
+ * Returns the queue which corresponds to a given device.
+ *
+ * FIXME: this should take struct block_device * as argument in future.
+ */
+
+static request_queue_t *ata_get_queue(kdev_t dev)
+{
+	struct ata_channel *ch = (struct ata_channel *)blk_dev[major(dev)].data;
+
+	/* FIXME: ALLERT: This discriminates between master and slave! */
+	return &ch->drives[DEVICE_NR(dev) & 1].queue;
+}
+
 static void channel_init(struct ata_channel *ch)
 {
 	if (!ch->present)
@@ -882,7 +896,7 @@
 
 	init_gendisk(ch);
 	blk_dev[ch->major].data = ch;
-	blk_dev[ch->major].queue = ide_get_queue;
+	blk_dev[ch->major].queue = ata_get_queue;
 
 	/* all went well, flag this channel entry as valid */
 	ch->present = 1;
diff -urN linux-2.5.11/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.11/drivers/ide/ide-taskfile.c	2002-04-30 18:05:41.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-04-30 16:36:59.000000000 +0200
@@ -522,9 +522,12 @@
 
 	ide__sti();	/* local CPU only */
 
-	if (!OK_STAT(stat = GET_STAT(), READY_STAT, BAD_STAT))
-		return ide_error(drive, "task_no_data_intr", stat);
-		/* calls ide_end_drive_cmd */
+	if (!OK_STAT(stat = GET_STAT(), READY_STAT, BAD_STAT)) {
+		/* Keep quite for NOP becouse they are expected to fail. */
+		if (args && args->taskfile.command != WIN_NOP)
+			return ide_error(drive, "task_no_data_intr", stat);
+	}
+
 	if (args)
 		ide_end_drive_cmd (drive, stat, GET_ERR());
 
@@ -854,6 +857,7 @@
 			return;
 
 		case WIN_NOP:
+			args->handler = task_no_data_intr;
 			args->command_type = IDE_DRIVE_TASK_NO_DATA;
 			return;
 
diff -urN linux-2.5.11/include/linux/hdreg.h linux/include/linux/hdreg.h
--- linux-2.5.11/include/linux/hdreg.h	2002-04-29 05:12:40.000000000 +0200
+++ linux/include/linux/hdreg.h	2002-04-30 13:23:57.000000000 +0200
@@ -34,6 +34,7 @@
 #define ECC_STAT		0x04	/* Corrected error */
 #define DRQ_STAT		0x08
 #define SEEK_STAT		0x10
+#define SERVICE_STAT		SEEK_STAT
 #define WRERR_STAT		0x20
 #define READY_STAT		0x40
 #define BUSY_STAT		0x80
@@ -50,6 +51,13 @@
 #define ICRC_ERR		0x80	/* new meaning:  CRC error during transfer */
 
 /*
+ * sector count bits
+ */
+#define NSEC_CD			0x01
+#define NSEC_IO			0x02
+#define NSEC_REL		0x04
+
+/*
  * Command Header sizes for IOCTL commands
  */
 

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

* [PATCH] 2.5.12 IDE 49
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (13 preceding siblings ...)
  2002-04-30 15:16 ` [PATCH] 2.5.11 IDE 48 Martin Dalecki
@ 2002-05-02  8:39 ` Martin Dalecki
  2002-05-02  8:42 ` Linux 2.5.7 Martin Dalecki
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-05-02  8:39 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

- Fix compilation of piix.c

- Revoke the PADAM_ prefix from sleep hwgroup member.

- Fix Pacific Digital host chip driver API.

- Fix Tekram host chip driver API.

- Fold hwif_unregister() directly in to channel code.

[-- Attachment #2: ide-clean-49.diff --]
[-- Type: text/plain, Size: 14580 bytes --]

diff -ur linux-2.5.12/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.12/drivers/ide/ide.c	2002-05-01 02:08:56.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-05-02 03:20:40.000000000 +0200
@@ -1187,12 +1188,12 @@
 {
 	if (timeout > WAIT_WORSTCASE)
 		timeout = WAIT_WORSTCASE;
-	drive->PADAM_sleep = timeout + jiffies;
+	drive->sleep = timeout + jiffies;
 }
 
 
 /*
- * Determine the longes sleep time for the devices in our hwgroup.
+ * Determine the longest sleep time for the devices at this channel.
  */
 static unsigned long longest_sleep(struct ata_channel *channel)
 {
@@ -1218,8 +1219,8 @@
 			/* This device is sleeping and waiting to be serviced
 			 * later than any other device we checked thus far.
 			 */
-			if (drive->PADAM_sleep && (!sleep || time_after(sleep, drive->PADAM_sleep)))
-				sleep = drive->PADAM_sleep;
+			if (drive->sleep && (!sleep || time_after(sleep, drive->sleep)))
+				sleep = drive->sleep;
 		}
 	}
 
@@ -1256,16 +1257,15 @@
 			if (list_empty(&drive->queue.queue_head))
 				continue;
 
-			/* This device still want's to remain idle.
+			/* This device still wants to remain idle.
 			 */
-			if (drive->PADAM_sleep && time_after(jiffies, drive->PADAM_sleep))
+			if (drive->sleep && time_after(jiffies, drive->sleep))
 				continue;
 
 			/* Take this device, if there is no device choosen thus far or
 			 * it's more urgent.
 			 */
-			if (!choice || (drive->PADAM_sleep && (!choice->PADAM_sleep || time_after(choice->PADAM_sleep, drive->PADAM_sleep))))
-			{
+			if (!choice || (drive->sleep && (!choice->sleep || time_after(choice->sleep, drive->sleep)))) {
 				if (!blk_queue_plugged(&drive->queue))
 					choice = drive;
 			}
@@ -1315,7 +1315,6 @@
  * Feed commands to a drive until it barfs.  Called with ide_lock/DRIVE_LOCK
  * held and busy channel.
  */
-
 static void queue_commands(struct ata_device *drive, int masked_irq)
 {
 	ide_hwgroup_t *hwgroup = drive->channel->hwgroup;
@@ -1325,7 +1324,7 @@
 		struct request *rq = NULL;
 
 		if (!test_bit(IDE_BUSY, &hwgroup->flags))
-			printk(KERN_ERR"%s: hwgroup not busy while queueing\n", drive->name);
+			printk(KERN_ERR"%s: error: not busy while queueing!\n", drive->name);
 
 		/* Abort early if we can't queue another command. for non
 		 * tcq, ata_can_queue is always 1 since we never get here
@@ -1337,7 +1336,7 @@
 			break;
 		}
 
-		drive->PADAM_sleep = 0;
+		drive->sleep = 0;
 
 		if (test_bit(IDE_DMA, &hwgroup->flags)) {
 			printk("ide_do_request: DMA in progress...\n");
@@ -1825,10 +1824,9 @@
  * completed. This is again intended for careful use by the ATAPI tape/cdrom
  * driver code.
  */
-int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action)
+int ide_do_drive_cmd(struct ata_device *drive, struct request *rq, ide_action_t action)
 {
 	unsigned long flags;
-	ide_hwgroup_t *hwgroup = HWGROUP(drive);
 	unsigned int major = drive->channel->major;
 	request_queue_t *q = &drive->queue;
 	struct list_head *queue_head = &q->queue_head;
@@ -1846,7 +1844,7 @@
 	spin_lock_irqsave(&ide_lock, flags);
 	if (blk_queue_empty(&drive->queue) || action == ide_preempt) {
 		if (action == ide_preempt)
-			hwgroup->rq = NULL;
+			HWGROUP(drive)->rq = NULL;
 	} else {
 		if (action == ide_wait || action == ide_end)
 			queue_head = queue_head->prev;
@@ -1873,21 +1871,22 @@
  * usage == 1 (we need an open channel to use an ioctl :-), so this
  * is our limit.
  */
-int ide_revalidate_disk (kdev_t i_rdev)
+int ide_revalidate_disk(kdev_t i_rdev)
 {
-	ide_drive_t *drive;
-	ide_hwgroup_t *hwgroup;
+	struct ata_device *drive;
 	unsigned long flags;
 	int res;
 
 	if ((drive = get_info_ptr(i_rdev)) == NULL)
 		return -ENODEV;
-	hwgroup = HWGROUP(drive);
+
 	spin_lock_irqsave(&ide_lock, flags);
+
 	if (drive->busy || (drive->usage > 1)) {
 		spin_unlock_irqrestore(&ide_lock, flags);
 		return -EBUSY;
 	}
+
 	drive->busy = 1;
 	MOD_INC_USE_COUNT;
 	spin_unlock_irqrestore(&ide_lock, flags);
@@ -2032,71 +2031,18 @@
 };
 #endif
 
-/*
- * Note that we only release the standard ports, and do not even try to handle
- * any extra ports allocated for weird IDE interface chipsets.
- */
-static void hwif_unregister(struct ata_channel *ch)
-{
-	int i;
-	ide_hwgroup_t *hwgroup = ch->hwgroup;
-
-	/*
-	 * Free the irq if we were the only channel using it.
-	 */
-	int n = 0;
-
-	for (i = 0; i < MAX_HWIFS; ++i) {
-		struct ata_channel *tmp = &ide_hwifs[i];
-
-		if (!tmp->present)
-			continue;
-
-		if (tmp->irq == ch->irq)
-			++n;
-	}
-	if (n == 1)
-		free_irq(ch->irq, hwgroup);
-
-
-	if (ch->straight8) {
-		release_region(ch->io_ports[IDE_DATA_OFFSET], 8);
-	} else {
-		if (ch->io_ports[IDE_DATA_OFFSET])
-			release_region(ch->io_ports[IDE_DATA_OFFSET], 1);
-		if (ch->io_ports[IDE_ERROR_OFFSET])
-			release_region(ch->io_ports[IDE_ERROR_OFFSET], 1);
-		if (ch->io_ports[IDE_NSECTOR_OFFSET])
-			release_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1);
-		if (ch->io_ports[IDE_SECTOR_OFFSET])
-			release_region(ch->io_ports[IDE_SECTOR_OFFSET], 1);
-		if (ch->io_ports[IDE_LCYL_OFFSET])
-			release_region(ch->io_ports[IDE_LCYL_OFFSET], 1);
-		if (ch->io_ports[IDE_HCYL_OFFSET])
-			release_region(ch->io_ports[IDE_HCYL_OFFSET], 1);
-		if (ch->io_ports[IDE_SELECT_OFFSET])
-			release_region(ch->io_ports[IDE_SELECT_OFFSET], 1);
-		if (ch->io_ports[IDE_STATUS_OFFSET])
-			release_region(ch->io_ports[IDE_STATUS_OFFSET], 1);
-	}
-	if (ch->io_ports[IDE_CONTROL_OFFSET])
-		release_region(ch->io_ports[IDE_CONTROL_OFFSET], 1);
-#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
-	if (ch->io_ports[IDE_IRQ_OFFSET])
-		release_region(ch->io_ports[IDE_IRQ_OFFSET], 1);
-#endif
-}
-
 void ide_unregister(struct ata_channel *ch)
 {
 	struct gendisk *gd;
 	struct ata_device *d;
 	ide_hwgroup_t *hwgroup;
-	int unit, i;
+	int unit;
+	int i;
 	unsigned long flags;
 	unsigned int p, minor;
 	struct ata_channel old;
-	int n = 0;
+	int n_irq;
+	int n_ch;
 
 	spin_lock_irqsave(&ide_lock, flags);
 
@@ -2146,10 +2092,40 @@
 #endif
 	spin_lock_irqsave(&ide_lock, flags);
 
-	hwif_unregister(ch);
+	/*
+	 * Note that we only release the standard ports, and do not even try to
+	 * handle any extra ports allocated for weird IDE interface chipsets.
+	 */
+
+	if (ch->straight8) {
+		release_region(ch->io_ports[IDE_DATA_OFFSET], 8);
+	} else {
+		if (ch->io_ports[IDE_DATA_OFFSET])
+			release_region(ch->io_ports[IDE_DATA_OFFSET], 1);
+		if (ch->io_ports[IDE_ERROR_OFFSET])
+			release_region(ch->io_ports[IDE_ERROR_OFFSET], 1);
+		if (ch->io_ports[IDE_NSECTOR_OFFSET])
+			release_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1);
+		if (ch->io_ports[IDE_SECTOR_OFFSET])
+			release_region(ch->io_ports[IDE_SECTOR_OFFSET], 1);
+		if (ch->io_ports[IDE_LCYL_OFFSET])
+			release_region(ch->io_ports[IDE_LCYL_OFFSET], 1);
+		if (ch->io_ports[IDE_HCYL_OFFSET])
+			release_region(ch->io_ports[IDE_HCYL_OFFSET], 1);
+		if (ch->io_ports[IDE_SELECT_OFFSET])
+			release_region(ch->io_ports[IDE_SELECT_OFFSET], 1);
+		if (ch->io_ports[IDE_STATUS_OFFSET])
+			release_region(ch->io_ports[IDE_STATUS_OFFSET], 1);
+	}
+	if (ch->io_ports[IDE_CONTROL_OFFSET])
+		release_region(ch->io_ports[IDE_CONTROL_OFFSET], 1);
+#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
+	if (ch->io_ports[IDE_IRQ_OFFSET])
+		release_region(ch->io_ports[IDE_IRQ_OFFSET], 1);
+#endif
 
 	/*
-	 * Remove us from the hwgroup
+	 * Remove us from the hwgroup.
 	 */
 
 	hwgroup = ch->hwgroup;
@@ -2177,20 +2153,30 @@
 	if (d->present)
 		hwgroup->XXX_drive = d;
 
-	/* Free the hwgroup if we were the only member.
+
+	/*
+	 * Free the irq if we were the only channel using it.
+	 *
+	 * Free the hwgroup if we were the only member.
 	 */
-	n = 0;
+	n_irq = n_ch = 0;
 	for (i = 0; i < MAX_HWIFS; ++i) {
 		struct ata_channel *tmp = &ide_hwifs[i];
 
 		if (!tmp->present)
 			continue;
 
+		if (tmp->irq == ch->irq)
+			++n_irq;
 		if (tmp->hwgroup == ch->hwgroup)
-			++n;
+			++n_ch;
 	}
-	if (n == 1)
+	if (n_irq == 1)
+		free_irq(ch->irq, ch->hwgroup);
+	if (n_ch == 1) {
 		kfree(ch->hwgroup);
+		ch->hwgroup = NULL;
+	}
 
 #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
 	ide_release_dma(ch);
diff -ur linux-2.5.12/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.12/drivers/ide/ide-dma.c	2002-05-01 02:08:49.000000000 +0200
+++ linux/drivers/ide/ide-dma.c	2002-05-02 01:18:54.000000000 +0200
@@ -270,16 +270,15 @@
 }
 
 /*
- * ide_build_dmatable() prepares a dma request.
- * Returns 0 if all went okay, returns 1 otherwise.
- * May also be invoked from trm290.c
+ * This prepares a dma request.  Returns 0 if all went okay, returns 1
+ * otherwise.  May also be invoked from trm290.c
  */
-int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
+int ide_build_dmatable(struct ata_device *drive, ide_dma_action_t func)
 {
-	struct ata_channel *hwif = drive->channel;
-	unsigned int *table = hwif->dmatable_cpu;
+	struct ata_channel *ch = drive->channel;
+	unsigned int *table = ch->dmatable_cpu;
 #ifdef CONFIG_BLK_DEV_TRM290
-	unsigned int is_trm290_chipset = (hwif->chipset == ide_trm290);
+	unsigned int is_trm290_chipset = (ch->chipset == ide_trm290);
 #else
 	const int is_trm290_chipset = 0;
 #endif
@@ -287,11 +286,11 @@
 	int i;
 	struct scatterlist *sg;
 
-	hwif->sg_nents = i = build_sglist(hwif, HWGROUP(drive)->rq);
+	ch->sg_nents = i = build_sglist(ch, HWGROUP(drive)->rq);
 	if (!i)
 		return 0;
 
-	sg = hwif->sg_table;
+	sg = ch->sg_table;
 	while (i) {
 		u32 cur_addr;
 		u32 cur_len;
@@ -309,8 +308,8 @@
 			u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
 
 			if (count++ >= PRD_ENTRIES) {
-				printk("ide-dma: req %p\n", HWGROUP(drive)->rq);
-				printk("count %d, sg_nents %d, cur_len %d, cur_addr %u\n", count, hwif->sg_nents, cur_len, cur_addr);
+				printk("ide-dma: count %d, sg_nents %d, cur_len %d, cur_addr %u\n",
+						count, ch->sg_nents, cur_len, cur_addr);
 				BUG();
 			}
 
@@ -328,9 +327,9 @@
 			 * the 64KB entry into two 32KB entries instead.
 			 */
 				if (count++ >= PRD_ENTRIES) {
-					pci_unmap_sg(hwif->pci_dev, sg,
-						     hwif->sg_nents,
-						     hwif->sg_dma_direction);
+					pci_unmap_sg(ch->pci_dev, sg,
+						     ch->sg_nents,
+						     ch->sg_dma_direction);
 					return 0;
 				}
 
diff -ur linux-2.5.12/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.12/drivers/ide/ide-probe.c	2002-05-01 02:08:44.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-05-02 03:15:06.000000000 +0200
@@ -745,7 +745,7 @@
 #else
 	printk("%s at %p on irq 0x%08x", ch->name,
 		ch->io_ports[IDE_DATA_OFFSET], ch->irq);
-#endif /* __mc68000__ && CONFIG_APUS */
+#endif
 	if (match)
 		printk(" (%sed with %s)",
 			ch->sharing_irq ? "shar" : "serializ", match->name);
diff -ur linux-2.5.12/drivers/ide/pdcadma.c linux/drivers/ide/pdcadma.c
--- linux-2.5.12/drivers/ide/pdcadma.c	2002-05-01 02:08:50.000000000 +0200
+++ linux/drivers/ide/pdcadma.c	2002-05-02 00:53:47.000000000 +0200
@@ -47,18 +47,18 @@
 
 	return p-buffer;	/* => must be less than 4k! */
 }
-#endif  /* defined(DISPLAY_PDCADMA_TIMINGS) && defined(CONFIG_PROC_FS) */
+#endif
 
 byte pdcadma_proc = 0;
 
 extern char *ide_xfer_verbose (byte xfer_rate);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
+
 /*
- * pdcadma_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
+ * This initiates/aborts (U)DMA read/write operations on a drive.
  */
-
-int pdcadma_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+int pdcadma_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
 	switch (func) {
 		case ide_dma_check:
@@ -66,9 +66,9 @@
 		default:
 			break;
 	}
-	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
+	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 unsigned int __init pci_init_pdcadma(struct pci_dev *dev)
 {
@@ -76,9 +76,9 @@
 	if (!pdcadma_proc) {
 		pdcadma_proc = 1;
 		bmide_dev = dev;
-		pdcadma_display_info = &pdcadma_get_info;
+		pdcadma_display_info = pdcadma_get_info;
 	}
-#endif /* DISPLAY_PDCADMA_TIMINGS && CONFIG_PROC_FS */
+#endif
 	return 0;
 }
 
diff -ur linux-2.5.12/drivers/ide/piix.c linux/drivers/ide/piix.c
--- linux-2.5.12/drivers/ide/piix.c	2002-05-01 02:08:55.000000000 +0200
+++ linux/drivers/ide/piix.c	2002-05-01 23:06:04.000000000 +0200
@@ -471,7 +471,9 @@
 				break;
 			}
 
+#ifndef CONFIG_BLK_DEV_PIIX_TRY133
 		case PIIX_UDMA_100:
+#endif
 		case PIIX_UDMA_133:
 			pci_read_config_dword(dev, PIIX_IDECFG, &u);
 			piix_80w = ((u & 0x30) ? 1 : 0) | ((u & 0xc0) ? 2 : 0);
@@ -484,7 +486,7 @@
 
 	if (piix_config->flags & PIIX_PINGPONG) {
 		pci_read_config_dword(dev, PIIX_IDECFG, &u);
-		u |= 0x400; 
+		u |= 0x400;
 		pci_write_config_dword(dev, PIIX_IDECFG, u);
 	}
 
diff -ur linux-2.5.12/drivers/ide/trm290.c linux/drivers/ide/trm290.c
--- linux-2.5.12/drivers/ide/trm290.c	2002-05-01 02:08:49.000000000 +0200
+++ linux/drivers/ide/trm290.c	2002-05-02 00:56:18.000000000 +0200
@@ -173,7 +173,7 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int trm290_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
 	struct ata_channel *hwif = drive->channel;
 	unsigned int count, reading = 2, writing = 0;
@@ -206,12 +206,12 @@
 		case ide_dma_test_irq:
 			return (inw(hwif->dma_base+2) == 0x00ff);
 		default:
-			return ide_dmaproc(func, drive);
+			return ide_dmaproc(func, drive, rq);
 	}
 	trm290_prepare_drive(drive, 0);	/* select PIO xfer */
 	return 1;
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * Invoked from ide-dma.c at boot time.
@@ -263,8 +263,8 @@
 	ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->unit ? 0x0080 : 0x0000), 3);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	hwif->dmaproc = &trm290_dmaproc;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+	hwif->udma = trm290_dmaproc;
+#endif
 
 	hwif->selectproc = &trm290_selectproc;
 	hwif->autodma = 0;				/* play it safe for now */
diff -ur linux-2.5.12/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.12/include/linux/ide.h	2002-05-01 02:08:49.000000000 +0200
+++ linux/include/linux/ide.h	2002-05-02 04:18:23.000000000 +0200
@@ -283,10 +283,8 @@
 	 */
 	request_queue_t	queue;	/* per device request queue */
 
-	/* Those are directly injected jiffie values. They should go away and
-	 * we should use generic timers instead!!!
-	 */
-	unsigned long PADAM_sleep;	/* sleep until this time */
+
+	unsigned long sleep;	/* sleep until this time */
 
 	/* Flags requesting/indicating one of the following special commands
 	 * executed on the request queue.

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

* Re: Linux 2.5.7
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (14 preceding siblings ...)
  2002-05-02  8:39 ` [PATCH] 2.5.12 IDE 49 Martin Dalecki
@ 2002-05-02  8:42 ` Martin Dalecki
  2002-05-02 13:22   ` Dave Jones
  2002-05-03 12:59 ` [PATCH] 2.5.13 IDE 50 Martin Dalecki
  2002-05-03 14:48 ` [PATCH] 2.5.13 IDE 51 Martin Dalecki
  17 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-05-02  8:42 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Non IDE series:

- Fix some "header magic" related to IDE code in blk.h.

- Fix blk_clear to remove knowlenge about blk_dev[] about the device from the
   kernel as well.

- Fix mtd read only block device.

- Remove LOCAL_END_REQUEST alltogether from the places where it was "used".

[-- Attachment #2: blkdev-2.5.12.diff --]
[-- Type: text/plain, Size: 18427 bytes --]

diff -ur linux-2.5.12/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- linux-2.5.12/drivers/block/cpqarray.c	2002-05-01 02:08:48.000000000 +0200
+++ linux/drivers/block/cpqarray.c	2002-05-02 03:32:42.000000000 +0200
@@ -52,7 +52,6 @@
 MODULE_LICENSE("GPL");
 
 #define MAJOR_NR COMPAQ_SMART2_MAJOR
-#define LOCAL_END_REQUEST
 #include <linux/blk.h>
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
diff -ur linux-2.5.12/drivers/block/floppy.c linux/drivers/block/floppy.c
--- linux-2.5.12/drivers/block/floppy.c	2002-05-01 02:08:48.000000000 +0200
+++ linux/drivers/block/floppy.c	2002-05-02 03:31:23.000000000 +0200
@@ -230,9 +230,7 @@
 
 static int irqdma_allocated;
 
-#define LOCAL_END_REQUEST
 #define MAJOR_NR FLOPPY_MAJOR
-
 #include <linux/blk.h>
 #include <linux/blkpg.h>
 #include <linux/cdrom.h> /* for the compatibility eject ioctl */
@@ -2275,7 +2273,7 @@
  * =============================
  */
 
-static inline void end_request(struct request *req, int uptodate)
+static inline void fd_end_request(struct request *req, int uptodate)
 {
 	kdev_t dev = req->rq_dev;
 
@@ -2320,7 +2318,7 @@
 			current_count_sectors -= req->current_nr_sectors;
 			req->nr_sectors -= req->current_nr_sectors;
 			req->sector += req->current_nr_sectors;
-			end_request(req, 1);
+			fd_end_request(req, 1);
 		}
 		spin_unlock_irqrestore(q->queue_lock, flags);
 
@@ -2348,7 +2346,7 @@
 			DRWE->last_error_generation = DRS->generation;
 		}
 		spin_lock_irqsave(q->queue_lock, flags);
-		end_request(req, 0);
+		fd_end_request(req, 0);
 		spin_unlock_irqrestore(q->queue_lock, flags);
 	}
 }
diff -ur linux-2.5.12/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.12/drivers/ide/ide.c	2002-05-01 02:08:56.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-05-02 03:20:40.000000000 +0200
@@ -135,13 +135,14 @@
 #endif
 #include <linux/pci.h>
 #include <linux/delay.h>
-#include <linux/ide.h>
+#include <linux/blk.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/completion.h>
 #include <linux/reboot.h>
 #include <linux/cdrom.h>
 #include <linux/device.h>
 #include <linux/kmod.h>
+#include <linux/ide.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -1781,7 +1780,7 @@
 	for (h = 0; h < MAX_HWIFS; ++h) {
 		struct ata_channel *ch = &ide_hwifs[h];
 		if (ch->present && major == ch->major) {
-			int unit = DEVICE_NR(i_rdev);
+			int unit = minor(i_rdev) >> PARTN_BITS;
 			if (unit < MAX_DRIVES) {
 				struct ata_device *drive = &ch->drives[unit];
 				if (drive->present)
@@ -2201,8 +2187,6 @@
 	 */
 	unregister_blkdev(ch->major, ch->name);
 	kfree(blksize_size[ch->major]);
-	blk_dev[ch->major].data = NULL;
-	blk_dev[ch->major].queue = NULL;
 	blk_clear(ch->major);
 	gd = ch->gd;
 	if (gd) {
diff -ur linux-2.5.12/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.12/drivers/ide/ide-cd.c	2002-05-01 02:08:56.000000000 +0200
+++ linux/drivers/ide/ide-cd.c	2002-05-02 03:22:13.000000000 +0200
@@ -304,9 +304,10 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
+#include <linux/blk.h>
 #include <linux/cdrom.h>
-#include <linux/ide.h>
 #include <linux/completion.h>
+#include <linux/ide.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
diff -ur linux-2.5.12/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.12/drivers/ide/ide-probe.c	2002-05-01 02:08:44.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-05-02 03:15:06.000000000 +0200
@@ -840,7 +840,7 @@
 	struct ata_channel *ch = (struct ata_channel *)blk_dev[major(dev)].data;
 
 	/* FIXME: ALLERT: This discriminates between master and slave! */
-	return &ch->drives[DEVICE_NR(dev) & 1].queue;
+	return &ch->drives[(minor(dev) >> PARTN_BITS) & 1].queue;
 }
 
 static void channel_init(struct ata_channel *ch)
diff -ur linux-2.5.12/drivers/md/lvm.c linux/drivers/md/lvm.c
--- linux-2.5.12/drivers/md/lvm.c	2002-05-01 02:08:46.000000000 +0200
+++ linux/drivers/md/lvm.c	2002-05-02 03:55:34.000000000 +0200
@@ -192,7 +192,6 @@
 
 #define MAJOR_NR LVM_BLK_MAJOR
 #define DEVICE_OFF(device)
-#define LOCAL_END_REQUEST
 
 /* lvm_do_lv_create calls fsync_dev_lockfs()/unlockfs() */
 /* #define	LVM_VFS_ENHANCEMENT */
diff -ur linux-2.5.12/drivers/md/md.c linux/drivers/md/md.c
--- linux-2.5.12/drivers/md/md.c	2002-05-01 02:08:51.000000000 +0200
+++ linux/drivers/md/md.c	2002-05-02 02:55:39.000000000 +0200
@@ -4004,9 +4004,8 @@
 #endif
 
 	del_gendisk(&md_gendisk);
-	blk_dev[MAJOR_NR].queue = NULL;
 	blk_clear(MAJOR_NR);
-	
+
 	free_device_names();
 }
 #endif
diff -ur linux-2.5.12/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c
--- linux-2.5.12/drivers/mtd/mtdblock.c	2002-05-01 02:08:55.000000000 +0200
+++ linux/drivers/mtd/mtdblock.c	2002-05-02 03:57:14.000000000 +0200
@@ -23,11 +23,7 @@
 #ifndef QUEUE_EMPTY
 #define QUEUE_EMPTY  (!CURRENT)
 #endif
-#if LINUX_VERSION_CODE < 0x20300
-#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync)
-#else
 #define QUEUE_PLUGGED (blk_queue_plugged(QUEUE))
-#endif
 
 #ifdef CONFIG_DEVFS_FS
 #include <linux/devfs_fs_kernel.h>
diff -ur linux-2.5.12/drivers/mtd/mtdblock_ro.c linux/drivers/mtd/mtdblock_ro.c
--- linux-2.5.12/drivers/mtd/mtdblock_ro.c	2002-05-01 02:08:57.000000000 +0200
+++ linux/drivers/mtd/mtdblock_ro.c	2002-05-02 04:09:00.000000000 +0200
@@ -7,7 +7,7 @@
 
 #ifdef MTDBLOCK_DEBUG
 #define DEBUGLVL debug
-#endif							       
+#endif
 
 
 #include <linux/module.h>
@@ -16,7 +16,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/compatmac.h>
 
-#define LOCAL_END_REQUEST
 #define MAJOR_NR MTD_BLOCK_MAJOR
 #define DEVICE_NAME "mtdblock"
 #define DEVICE_NR(device) (device)
@@ -34,6 +33,7 @@
 MODULE_PARM(debug, "i");
 #endif
 
+static spinlock_t mtdro_lock;
 
 static int mtd_sizes[MAX_MTD_DEVICES];
 
@@ -106,7 +106,7 @@
 
 static void mtdblock_request(RQFUNC_ARG)
 {
-   struct request *current_request;
+   struct request *req;
    unsigned int res = 0;
    struct mtd_info *mtd;
 
@@ -115,50 +115,48 @@
       /* Grab the Request and unlink it from the request list, INIT_REQUEST
        	 will execute a return if we are done. */
       INIT_REQUEST;
-      current_request = CURRENT;
+      req = CURRENT;
    
-      if (minor(current_request->rq_dev) >= MAX_MTD_DEVICES)
+      if (minor(req->rq_dev) >= MAX_MTD_DEVICES)
       {
 	 printk("mtd: Unsupported device!\n");
-	 mtdblock_end_request(current_request, 0);
+	 mtdblock_end_request(req, 0);
 	 continue;
       }
       
       // Grab our MTD structure
 
-      mtd = __get_mtd_device(NULL, minor(current_request->rq_dev));
+      mtd = __get_mtd_device(NULL, minor(req->rq_dev));
       if (!mtd) {
 	      printk("MTD device %d doesn't appear to exist any more\n", CURRENT_DEV);
-	      mtdblock_end_request(current_request, 0);
+	      mtdblock_end_request(req, 0);
       }
 
-      if (current_request->sector << 9 > mtd->size ||
-	  (current_request->sector + current_request->nr_sectors) << 9 > mtd->size)
+      if (req->sector << 9 > mtd->size ||
+	  (req->sector + req->nr_sectors) << 9 > mtd->size)
       {
 	 printk("mtd: Attempt to read past end of device!\n");
-	 printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size, current_request->sector, current_request->nr_sectors);
-	 mtdblock_end_request(current_request, 0);
+	 printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size, req->sector, req->nr_sectors);
+	 mtdblock_end_request(req, 0);
 	 continue;
       }
       
       /* Remove the request we are handling from the request list so nobody messes
          with it */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
       /* Now drop the lock that the ll_rw_blk functions grabbed for us
          and process the request. This is necessary due to the extreme time
          we spend processing it. */
-      spin_unlock_irq(&io_request_lock);
-#endif
+      spin_unlock_irq(&mtdro_lock);
 
       // Handle the request
-      switch (current_request->cmd)
+      switch (rq_data_dir(req))
       {
          size_t retlen;
 
 	 case READ:
-	 if (MTD_READ(mtd,current_request->sector<<9, 
-		      current_request->nr_sectors << 9, 
-		      &retlen, current_request->buffer) == 0)
+	 if (MTD_READ(mtd,req->sector<<9, 
+		      req->nr_sectors << 9, 
+		      &retlen, req->buffer) == 0)
 	    res = 1;
 	 else
 	    res = 0;
@@ -166,8 +164,8 @@
 	 
 	 case WRITE:
 
-	 /* printk("mtdblock_request WRITE sector=%d(%d)\n",current_request->sector,
-		current_request->nr_sectors);
+	 /* printk("mtdblock_request WRITE sector=%d(%d)\n",req->sector,
+		req->nr_sectors);
 	 */
 
 	 // Read only device
@@ -178,9 +176,9 @@
 	 }
 
 	 // Do the write
-	 if (MTD_WRITE(mtd,current_request->sector<<9, 
-		       current_request->nr_sectors << 9, 
-		       &retlen, current_request->buffer) == 0)
+	 if (MTD_WRITE(mtd,req->sector<<9, 
+		       req->nr_sectors << 9, 
+		       &retlen, req->buffer) == 0)
 	    res = 1;
 	 else
 	    res = 0;
@@ -193,10 +191,8 @@
       }
 
       // Grab the lock and re-thread the item onto the linked list
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-	spin_lock_irq(&io_request_lock);
-#endif
-	mtdblock_end_request(current_request, res);
+	spin_lock_irq(&mtdro_lock);
+	mtdblock_end_request(req, res);
    }
 }
 
@@ -255,6 +251,7 @@
 {
 	int i;
 
+	spin_lock_init(&mtdro_lock);
 	if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
 		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
 		       MTD_BLOCK_MAJOR);
@@ -270,7 +267,7 @@
 	blksize_size[MAJOR_NR] = NULL;
 	blk_size[MAJOR_NR] = mtd_sizes;
 	
-	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request, &mtdro_lock);
 	return 0;
 }
 
diff -ur linux-2.5.12/drivers/s390/block/dasd_int.h linux/drivers/s390/block/dasd_int.h
--- linux-2.5.12/drivers/s390/block/dasd_int.h	2002-05-01 02:09:00.000000000 +0200
+++ linux/drivers/s390/block/dasd_int.h	2002-05-02 02:46:23.000000000 +0200
@@ -61,47 +61,6 @@
 #include <asm/todclk.h>
 #include <asm/debug.h>
 
-/* Kernel Version Compatibility section */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98))
-typedef struct request *request_queue_t;
-#define block_device_operations file_operations
-#define __setup(x,y) struct dasd_device_t
-#define devfs_register_blkdev(major,name,ops) register_blkdev(major,name,ops)
-#define register_disk(dd,dev,partn,ops,size) \
-do { \
-	dd->sizes[MINOR(dev)] = size >> 1; \
-	resetup_one_dev(dd,MINOR(dev)>>DASD_PARTN_BITS); \
-} while(0)
-#define init_waitqueue_head(x) do { *x = NULL; } while(0)
-#define blk_cleanup_queue(x) do {} while(0)
-#define blk_init_queue(x...) do {} while(0)
-#define blk_queue_headactive(x...) do {} while(0)
-#define blk_queue_make_request(x) do {} while(0)
-#define list_empty(x) (0)
-#define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \
-do { \
-        blk_dev[d_major].request_fn = d_request_fn; \
-        blk_dev[d_major].queue = d_queue_fn; \
-        blk_dev[d_major].current_request = d_current; \
-} while(0)
-#define INIT_GENDISK(D_MAJOR,D_NAME,D_PARTN_BITS,D_PER_MAJOR) \
-	major:D_MAJOR, \
-	major_name:D_NAME, \
-	minor_shift:D_PARTN_BITS, \
-	max_nr:D_PER_MAJOR, \
-	nr_real:D_PER_MAJOR,
-static inline struct request * 
-dasd_next_request( request_queue_t *queue ) 
-{
-    return *queue;
-}
-static inline void 
-dasd_dequeue_request( request_queue_t * q, struct request *req )
-{
-        *q = req->next;
-        req->next = NULL;
-}
-#else
 #define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \
 do { \
         blk_dev[d_major].queue = d_queue_fn; \
@@ -111,18 +70,17 @@
 	major_name:D_NAME, \
 	minor_shift:D_PARTN_BITS, \
 	nr_real:D_PER_MAJOR, \
-        fops:&dasd_device_operations, 
-static inline struct request * 
-dasd_next_request( request_queue_t *queue ) 
+        fops:&dasd_device_operations,
+static inline struct request *
+dasd_next_request( request_queue_t *queue )
 {
         return elv_next_request(queue);
 }
-static inline void 
+static inline void
 dasd_dequeue_request( request_queue_t * q, struct request *req )
 {
         blkdev_dequeue_request (req);
 }
-#endif
 
 /* dasd_range_t are used for dynamic device att-/detachment */
 typedef struct dasd_devreg_t {
diff -ur linux-2.5.12/drivers/s390/block/xpram.c linux/drivers/s390/block/xpram.c
--- linux-2.5.12/drivers/s390/block/xpram.c	2002-05-01 02:09:00.000000000 +0200
+++ linux/drivers/s390/block/xpram.c	2002-05-02 02:48:12.000000000 +0200
@@ -1016,13 +1016,9 @@
 	 * arrays if it uses the default values.
 	 */
 
-#if (XPRAM_VERSION == 22)
-	blk_dev[major].request_fn = xpram_request;
-#elif (XPRAM_VERSION == 24)
 	q = BLK_DEFAULT_QUEUE (major);
 	blk_init_queue (q, xpram_request);
 	blk_queue_hardsect_size(q, xpram_hardsect);
-#endif /* V22/V24 */
 
 	/* we want to have XPRAM_UNUSED blocks security buffer between devices */
 	mem_usable=xpram_mem_avail-(XPRAM_UNUSED*(xpram_devs-1));
@@ -1148,9 +1144,6 @@
 	blksize_size[major] = NULL;
  fail_malloc_devices:
  fail_malloc:
-#if (XPRAM_VERSION == 22)
-	blk_dev[major].request_fn = NULL;
-#endif /* V22 */
 	/* ???	unregister_chrdev(major, "xpram"); */
 	unregister_blkdev(major, "xpram");
 	return result;
@@ -1180,9 +1173,6 @@
 
 	/* first of all, reset all the data structures */
 
-#if (XPRAM_VERSION == 22)
-	blk_dev[major].request_fn = NULL;
-#endif /* V22 */
 	kfree(blksize_size[major]);
 	kfree(xpram_offsets);
 	blk_clear(major);
diff -ur linux-2.5.12/drivers/s390/char/tapedefs.h linux/drivers/s390/char/tapedefs.h
--- linux-2.5.12/drivers/s390/char/tapedefs.h	2002-05-01 02:08:47.000000000 +0200
+++ linux/drivers/s390/char/tapedefs.h	2002-05-02 02:42:19.000000000 +0200
@@ -33,44 +33,17 @@
 #define TAPEBLOCK_RETRIES 20     // number of retries, when a block-dev request fails.
 
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
 #define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \
 do { \
         blk_dev[d_major].queue = d_queue_fn; \
 } while(0)
-static inline struct request * 
-tape_next_request( request_queue_t *queue ) 
+static inline struct request *
+tape_next_request( request_queue_t *queue )
 {
         return elv_next_request(queue);
 }
-static inline void 
+static inline void
 tape_dequeue_request( request_queue_t * q, struct request *req )
 {
         blkdev_dequeue_request (req);
 }
-#else 
-#define s390_dev_info_t dev_info_t
-typedef struct request *request_queue_t;
-#ifndef init_waitqueue_head
-#define init_waitqueue_head(x) do { *x = NULL; } while(0)
-#endif
-#define blk_init_queue(x,y) do {} while(0)
-#define blk_queue_headactive(x,y) do {} while(0)
-#define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \
-do { \
-        blk_dev[d_major].request_fn = d_request_fn; \
-        blk_dev[d_major].queue = d_queue_fn; \
-        blk_dev[d_major].current_request = d_current; \
-} while(0)
-static inline struct request *
-tape_next_request( request_queue_t *queue ) 
-{
-    return *queue;
-}
-static inline void 
-tape_dequeue_request( request_queue_t * q, struct request *req )
-{
-        *q = req->next;
-        req->next = NULL;
-}
-#endif 
diff -ur linux-2.5.12/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- linux-2.5.12/drivers/scsi/sr.c	2002-05-01 02:08:50.000000000 +0200
+++ linux/drivers/scsi/sr.c	2002-05-02 03:26:11.000000000 +0200
@@ -49,7 +49,6 @@
 #include <asm/uaccess.h>
 
 #define MAJOR_NR SCSI_CDROM_MAJOR
-#define LOCAL_END_REQUEST
 #include <linux/blk.h>
 #include "scsi.h"
 #include "hosts.h"
diff -ur linux-2.5.12/include/linux/blkdev.h linux/include/linux/blkdev.h
--- linux-2.5.12/include/linux/blkdev.h	2002-05-01 02:08:49.000000000 +0200
+++ linux/include/linux/blkdev.h	2002-05-02 02:55:24.000000000 +0200
@@ -336,6 +336,8 @@
 	blk_size_in_bytes[major] = NULL;
 #endif
 	blksize_size[major] = NULL;
+	blk_dev[major].queue = NULL;
+
 }
 
 extern inline int queue_hardsect_size(request_queue_t *q)
diff -ur linux-2.5.12/include/linux/blk.h linux/include/linux/blk.h
--- linux-2.5.12/include/linux/blk.h	2002-05-01 02:08:51.000000000 +0200
+++ linux/include/linux/blk.h	2002-05-02 04:17:46.000000000 +0200
@@ -97,19 +97,14 @@
 } while (0)
 
 #define elv_add_request(q, rq, back) _elv_add_request((q), (rq), (back), 1)
-	
-#if defined(MAJOR_NR) || defined(IDE_DRIVER)
+
+#if defined(MAJOR_NR)
 
 /*
  * Add entries as needed.
  */
 
-#ifdef IDE_DRIVER
-
-#define DEVICE_NR(device)	(minor(device) >> PARTN_BITS)
-#define DEVICE_NAME "ide"
-
-#elif (MAJOR_NR == RAMDISK_MAJOR)
+#if (MAJOR_NR == RAMDISK_MAJOR)
 
 /* ram disk */
 #define DEVICE_NAME "ramdisk"
@@ -291,7 +286,6 @@
 #endif /* MAJOR_NR == whatever */
 
 #if (MAJOR_NR != SCSI_TAPE_MAJOR) && (MAJOR_NR != OSST_MAJOR)
-#if !defined(IDE_DRIVER)
 
 #ifndef CURRENT
 #define CURRENT elv_next_request(&blk_dev[MAJOR_NR].request_queue)
@@ -330,12 +324,9 @@
 	if (!CURRENT->bio)					\
 		panic(DEVICE_NAME ": no bio");			\
 
-#endif /* !defined(IDE_DRIVER) */
-
 /*
- * If we have our own end_request, we do not want to include this mess
+ * Default end request handler for "legacy" drivers.
  */
-#ifndef LOCAL_END_REQUEST
 static inline void end_request(int uptodate)
 {
 	struct request *req = CURRENT;
@@ -347,8 +338,7 @@
 	blkdev_dequeue_request(req);
 	end_that_request_last(req);
 }
-#endif /* !LOCAL_END_REQUEST */
 #endif /* (MAJOR_NR != SCSI_TAPE_MAJOR) */
-#endif /* defined(MAJOR_NR) || defined(IDE_DRIVER) */
+#endif /* defined(MAJOR_NR) */
 
 #endif /* _BLK_H */
diff -ur linux-2.5.12/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.12/include/linux/ide.h	2002-05-01 02:08:49.000000000 +0200
+++ linux/include/linux/ide.h	2002-05-02 04:18:23.000000000 +0200
@@ -642,13 +640,6 @@
 extern struct ata_channel ide_hwifs[];		/* master data repository */
 extern int noautodma;
 
-/*
- * We need blk.h, but we replace its end_request by our own version.
- */
-#define IDE_DRIVER		/* Toggle some magic bits in blk.h */
-#define LOCAL_END_REQUEST	/* Don't generate end_request in blk.h */
-#include <linux/blk.h>
-
 extern int __ide_end_request(struct ata_device *, struct request *, int, int);
 extern int ide_end_request(struct ata_device *drive, struct request *, int);
 
diff -ur linux-2.5.12/include/linux/nbd.h linux/include/linux/nbd.h
--- linux-2.5.12/include/linux/nbd.h	2002-05-01 02:09:01.000000000 +0200
+++ linux/include/linux/nbd.h	2002-05-02 04:22:03.000000000 +0200
@@ -25,8 +25,6 @@
 #include <linux/locks.h>
 #include <asm/semaphore.h>
 
-#define LOCAL_END_REQUEST
-
 #include <linux/blk.h>
 
 #ifdef PARANOIA

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

* Re: Linux 2.5.7
  2002-05-02 13:22   ` Dave Jones
@ 2002-05-02 12:44     ` Martin Dalecki
  2002-05-02 13:54       ` David Woodhouse
  0 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-05-02 12:44 UTC (permalink / raw)
  To: Dave Jones; +Cc: Linus Torvalds, Kernel Mailing List, dwmw2

Uz.ytkownik Dave Jones napisa?:
> On Thu, May 02, 2002 at 10:42:54AM +0200, Martin Dalecki wrote:
> 
>  > -   struct request *current_request;
>  > +   struct request *req;
>  >     unsigned int res = 0;
>  >     struct mtd_info *mtd;
> 
> This gratuitous change makes life a lot more irritating when bring
> forward fixes from 2.4. They now need an extra pass to go through
> and munge all the varnames. Or are you proposing the same change
> for 2.4 ?
>  

No I was consciuous: I just saw some macro preprocessing
clashes.


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

* Re: Linux 2.5.7
  2002-05-02 13:54       ` David Woodhouse
@ 2002-05-02 13:02         ` Martin Dalecki
  2002-05-02 14:06           ` David Woodhouse
  0 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-05-02 13:02 UTC (permalink / raw)
  To: David Woodhouse; +Cc: Dave Jones, Linus Torvalds, Kernel Mailing List

Uz.ytkownik David Woodhouse napisa?:
> dalecki@evision-ventures.com said:
> 
>> No I was consciuous: I just saw some macro preprocessing clashes. 
> 
> 
> But not conscious enough to bother to Cc the maintainer or explain the 
> clashes you saw?

You saw it so what's the problem? ;-).



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

* Re: Linux 2.5.7
  2002-05-02  8:42 ` Linux 2.5.7 Martin Dalecki
@ 2002-05-02 13:22   ` Dave Jones
  2002-05-02 12:44     ` Martin Dalecki
  0 siblings, 1 reply; 39+ messages in thread
From: Dave Jones @ 2002-05-02 13:22 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, Kernel Mailing List, dwmw2

On Thu, May 02, 2002 at 10:42:54AM +0200, Martin Dalecki wrote:

 > -   struct request *current_request;
 > +   struct request *req;
 >     unsigned int res = 0;
 >     struct mtd_info *mtd;

This gratuitous change makes life a lot more irritating when bring
forward fixes from 2.4. They now need an extra pass to go through
and munge all the varnames. Or are you proposing the same change
for 2.4 ?
 
-- 
| Dave Jones.        http://www.codemonkey.org.uk
| SuSE Labs

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

* Re: Linux 2.5.7
  2002-05-02 12:44     ` Martin Dalecki
@ 2002-05-02 13:54       ` David Woodhouse
  2002-05-02 13:02         ` Martin Dalecki
  0 siblings, 1 reply; 39+ messages in thread
From: David Woodhouse @ 2002-05-02 13:54 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Dave Jones, Linus Torvalds, Kernel Mailing List


dalecki@evision-ventures.com said:
>  No I was consciuous: I just saw some macro preprocessing clashes. 

But not conscious enough to bother to Cc the maintainer or explain the 
clashes you saw?

Do what you like; I'm ignoring 2.5 until Marcelo gets 2.4.19 out and I can
send him the rest of the code I'm sitting on for 2.4.20-pre1; at which point
I'll update everything in my tree to build against 2.5 and require magic in
compatmac.h for the 2.4 build, and I'll look at what's changed then.

--
dwmw2



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

* Re: Linux 2.5.7
  2002-05-02 13:02         ` Martin Dalecki
@ 2002-05-02 14:06           ` David Woodhouse
  0 siblings, 0 replies; 39+ messages in thread
From: David Woodhouse @ 2002-05-02 14:06 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Dave Jones, Kernel Mailing List


dalecki@evision-ventures.com said:
>  You saw it so what's the problem? ;-).

I saw it because someone did me the courtesy of adding me to the Cc: list.

Please consider doing that yourself in future.

--
dwmw2



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

* [PATCH] 2.5.13 IDE 50
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (15 preceding siblings ...)
  2002-05-02  8:42 ` Linux 2.5.7 Martin Dalecki
@ 2002-05-03 12:59 ` Martin Dalecki
  2002-05-03 18:12   ` Tim Schmielau
  2002-05-03 14:48 ` [PATCH] 2.5.13 IDE 51 Martin Dalecki
  17 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-05-03 12:59 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List

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

Thu May  2 11:53:59 CEST 2002 ide-clean-50

Sync up with 2.5.13.

- Fix wrong usage of time_after in ide.c. This should cure the drive seek
   timeout problems some people where expierencing. This was clarified to me by
   Bartek, who apparently checked whatever the actual code is consistent with
   the comments in front of it. Thank you Bartlomiej Zolnierkiewicz.

   I think now that we should have time_past(xxx) in <linux/timer.h>.

- Fix hpt34x.c compilation.

- Minor improvements in ide-pci and some cleanups in ide-probe.c

- Nuke some vastly outdated comments.

[-- Attachment #2: ide-clean-50.diff --]
[-- Type: text/plain, Size: 39199 bytes --]

diff -urN linux-2.5.13/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- linux-2.5.13/drivers/ide/hpt34x.c	2002-05-03 02:22:41.000000000 +0200
+++ linux/drivers/ide/hpt34x.c	2002-05-03 13:32:07.000000000 +0200
@@ -249,14 +249,14 @@
 						     ide_dma_off_quietly);
 }
 
-static int config_drive_xfer_rate (ide_drive_t *drive)
+static int config_drive_xfer_rate(struct ata_device *drive, struct request *rq)
 {
 	struct hd_driveid *id = drive->id;
 	ide_dma_action_t dma_func = ide_dma_on;
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
+		if (ide_dmaproc(ide_dma_bad_drive, drive, rq)) {
 			dma_func = ide_dma_off;
 			goto fast_ata_pio;
 		}
@@ -278,7 +278,7 @@
 				if (dma_func != ide_dma_on)
 					goto no_dma_set;
 			}
-		} else if (ide_dmaproc(ide_dma_good_drive, drive)) {
+		} else if (ide_dmaproc(ide_dma_good_drive, drive, rq)) {
 			if (id->eide_dma_time > 150) {
 				goto no_dma_set;
 			}
@@ -301,7 +301,7 @@
 		dma_func = ide_dma_off;
 #endif /* CONFIG_HPT34X_AUTODMA */
 
-	return drive->channel->dmaproc(dma_func, drive);
+	return drive->channel->udma(dma_func, drive, rq);
 }
 
 /*
@@ -312,7 +312,7 @@
  * by HighPoint|Triones Technologies, Inc.
  */
 
-int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+int hpt34x_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
 	struct ata_channel *hwif = drive->channel;
 	unsigned long dma_base = hwif->dma_base;
@@ -321,7 +321,7 @@
 
 	switch (func) {
 		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
+			return config_drive_xfer_rate(drive, rq);
 		case ide_dma_read:
 			reading = 1 << 3;
 		case ide_dma_write:
@@ -347,7 +347,7 @@
 		default:
 			break;
 	}
-	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
+	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
@@ -423,7 +423,7 @@
 		else
 			hwif->autodma = 0;
 
-		hwif->dmaproc = &hpt34x_dmaproc;
+		hwif->udma = &hpt34x_dmaproc;
 		hwif->highmem = 1;
 	} else {
 		hwif->drives[0].autotune = 1;
diff -urN linux-2.5.13/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.13/drivers/ide/ide.c	2002-05-03 02:22:52.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-05-03 13:29:23.000000000 +0200
@@ -1,15 +1,19 @@
-/*
- *  Copyright (C) 1994-1998  Linus Torvalds & authors (see below)
+/**** vi:set ts=8 sts=8 sw=8:************************************************
+ *
+ *  Copyright (C) 1994-1998,2002  Linus Torvalds and authors:
  *
- *  Mostly written by Mark Lord  <mlord@pobox.com>
- *                and Gadi Oxman <gadio@netvision.net.il>
- *                and Andre Hedrick <andre@linux-ide.org>
+ *	Mark Lord	<mlord@pobox.com>
+ *      Gadi Oxman	<gadio@netvision.net.il>
+ *      Andre Hedrick	<andre@linux-ide.org>
+ *	Jens Axboe	<axboe@suse.de>
+ *      Marcin Dalecki	<martin@dalecki.de>
  *
  *  See linux/MAINTAINERS for address of current maintainer.
  *
- * This is the multiple IDE interface driver, as evolved from hd.c.
- * It supports up to MAX_HWIFS IDE interfaces, on one or more IRQs (usually 14 & 15).
- * There can be up to two drives per interface, as per the ATA-2 spec.
+ * This is the basic common code of the ATA interface drivers.
+ *
+ * It supports up to MAX_HWIFS IDE interfaces, on one or more IRQs (usually 14
+ * & 15).  There can be up to two drives per interface, as per the ATA-7 spec.
  *
  * Primary:    ide0, port 0x1f0; major=3;  hda is minor=0; hdb is minor=64
  * Secondary:  ide1, port 0x170; major=22; hdc is minor=0; hdd is minor=64
@@ -17,102 +21,15 @@
  * Quaternary: ide3, port 0x???; major=34; hdg is minor=0; hdh is minor=64
  * ...
  *
- *  From hd.c:
- *  |
- *  | It traverses the request-list, using interrupts to jump between functions.
- *  | As nearly all functions can be called within interrupts, we may not sleep.
- *  | Special care is recommended.  Have Fun!
- *  |
- *  | modified by Drew Eckhardt to check nr of hd's from the CMOS.
- *  |
- *  | Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
- *  | in the early extended-partition checks and added DM partitions.
- *  |
- *  | Early work on error handling by Mika Liljeberg (liljeber@cs.Helsinki.FI).
- *  |
- *  | IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
- *  | and general streamlining by Mark Lord (mlord@pobox.com).
- *
- *  October, 1994 -- Complete line-by-line overhaul for linux 1.1.x, by:
- *
- *	Mark Lord	(mlord@pobox.com)		(IDE Perf.Pkg)
- *	Delman Lee	(delman@ieee.org)		("Mr. atdisk2")
- *	Scott Snyder	(snyder@fnald0.fnal.gov)	(ATAPI IDE cd-rom)
- *
- *  This was a rewrite of just about everything from hd.c, though some original
- *  code is still sprinkled about.  Think of it as a major evolution, with
- *  inspiration from lots of linux users, esp.  hamish@zot.apana.org.au
- *
- *  Version 1.0 ALPHA	initial code, primary i/f working okay
- *  Version 1.3 BETA	dual i/f on shared irq tested & working!
- *  Version 1.4 BETA	added auto probing for irq(s)
- *  Version 1.5 BETA	added ALPHA (untested) support for IDE cd-roms,
- *  ...
- * Version 5.50		allow values as small as 20 for idebus=
- * Version 5.51		force non io_32bit in drive_cmd_intr()
- *			change delay_10ms() to delay_50ms() to fix problems
- * Version 5.52		fix incorrect invalidation of removable devices
- *			add "hdx=slow" command line option
- * Version 5.60		start to modularize the driver; the disk and ATAPI
- *			 drivers can be compiled as loadable modules.
- *			move IDE probe code to ide-probe.c
- *			move IDE disk code to ide-disk.c
- *			add support for generic IDE device subdrivers
- *			add m68k code from Geert Uytterhoeven
- *			probe all interfaces by default
- *			add ioctl to (re)probe an interface
- * Version 6.00		use per device request queues
- *			attempt to optimize shared hwgroup performance
- *			add ioctl to manually adjust bandwidth algorithms
- *			add kerneld support for the probe module
- *			fix bug in ide_error()
- *			fix bug in the first ide_get_lock() call for Atari
- *			don't flush leftover data for ATAPI devices
- * Version 6.01		clear hwgroup->active while the hwgroup sleeps
- *			support HDIO_GETGEO for floppies
- * Version 6.02		fix ide_ack_intr() call
- *			check partition table on floppies
- * Version 6.03		handle bad status bit sequencing in ide_wait_stat()
- * Version 6.10		deleted old entries from this list of updates
- *			replaced triton.c with ide-dma.c generic PCI DMA
- *			added support for BIOS-enabled UltraDMA
- *			rename all "promise" things to "pdc4030"
- *			fix EZ-DRIVE handling on small disks
- * Version 6.11		fix probe error in ide_scan_devices()
- *			fix ancient "jiffies" polling bugs
- *			mask all hwgroup interrupts on each irq entry
- * Version 6.12		integrate ioctl and proc interfaces
- *			fix parsing of "idex=" command line parameter
- * Version 6.13		add support for ide4/ide5 courtesy rjones@orchestream.com
- * Version 6.14		fixed IRQ sharing among PCI devices
- * Version 6.15		added SMP awareness to IDE drivers
- * Version 6.16		fixed various bugs; even more SMP friendly
- * Version 6.17		fix for newest EZ-Drive problem
- * Version 6.18		default unpartitioned-disk translation now "BIOS LBA"
- * Version 6.19		Re-design for a UNIFORM driver for all platforms,
- *			  model based on suggestions from Russell King and
- *			  Geert Uytterhoeven
- *			Promise DC4030VL now supported.
- *			add support for ide6/ide7
- *			delay_50ms() changed to ide_delay_50ms() and exported.
- * Version 6.20		Added/Fixed Generic ATA-66 support and hwif detection.
- *			Added hdx=flash to allow for second flash disk
- *			  detection w/o the hang loop.
- *			Added support for ide8/ide9
- *			Added idex=ata66 for the quirky chipsets that are
- *			  ATA-66 compliant, but have yet to determine a method
- *			  of verification of the 80c cable presence.
- *			  Specifically Promise's PDC20262 chipset.
- * Version 6.21		Fixing/Fixed SMP spinlock issue with insight from an old
- *			  hat that clarified original low level driver design.
- * Version 6.30		Added SMP support; fixed multmode issues.  -ml
- * Version 6.31		Debug Share INTR's and request queue streaming
- *			Native ATA-100 support
- *			Prep for Cascades Project
- * Version 6.32		4GB highmem support for DMA, and mapping of those for
- *			PIO transfer (Jens Axboe)
+ *  Contributors:
+ *
+ *	Drew Eckhardt
+ *	Branko Lankester	<lankeste@fwi.uva.nl>
+ *	Mika Liljeberg
+ *	Delman Lee		<delman@ieee.org>
+ *	Scott Snyder		<snyder@fnald0.fnal.gov>
  *
- *  Some additional driver compile-time options are in ./include/linux/ide.h
+ *  Some additional driver compile-time options are in <linux/ide.h>
  */
 
 #define	VERSION	"7.0.0"
@@ -253,10 +170,7 @@
 #endif
 }
 
-/*
- * Do not even *think* about calling this!
- */
-static void init_hwif_data(struct ata_channel *hwif, unsigned int index)
+static void init_hwif_data(struct ata_channel *ch, unsigned int index)
 {
 	static const byte ide_major[] = {
 		IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR,
@@ -266,30 +180,30 @@
 	unsigned int unit;
 	hw_regs_t hw;
 
-	/* bulk initialize hwif & drive info with zeros */
-	memset(hwif, 0, sizeof(struct ata_channel));
+	/* bulk initialize channel & drive info with zeros */
+	memset(ch, 0, sizeof(struct ata_channel));
 	memset(&hw, 0, sizeof(hw_regs_t));
 
 	/* fill in any non-zero initial values */
-	hwif->index     = index;
-	ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);
-	memcpy(&hwif->hw, &hw, sizeof(hw));
-	memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
-	hwif->noprobe	= !hwif->io_ports[IDE_DATA_OFFSET];
+	ch->index     = index;
+	ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &ch->irq);
+	memcpy(&ch->hw, &hw, sizeof(hw));
+	memcpy(ch->io_ports, hw.io_ports, sizeof(hw.io_ports));
+	ch->noprobe	= !ch->io_ports[IDE_DATA_OFFSET];
 #ifdef CONFIG_BLK_DEV_HD
-	if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA)
-		hwif->noprobe = 1; /* may be overridden by ide_setup() */
+	if (ch->io_ports[IDE_DATA_OFFSET] == HD_DATA)
+		ch->noprobe = 1; /* may be overridden by ide_setup() */
 #endif /* CONFIG_BLK_DEV_HD */
-	hwif->major = ide_major[index];
-	sprintf(hwif->name, "ide%d", index);
-	hwif->bus_state = BUSSTATE_ON;
+	ch->major = ide_major[index];
+	sprintf(ch->name, "ide%d", index);
+	ch->bus_state = BUSSTATE_ON;
 
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		struct ata_device *drive = &hwif->drives[unit];
+		struct ata_device *drive = &ch->drives[unit];
 
 		drive->type			= ATA_DISK;
 		drive->select.all		= (unit<<4)|0xa0;
-		drive->channel			= hwif;
+		drive->channel			= ch;
 		drive->ctl			= 0x08;
 		drive->ready_stat		= READY_STAT;
 		drive->bad_wstat		= BAD_W_STAT;
@@ -1258,7 +1172,7 @@
 
 			/* This device still wants to remain idle.
 			 */
-			if (drive->sleep && time_after(jiffies, drive->sleep))
+			if (drive->sleep && time_after(drive->sleep, jiffies))
 				continue;
 
 			/* Take this device, if there is no device choosen thus far or
@@ -1285,8 +1199,8 @@
 		 * want to hog the cpu too much.
 		 */
 
-		if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep))
-		    sleep = jiffies + WAIT_MIN_SLEEP;
+		if (time_after(jiffies, sleep - WAIT_MIN_SLEEP))
+			sleep = jiffies + WAIT_MIN_SLEEP;
 #if 1
 		if (timer_pending(&channel->hwgroup->timer))
 			printk(KERN_ERR "ide_set_handler: timer already active\n");
@@ -2861,7 +2775,7 @@
  * "hdx=flash"		: allows for more than one ata_flash disk to be
  *				registered. In most cases, only one device
  *				will be present.
- * "hdx=scsi"		: the return of the ide-scsi flag, this is useful for
+ * "hdx=ide-scsi"	: the return of the ide-scsi flag, this is useful for
  *				allowwing ide-floppy, ide-tape, and ide-cdrom|writers
  *				to use ide-scsi emulation on a device specific option.
  * "idebus=xx"		: inform IDE driver of VESA/PCI bus speed in MHz,
@@ -2928,14 +2842,14 @@
 	    strncmp(s,"hd",2))		/* hdx= & hdxlun= */
 		return 0;
 
-	printk("ide_setup: %s", s);
+	printk(KERN_INFO  "ide_setup: %s", s);
 	init_ide_data ();
 
 #ifdef CONFIG_BLK_DEV_IDEDOUBLER
 	if (!strcmp(s, "ide=doubler")) {
 		extern int ide_doubler;
 
-		printk(" : Enabled support for IDE doublers\n");
+		printk(KERN_INFO" : Enabled support for IDE doublers\n");
 		ide_doubler = 1;
 
 		return 1;
@@ -2943,7 +2857,7 @@
 #endif
 
 	if (!strcmp(s, "ide=nodma")) {
-		printk("IDE: Prevented DMA\n");
+		printk(KERN_INFO "ATA: Prevented DMA\n");
 		noautodma = 1;
 
 		return 1;
@@ -3497,7 +3411,7 @@
 {
 	int h;
 
-	printk(KERN_INFO "Uniform Multi-Platform E-IDE driver ver.:" VERSION "\n");
+	printk(KERN_INFO "ATA/ATAPI driver v" VERSION "\n");
 
 	ide_devfs_handle = devfs_mk_dir (NULL, "ide", NULL);
 
@@ -3519,7 +3433,7 @@
 	    system_bus_speed = 33;
 #endif
 
-	printk("ide: system bus speed %dMHz\n", system_bus_speed);
+	printk(KERN_INFO "ATA: system bus speed %dMHz\n", system_bus_speed);
 
 	init_ide_data ();
 
@@ -3640,27 +3554,23 @@
 MODULE_PARM(options,"s");
 MODULE_LICENSE("GPL");
 
-static void __init parse_options (char *line)
+static int __init init_ata(void)
 {
-	char *next = line;
 
-	if (line == NULL || !*line)
-		return;
-	while ((line = next) != NULL) {
-		if ((next = strchr(line,' ')) != NULL)
-			*next++ = 0;
-		if (!ide_setup(line))
-			printk ("Unknown option '%s'\n", line);
-	}
-}
+	if (options != NULL && *options) {
+		char *next = options;
 
-static int __init init_ata (void)
-{
-	parse_options(options);
+		while ((options = next) != NULL) {
+			if ((next = strchr(options,' ')) != NULL)
+				*next++ = 0;
+			if (!ide_setup(options))
+				printk(KERN_ERR "Unknown option '%s'\n", options);
+		}
+	}
 	return ata_module_init();
 }
 
-static void __exit cleanup_ata (void)
+static void __exit cleanup_ata(void)
 {
 	int h;
 
diff -urN linux-2.5.13/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.13/drivers/ide/ide-disk.c	2002-05-03 02:22:38.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-05-03 13:29:23.000000000 +0200
@@ -1,11 +1,12 @@
-/*
- *  Copyright (C) 1994-1998  Linus Torvalds and authors:
+/***** vi:set ts=8 sts=8 sw=8:************************************************
+ *
+ *  Copyright (C) 1994-1998,2002  Linus Torvalds and authors:
  *
- *	Mark Lord <mlord@pobox.com>
- *	Gadi Oxman <gadio@netvision.net.il>
- *	Andre Hedrick <andre@linux-ide.org>
- *	Jens Axboe <axboe@suse.de>
- *	Marcin Dalecki <dalecki@evision.ag>
+ *	Mark Lord	<mlord@pobox.com>
+ *	Gadi Oxman	<gadio@netvision.net.il>
+ *	Andre Hedrick	<andre@linux-ide.org>
+ *	Jens Axboe	<axboe@suse.de>
+ *	Marcin Dalecki	<martin@dalecki.de>
  *
  * This is the ATA disk device driver, as evolved from hd.c and ide.c.
  */
diff -urN linux-2.5.13/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- linux-2.5.13/drivers/ide/ide-pci.c	2002-05-03 02:22:56.000000000 +0200
+++ linux/drivers/ide/ide-pci.c	2002-05-03 14:19:57.000000000 +0200
@@ -1,6 +1,8 @@
-/*
- *  Copyright (c) 1998-2000  Andre Hedrick <andre@linux-ide.org>
- *  Copyright (c) 1995-1998  Mark Lord
+/**** vi:set ts=8 sts=8 sw=8:************************************************
+ *
+ *  Copyright (C) 2002	     Marcin Dalecki <martin@dalecki.de>
+ *  Copyright (C) 1998-2000  Andre Hedrick <andre@linux-ide.org>
+ *  Copyright (C) 1995-1998  Mark Lord
  *
  *  May be copied or modified under the terms of the GNU General Public License
  */
@@ -81,17 +83,10 @@
 #endif
 
 #ifdef CONFIG_BLK_DEV_HPT366
-extern byte hpt363_shared_irq;
-extern byte hpt363_shared_pin;
-
 extern unsigned int pci_init_hpt366(struct pci_dev *);
 extern unsigned int ata66_hpt366(struct ata_channel *);
 extern void ide_init_hpt366(struct ata_channel *);
 extern void ide_dmacapable_hpt366(struct ata_channel *, unsigned long);
-#else
-/* FIXME: those have to be killed */
-static byte hpt363_shared_irq;
-static byte hpt363_shared_pin;
 #endif
 
 #ifdef CONFIG_BLK_DEV_NS87415
@@ -177,7 +172,7 @@
 #define ATA_F_PHACK	0x40	/* apply PROMISE hacks */
 #define ATA_F_HPTHACK	0x80	/* apply HPT366 hacks */
 
-typedef struct ide_pci_device_s {
+struct ata_pci_device {
 	unsigned short		vendor;
 	unsigned short		device;
 	unsigned int		(*init_chipset)(struct pci_dev *dev);
@@ -188,9 +183,9 @@
 	unsigned int		bootable;
 	unsigned int		extra;
 	unsigned int		flags;
-} ide_pci_device_t;
+};
 
-static ide_pci_device_t pci_chipsets[] __initdata = {
+static struct ata_pci_device pci_chipsets[] __initdata = {
 #ifdef CONFIG_BLK_DEV_PIIX
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
@@ -319,7 +314,7 @@
  * settings of split-mirror pci-config space, place chipset into init-mode,
  * and/or preserve an interrupt if the card is not native ide support.
  */
-static unsigned int __init trust_pci_irq(ide_pci_device_t *d, struct pci_dev *dev)
+static unsigned int __init trust_pci_irq(struct ata_pci_device *d, struct pci_dev *dev)
 {
 	if (d->flags & ATA_F_IRQ)
 		return dev->irq;
@@ -484,7 +479,7 @@
  * Setup DMA transfers on a channel.
  */
 static void __init setup_channel_dma(struct ata_channel *hwif, struct pci_dev *dev,
-		ide_pci_device_t *d,
+		struct ata_pci_device *d,
 		int port,
 		u8 class_rev,
 		int pciirq,
@@ -534,7 +529,7 @@
  * This gets called once for the master and for the slave interface.
  */
 static int __init setup_host_channel(struct pci_dev *dev,
-		ide_pci_device_t *d,
+		struct ata_pci_device *d,
 		int port,
 		u8 class_rev,
 		int pciirq,
@@ -648,17 +643,16 @@
 }
 
 /*
- * Looks at the primary/secondary channels on a PCI IDE device and, if they
- * are enabled, prepares the IDE driver for use with them.  This generic code
- * works for most PCI chipsets.
+ * Looks at the primary/secondary channels on a PCI IDE device and, if they are
+ * enabled, prepares the IDE driver for use with them.  This generic code works
+ * for most PCI chipsets.
  *
  * One thing that is not standardized is the location of the primary/secondary
  * interface "enable/disable" bits.  For chipsets that we "know" about, this
- * information is in the ide_pci_device_t struct; for all other chipsets, we
- * just assume both interfaces are enabled.
+ * information is in the struct ata_pci_device struct; for all other chipsets,
+ * we just assume both interfaces are enabled.
  */
-
-static void __init setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
+static void __init setup_pci_device(struct pci_dev *dev, struct ata_pci_device *d)
 {
 	int autodma = 0;
 	int pciirq = 0;
@@ -775,10 +769,11 @@
 	setup_host_channel(dev, d, ATA_SECONDARY, class_rev, pciirq, autodma, &pcicmd);
 }
 
-static void __init pdc20270_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d)
+static void __init pdc20270_device_order_fixup (struct pci_dev *dev, struct ata_pci_device *d)
 {
-	struct pci_dev *dev2 = NULL, *findev;
-	ide_pci_device_t *d2;
+	struct pci_dev *dev2 = NULL;
+	struct pci_dev *findev;
+	struct ata_pci_device *d2;
 
 	if (dev->bus->self &&
 	    dev->bus->self->vendor == PCI_VENDOR_ID_DEC &&
@@ -814,10 +809,10 @@
 	setup_pci_device(dev2, d2);
 }
 
-static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d)
+static void __init hpt366_device_order_fixup (struct pci_dev *dev, struct ata_pci_device *d)
 {
 	struct pci_dev *dev2 = NULL, *findev;
-	ide_pci_device_t *d2;
+	struct ata_pci_device *d2;
 	unsigned char pin1 = 0, pin2 = 0;
 	unsigned int class_rev;
 
@@ -843,9 +838,7 @@
 		    (PCI_FUNC(findev->devfn) & 1)) {
 			dev2 = findev;
 			pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
-			hpt363_shared_pin = (pin1 != pin2) ? 1 : 0;
-			hpt363_shared_irq = (dev->irq == dev2->irq) ? 1 : 0;
-			if (hpt363_shared_pin && hpt363_shared_irq) {
+			if ((pin1 != pin2) && (dev->irq == dev2->irq)) {
 				d->bootable = ON_BOARD;
 				printk("%s: onboard version of chipset, pin1=%d pin2=%d\n", dev->name, pin1, pin2);
 			}
@@ -869,7 +862,7 @@
 {
 	unsigned short vendor;
 	unsigned short device;
-	ide_pci_device_t *d;
+	struct ata_pci_device *d;
 
 	vendor = dev->vendor;
 	device = dev->device;
@@ -881,7 +874,7 @@
 		++d;
 
 	if (d->init_channel == ATA_PCI_IGNORE)
-		printk("%s: has been ignored by PCI bus scan\n", dev->name);
+		printk(KERN_INFO "ATA: %s: ignored by PCI bus scan\n", dev->name);
 	else if ((d->vendor == PCI_VENDOR_ID_OPTI && d->device == PCI_DEVICE_ID_OPTI_82C558) && !(PCI_FUNC(dev->devfn) & 1))
 		return;
 	else if ((d->vendor == PCI_VENDOR_ID_CONTAQ && d->device == PCI_DEVICE_ID_CONTAQ_82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))
@@ -896,10 +889,10 @@
 		pdc20270_device_order_fixup(dev, d);
 	else if (!(d->vendor == 0 && d->device == 0) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
 		if (d->vendor == 0 && d->device == 0)
-			printk("%s: unknown IDE controller on PCI slot %s, vendor=%04x, device=%04x\n",
-			       dev->name, dev->slot_name, vendor, device);
+			printk(KERN_INFO "ATA: unknown ATA interface %s (%04x:%04x) on PCI slot %s\n",
+			       dev->name, vendor, device, dev->slot_name);
 		else
-			printk("%s: IDE controller on PCI slot %s\n", dev->name, dev->slot_name);
+			printk(KERN_INFO "ATA: interface %s on PCI slot %s\n", dev->name, dev->slot_name);
 		setup_pci_device(dev, d);
 	}
 }
diff -urN linux-2.5.13/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.13/drivers/ide/ide-probe.c	2002-05-03 02:22:37.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-05-03 15:18:13.000000000 +0200
@@ -1,4 +1,5 @@
-/*
+/**** vi:set ts=8 sts=8 sw=8:************************************************
+ *
  *  Copyright (C) 1994-1998  Linus Torvalds & authors (see below)
  *
  *  Mostly written by Mark Lord <mlord@pobox.com>
@@ -47,7 +48,7 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-static inline void do_identify (ide_drive_t *drive, byte cmd)
+static inline void do_identify(struct ata_device *drive, u8 cmd)
 {
 	int bswap = 1;
 	struct hd_driveid *id;
@@ -121,7 +122,7 @@
 	drive->present = 1;
 
 	/*
-	 * Check for an ATAPI device
+	 * Check for an ATAPI device:
 	 */
 	if (cmd == WIN_PIDENTIFY) {
 		byte type = (id->config >> 8) & 0x1f;
@@ -172,7 +173,7 @@
 	}
 
 	/*
-	 * Not an ATAPI device: looks like a "regular" hard disk
+	 * Not an ATAPI device: looks like a "regular" hard disk:
 	 */
 	if (id->config & (1<<7))
 		drive->removable = 1;
@@ -185,7 +186,7 @@
 	 */
 
 	if (drive_is_flashcard(drive)) {
-		ide_drive_t *mate = &drive->channel->drives[1 ^ drive->select.b.unit];
+		struct ata_device *mate = &drive->channel->drives[1 ^ drive->select.b.unit];
 		if (!mate->ata_flash) {
 			mate->present = 0;
 			mate->noprobe = 1;
@@ -204,26 +205,37 @@
 	kfree(id);
 err_kmalloc:
 	drive->present = 0;
+
 	return;
 }
 
 /*
- * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive
- * and waits for a response.  It also monitors irqs while this is
- * happening, in hope of automatically determining which one is
- * being used by the interface.
+ * Sends an ATA(PI) IDENTIFY request to a drive and wait for a response.  It
+ * also monitor irqs while this is happening, in hope of automatically
+ * determining which one is being used by the interface.
  *
  * Returns:	0  device was identified
  *		1  device timed-out (no response to identify request)
  *		2  device aborted the command (refused to identify itself)
  */
-static int actual_try_to_identify (ide_drive_t *drive, byte cmd)
+static int identify(struct ata_device *drive, u8 cmd)
 {
 	int rc;
+	int autoprobe = 0;
+	unsigned long cookie = 0;
 	ide_ioreg_t hd_status;
 	unsigned long timeout;
-	byte s, a;
+	u8 s;
+	u8 a;
+
+
+	if (IDE_CONTROL_REG && !drive->channel->irq) {
+		autoprobe = 1;
+		cookie = probe_irq_on();
+		OUT_BYTE(drive->ctl,IDE_CONTROL_REG);	/* enable device irq */
+	}
 
+	rc = 1;
 	if (IDE_CONTROL_REG) {
 		/* take a deep breath */
 		ide_delay_50ms();
@@ -247,19 +259,18 @@
 #if CONFIG_BLK_DEV_PDC4030
 	if (drive->channel->chipset == ide_pdc4030) {
 		/* DC4030 hosted drives need their own identify... */
-		extern int pdc4030_identify(ide_drive_t *);
-		if (pdc4030_identify(drive)) {
-			return 1;
-		}
+		extern int pdc4030_identify(struct ata_device *);
+
+		if (pdc4030_identify(drive))
+			goto out;
 	} else
-#endif /* CONFIG_BLK_DEV_PDC4030 */
+#endif
 		OUT_BYTE(cmd,IDE_COMMAND_REG);		/* ask drive for ID */
 	timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
 	timeout += jiffies;
 	do {
-		if (0 < (signed long)(jiffies - timeout)) {
-			return 1;	/* drive timed-out */
-		}
+		if (time_after(jiffies, timeout))
+			goto out;	/* drive timed-out */
 		ide_delay_50ms();		/* give drive a breather */
 	} while (IN_BYTE(hd_status) & BUSY_STAT);
 
@@ -274,23 +285,8 @@
 		__restore_flags(flags);	/* local CPU only */
 	} else
 		rc = 2;			/* drive refused ID */
-	return rc;
-}
-
-static int try_to_identify (ide_drive_t *drive, byte cmd)
-{
-	int retval;
-	int autoprobe = 0;
-	unsigned long cookie = 0;
-
-	if (IDE_CONTROL_REG && !drive->channel->irq) {
-		autoprobe = 1;
-		cookie = probe_irq_on();
-		OUT_BYTE(drive->ctl,IDE_CONTROL_REG);	/* enable device irq */
-	}
-
-	retval = actual_try_to_identify(drive, cmd);
 
+out:
 	if (autoprobe) {
 		int irq;
 		OUT_BYTE(drive->ctl | 0x02, IDE_CONTROL_REG);	/* mask device irq */
@@ -304,7 +300,8 @@
 				printk("%s: IRQ probe failed (0x%lx)\n", drive->name, cookie);
 		}
 	}
-	return retval;
+
+	return rc;
 }
 
 
@@ -324,10 +321,11 @@
  *		3  bad status from device (possible for ATAPI drives)
  *		4  probe was not attempted because failure was obvious
  */
-static int do_probe (ide_drive_t *drive, byte cmd)
+static int do_probe(struct ata_device *drive, byte cmd)
 {
 	int rc;
 	struct ata_channel *hwif = drive->channel;
+
 	if (drive->present) {	/* avoid waiting for inappropriate probes */
 		if ((drive->type != ATA_DISK) && (cmd == WIN_IDENTIFY))
 			return 4;
@@ -348,11 +346,10 @@
 		return 3;    /* no i/f present: mmm.. this should be a 4 -ml */
 	}
 
-	if (OK_STAT(GET_STAT(),READY_STAT,BUSY_STAT)
-	 || drive->present || cmd == WIN_PIDENTIFY)
+	if (OK_STAT(GET_STAT(),READY_STAT,BUSY_STAT) || drive->present || cmd == WIN_PIDENTIFY)
 	{
-		if ((rc = try_to_identify(drive,cmd)))   /* send cmd and wait */
-			rc = try_to_identify(drive,cmd); /* failed: try again */
+		if ((rc = identify(drive,cmd)))   /* send cmd and wait */
+			rc = identify(drive,cmd); /* failed: try again */
 		if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) {
 			unsigned long timeout;
 			printk("%s: no response (status = 0x%02x), resetting drive\n", drive->name, GET_STAT());
@@ -363,14 +360,14 @@
 			timeout = jiffies;
 			while ((GET_STAT() & BUSY_STAT) && time_before(jiffies, timeout + WAIT_WORSTCASE))
 				ide_delay_50ms();
-			rc = try_to_identify(drive, cmd);
+			rc = identify(drive, cmd);
 		}
 		if (rc == 1)
 			printk("%s: no response (status = 0x%02x)\n", drive->name, GET_STAT());
 		(void) GET_STAT();		/* ensure drive irq is clear */
-	} else {
+	} else
 		rc = 3;				/* not present or maybe ATAPI */
-	}
+
 	if (drive->select.b.unit != 0) {
 		SELECT_DRIVE(hwif,&hwif->drives[0]);	/* exit with drive0 selected */
 		ide_delay_50ms();
@@ -379,10 +376,7 @@
 	return rc;
 }
 
-/*
- *
- */
-static void enable_nest(ide_drive_t *drive)
+static void enable_nest(struct ata_device *drive)
 {
 	unsigned long timeout;
 
@@ -392,7 +386,7 @@
 	OUT_BYTE(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
 	timeout = jiffies + WAIT_WORSTCASE;
 	do {
-		if (jiffies > timeout) {
+		if (time_after(jiffies, timeout)) {
 			printk("failed (timeout)\n");
 			return;
 		}
@@ -411,17 +405,21 @@
 /*
  * Tests for existence of a given drive using do_probe().
  */
-static inline void probe_for_drive (ide_drive_t *drive)
+static inline void probe_for_drive(struct ata_device *drive)
 {
 	if (drive->noprobe)			/* skip probing? */
 		return;
+
 	if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */
 		do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */
 	}
+
 	if (drive->id && strstr(drive->id->model, "E X A B Y T E N E S T"))
 		enable_nest(drive);
+
 	if (!drive->present)
 		return;			/* drive not found */
+
 	if (drive->id == NULL) {		/* identification failed? */
 		if (drive->type == ATA_DISK) {
 			printk ("%s: non-IDE drive, CHS=%d/%d/%d\n",
@@ -545,7 +543,7 @@
 		do {
 			ide_delay_50ms();
 			stat = IN_BYTE(ch->io_ports[IDE_STATUS_OFFSET]);
-		} while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies));
+		} while ((stat & BUSY_STAT) && time_before(jiffies, timeout));
 	}
 
 	__restore_flags(flags);	/* local CPU only */
@@ -568,34 +566,7 @@
 	__restore_flags(flags);
 }
 
-/*
- * init request queue
- */
-static void init_device_queue(struct ata_device *drive)
-{
-	request_queue_t *q = &drive->queue;
-	int max_sectors = 255;
-
-	q->queuedata = drive->channel;
-	blk_init_queue(q, do_ide_request, &ide_lock);
-	blk_queue_segment_boundary(q, 0xffff);
-
-	/* IDE can do up to 128K per request, pdc4030 needs smaller limit */
-#ifdef CONFIG_BLK_DEV_PDC4030
-	if (drive->channel->chipset == ide_pdc4030)
-		max_sectors = 127;
-#endif
-	blk_queue_max_sectors(q, max_sectors);
-
-	/* IDE DMA can do PRD_ENTRIES number of segments. */
-	blk_queue_max_hw_segments(q, PRD_SEGMENTS);
-
-	/* This is a driver limit and could be eliminated. */
-	blk_queue_max_phys_segments(q, PRD_SEGMENTS);
-}
-
 #if MAX_HWIFS > 1
-
 /*
  * This is used to simplify logic in init_irq() below.
  *
@@ -607,18 +578,19 @@
  *
  * This routine detects and reports such situations, but does not fix them.
  */
-static void save_match(struct ata_channel *hwif, struct ata_channel *new,
-		struct ata_channel **match)
+static struct ata_channel *save_match(struct ata_channel *ch, struct ata_channel *h,
+		struct ata_channel *match)
 {
-	struct ata_channel *m = *match;
+	if (match && match->hwgroup && match->hwgroup != h->hwgroup) {
+		if (!h->hwgroup)
+			return match;
 
-	if (m && m->hwgroup && m->hwgroup != new->hwgroup) {
-		if (!new->hwgroup)
-			return;
-		printk("%s: potential irq problem with %s and %s\n", hwif->name, new->name, m->name);
+		printk("%s: potential irq problem with %s and %s\n", ch->name,h->name, match->name);
 	}
-	if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */
-		*match = new;
+	if (!match || match->irq != ch->irq) /* don't undo a prior perfect match */
+		match = h;
+
+	return match;
 }
 #endif
 
@@ -643,10 +615,8 @@
 	ide_hwgroup_t *new_hwgroup;
 	struct ata_channel *match = NULL;
 
-
-	/* Allocate the buffer and potentially sleep first */
-
-	new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL);
+	/* Spare allocation before sleep. */
+	new_hwgroup = kmalloc(sizeof(*hwgroup), GFP_KERNEL);
 
 	spin_lock_irqsave(&ide_lock, flags);
 	ch->hwgroup = NULL;
@@ -658,19 +628,22 @@
 	for (i = 0; i < MAX_HWIFS; ++i) {
 		struct ata_channel *h = &ide_hwifs[i];
 
-		if (h->hwgroup) {  /* scan only initialized channels */
-			if (ch->irq == h->irq) {
-				ch->sharing_irq = h->sharing_irq = 1;
-				if (ch->chipset != ide_pci || h->chipset != ide_pci)
-					save_match(ch, h, &match);
-
-				/* FIXME: This is still confusing. What would
-				 * happen if we match-ed two times?
-				 */
-
-				if (ch->serialized || h->serialized)
-					save_match(ch, h, &match);
-			}
+		/* scan only initialized channels */
+		if (!h->hwgroup)
+			continue;
+
+		if (ch->irq != h->irq)
+		        continue;
+
+		ch->sharing_irq = h->sharing_irq = 1;
+
+		if (ch->chipset != ide_pci || h->chipset != ide_pci ||
+		     ch->serialized || h->serialized) {
+			if (match && match->hwgroup && match->hwgroup != h->hwgroup)
+				printk("%s: potential irq problem with %s and %s\n", ch->name, h->name, match->name);
+			/* don't undo a prior perfect match */
+			if (!match || match->irq != ch->irq)
+				match = h;
 		}
 	}
 #endif
@@ -721,6 +694,8 @@
 	ch->hwgroup = hwgroup;
 	for (i = 0; i < MAX_DRIVES; ++i) {
 		struct ata_device *drive = &ch->drives[i];
+		request_queue_t *q;
+		int max_sectors = 255;
 
 		if (!drive->present)
 			continue;
@@ -728,7 +703,27 @@
 		if (!hwgroup->XXX_drive)
 			hwgroup->XXX_drive = drive;
 
-		init_device_queue(drive);
+		/*
+		 * Init the per device request queue
+		 */
+
+		q = &drive->queue;
+		q->queuedata = drive->channel;
+		blk_init_queue(q, do_ide_request, &ide_lock);
+		blk_queue_segment_boundary(q, 0xffff);
+
+		/* ATA can do up to 128K per request, pdc4030 needs smaller limit */
+#ifdef CONFIG_BLK_DEV_PDC4030
+		if (drive->channel->chipset == ide_pdc4030)
+			max_sectors = 127;
+#endif
+		blk_queue_max_sectors(q, max_sectors);
+
+		/* IDE DMA can do PRD_ENTRIES number of segments. */
+		blk_queue_max_hw_segments(q, PRD_ENTRIES);
+
+		/* FIXME: This is a driver limit and could be eliminated. */
+		blk_queue_max_phys_segments(q, PRD_ENTRIES);
 	}
 	spin_unlock_irqrestore(&ide_lock, flags);
 
@@ -755,80 +750,10 @@
 }
 
 /*
- * 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(struct ata_channel *hwif)
-{
-	struct gendisk *gd;
-	unsigned int unit, minors, i;
-	extern devfs_handle_t ide_devfs_handle;
-
-	minors = MAX_DRIVES * (1 << PARTN_BITS);
-
-	gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
-	if (!gd)
-		goto err_kmalloc_gd;
-
-	gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
-	if (!gd->sizes)
-		goto err_kmalloc_gd_sizes;
-
-	gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
-	if (!gd->part)
-		goto err_kmalloc_gd_part;
-	memset(gd->part, 0, minors * sizeof(struct hd_struct));
-
-	for (unit = 0; unit < MAX_DRIVES; ++unit)
-		hwif->drives[unit].part = &gd->part[unit << PARTN_BITS];
-
-	gd->major	= hwif->major;		/* our major device number */
-	gd->major_name	= IDE_MAJOR_NAME;	/* treated special in genhd.c */
-	gd->minor_shift	= PARTN_BITS;		/* num bits for partitions */
-	gd->nr_real	= MAX_DRIVES;		/* current num real drives */
-	gd->next	= NULL;			/* linked list of major devs */
-	gd->fops        = ide_fops;             /* file operations */
-	gd->de_arr	= kmalloc(sizeof(*gd->de_arr) * MAX_DRIVES, GFP_KERNEL);
-	gd->flags	= kmalloc(sizeof(*gd->flags) * MAX_DRIVES, GFP_KERNEL);
-	if (gd->de_arr)
-		memset(gd->de_arr, 0, sizeof(*gd->de_arr) * MAX_DRIVES);
-	if (gd->flags)
-		memset(gd->flags, 0, sizeof(*gd->flags) * MAX_DRIVES);
-
-	hwif->gd = gd;
-	add_gendisk(gd);
-
-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		char name[80];
-
-		ide_add_generic_settings(hwif->drives + unit);
-		hwif->drives[unit].dn = ((hwif->unit ? 2 : 0) + unit);
-		sprintf (name, "host%d/bus%d/target%d/lun%d",
-			hwif->index, hwif->unit, unit, hwif->drives[unit].lun);
-		if (hwif->drives[unit].present)
-			hwif->drives[unit].de = devfs_mk_dir(ide_devfs_handle, name, NULL);
-	}
-	return;
-
-err_kmalloc_bs:
-	kfree(gd->part);
-err_kmalloc_gd_part:
-	kfree(gd->sizes);
-err_kmalloc_gd_sizes:
-	kfree(gd);
-err_kmalloc_gd:
-	printk(KERN_CRIT "(ide::init_gendisk) Out of memory\n");
-	return;
-}
-
-/*
  * Returns the queue which corresponds to a given device.
  *
  * FIXME: this should take struct block_device * as argument in future.
  */
-
 static request_queue_t *ata_get_queue(kdev_t dev)
 {
 	struct ata_channel *ch = (struct ata_channel *)blk_dev[major(dev)].data;
@@ -837,8 +762,15 @@
 	return &ch->drives[DEVICE_NR(dev) & 1].queue;
 }
 
+/* Number of minor numbers we consume par channel. */
+#define ATA_MINORS	(MAX_DRIVES * (1 << PARTN_BITS))
+
 static void channel_init(struct ata_channel *ch)
 {
+	struct gendisk *gd;
+	unsigned int unit;
+	extern devfs_handle_t ide_devfs_handle;
+
 	if (!ch->present)
 		return;
 
@@ -888,33 +820,96 @@
 		printk(KERN_INFO "%s: probed IRQ %d failed, using default.\n", ch->name, ch->irq);
 	}
 
-	init_gendisk(ch);
+	/* Initialize partition and global device data.  ide_geninit() gets
+	 * called somewhat later, during the partition check.
+	 */
+
+	gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
+	if (!gd)
+		goto err_kmalloc_gd;
+
+	gd->sizes = kmalloc(ATA_MINORS * sizeof(int), GFP_KERNEL);
+	if (!gd->sizes)
+		goto err_kmalloc_gd_sizes;
+
+	gd->part = kmalloc(ATA_MINORS * sizeof(struct hd_struct), GFP_KERNEL);
+	if (!gd->part)
+		goto err_kmalloc_gd_part;
+	memset(gd->part, 0, ATA_MINORS * sizeof(struct hd_struct));
+
+	for (unit = 0; unit < MAX_DRIVES; ++unit)
+		ch->drives[unit].part = &gd->part[unit << PARTN_BITS];
+
+	gd->major	= ch->major;		/* our major device number */
+	gd->major_name	= IDE_MAJOR_NAME;	/* treated special in genhd.c */
+	gd->minor_shift	= PARTN_BITS;		/* num bits for partitions */
+	gd->nr_real	= MAX_DRIVES;		/* current num real drives */
+	gd->next	= NULL;			/* linked list of major devs */
+	gd->fops        = ide_fops;             /* file operations */
+
+	gd->de_arr	= kmalloc(sizeof(*gd->de_arr) * MAX_DRIVES, GFP_KERNEL);
+	if (gd->de_arr)
+		memset(gd->de_arr, 0, sizeof(*gd->de_arr) * MAX_DRIVES);
+	else
+	    goto err_kmalloc_gd_de_arr;
+
+	gd->flags	= kmalloc(sizeof(*gd->flags) * MAX_DRIVES, GFP_KERNEL);
+	if (gd->flags)
+		memset(gd->flags, 0, sizeof(*gd->flags) * MAX_DRIVES);
+	else
+	    goto err_kmalloc_gd_flags;
+
+	ch->gd = gd;
+	add_gendisk(gd);
+
+	for (unit = 0; unit < MAX_DRIVES; ++unit) {
+		char name[80];
+
+		ide_add_generic_settings(ch->drives + unit);
+		ch->drives[unit].dn = ((ch->unit ? 2 : 0) + unit);
+		sprintf(name, "host%d/bus%d/target%d/lun%d",
+			ch->index, ch->unit, unit, ch->drives[unit].lun);
+		if (ch->drives[unit].present)
+			ch->drives[unit].de = devfs_mk_dir(ide_devfs_handle, name, NULL);
+	}
+
 	blk_dev[ch->major].data = ch;
 	blk_dev[ch->major].queue = ata_get_queue;
 
-	/* all went well, flag this channel entry as valid */
+	/* All went well, flag this channel entry as valid again. */
 	ch->present = 1;
 
 	return;
+
+err_kmalloc_gd_flags:
+	kfree(gd->de_arr);
+err_kmalloc_gd_de_arr:
+	kfree(gd->part);
+err_kmalloc_gd_part:
+	kfree(gd->sizes);
+err_kmalloc_gd_sizes:
+	kfree(gd);
+err_kmalloc_gd:
+	printk(KERN_CRIT "(%s) Out of memory\n", __FUNCTION__);
 }
 
 int ideprobe_init (void)
 {
-	unsigned int index;
+	unsigned int i;
 	int probe[MAX_HWIFS];
 
-	memset(probe, 0, MAX_HWIFS * sizeof(int));
-	for (index = 0; index < MAX_HWIFS; ++index)
-		probe[index] = !ide_hwifs[index].present;
+	for (i = 0; i < MAX_HWIFS; ++i)
+		probe[i] = !ide_hwifs[i].present;
 
 	/*
 	 * Probe for drives in the usual way.. CMOS/BIOS, then poke at ports
 	 */
-	for (index = 0; index < MAX_HWIFS; ++index)
-		if (probe[index])
-			channel_probe(&ide_hwifs[index]);
-	for (index = 0; index < MAX_HWIFS; ++index)
-		if (probe[index])
-			channel_init(&ide_hwifs[index]);
+	for (i = 0; i < MAX_HWIFS; ++i)
+		if (probe[i])
+			channel_probe(&ide_hwifs[i]);
+	for (i = 0; i < MAX_HWIFS; ++i)
+		if (probe[i])
+			channel_init(&ide_hwifs[i]);
+
 	return 0;
 }

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

* [PATCH] 2.5.13 IDE 51
  2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
                   ` (16 preceding siblings ...)
  2002-05-03 12:59 ` [PATCH] 2.5.13 IDE 50 Martin Dalecki
@ 2002-05-03 14:48 ` Martin Dalecki
  17 siblings, 0 replies; 39+ messages in thread
From: Martin Dalecki @ 2002-05-03 14:48 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Kernel Mailing List, axboe

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

Fri May  3 17:19:41 CEST 2002 ide-clean-51

Synchronize with Jens. Applying tons of janitorian stuff to his TCQ code.
Making functions static where appropriate and so on... Marking the config entry
for it experimental and so on.  His changelog follows:

2.5.13 now has the generic tag support that I wrote included, here's an
IDE TCQ that uses that. Changes since the version posted for 2.5.12:

- Fix the ide_tcq_invalidate_queue() WIN_NOP usage needed to clear the
   internal queue on errors. It was disabled in the last version due to
   the ata_request changes, it should work now.

- Remove Promise tcq disable check, it works just fine on Promise as
   long as we handle the two-drives-with-tcq case like we currently do.

That's about it, code should be solid.

[-- Attachment #2: ide-clean-51.diff --]
[-- Type: text/plain, Size: 43542 bytes --]

diff -urN linux-2.5.13/drivers/ide/Config.help linux/drivers/ide/Config.help
--- linux-2.5.13/drivers/ide/Config.help	2002-05-03 02:22:56.000000000 +0200
+++ linux/drivers/ide/Config.help	2002-05-03 16:09:15.000000000 +0200
@@ -751,6 +751,37 @@
 
   Generally say N here.
 
+CONFIG_BLK_DEV_IDE_TCQ
+  Support for tagged command queueing on ATA disk drives. This enables
+  the IDE layer to have multiple in-flight requests on hardware that
+  supports it. For now this includes the IBM Deskstar series drives,
+  such as the 22GXP, 75GXP, 40GV, 60GXP, and 120GXP (ie any Deskstar made
+  in the last couple of years), and at least some of the Western
+  Digital drives in the Expert series (by nature of really being IBM
+  drives).
+
+  If you have such a drive, say Y here.
+
+CONFIG_BLK_DEV_IDE_TCQ_DEPTH
+  Maximum size of commands to enable per-drive. Any value between 1
+  and 32 is valid, with 32 being the maxium that the hardware supports.
+
+  You probably just want the default of 32 here. If you enter an invalid
+  number, the default value will be used.
+
+CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
+  Enabled tagged command queueing unconditionally on drives that report
+  support for it. Regardless of the chosen value here, tagging can be
+  controlled at run time:
+
+  echo "using_tcq:32" > /proc/ide/hdX/settings
+
+  where any value between 1-32 selects chosen queue depth and enables
+  TCQ, and 0 disables it. hdparm version 4.7 an above also support
+  TCQ manipulations.
+
+  Generally say Y here.
+
 CONFIG_BLK_DEV_IT8172
   Say Y here to support the on-board IDE controller on the Integrated
   Technology Express, Inc. ITE8172 SBC.  Vendor page at
diff -urN linux-2.5.13/drivers/ide/Config.in linux/drivers/ide/Config.in
--- linux-2.5.13/drivers/ide/Config.in	2002-05-03 02:22:56.000000000 +0200
+++ linux/drivers/ide/Config.in	2002-05-03 17:10:12.000000000 +0200
@@ -47,6 +47,11 @@
 	 dep_bool '      Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI
          dep_bool '    Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
 	 define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI
+	 dep_bool '    ATA tagged command queueing (EXPERIMENTAL)' CONFIG_BLK_DEV_IDE_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
+	 dep_bool '      TCQ on by default' CONFIG_BLK_DEV_IDE_TCQ_DEFAULT $CONFIG_BLK_DEV_IDE_TCQ
+	 if [ "$CONFIG_BLK_DEV_IDE_TCQ" != "n" ]; then
+	    int '      Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 32
+	 fi
 	 dep_bool '    Good-Bad DMA Model-Firmware (EXPERIMENTAL)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_EXPERIMENTAL
 	 dep_bool '    AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI
 	 dep_mbool '      AEC62XX Tuning support' CONFIG_AEC62XX_TUNING $CONFIG_BLK_DEV_AEC62XX
diff -urN linux-2.5.13/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c
--- linux-2.5.13/drivers/ide/hpt366.c	2002-05-03 02:22:42.000000000 +0200
+++ linux/drivers/ide/hpt366.c	2002-05-03 16:53:22.000000000 +0200
@@ -346,8 +346,6 @@
 static unsigned int pci_rev_check_hpt3xx(struct pci_dev *dev);
 static unsigned int pci_rev2_check_hpt3xx(struct pci_dev *dev);
 byte hpt366_proc = 0;
-byte hpt363_shared_irq;
-byte hpt363_shared_pin;
 extern char *ide_xfer_verbose (byte xfer_rate);
 
 #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
diff -urN linux-2.5.13/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.13/drivers/ide/ide.c	2002-05-03 16:09:02.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-05-03 16:09:15.000000000 +0200
@@ -311,7 +311,10 @@
 
 	if (!end_that_request_first(rq, uptodate, nr_secs)) {
 		add_blkdev_randomness(major(rq->rq_dev));
-		blkdev_dequeue_request(rq);
+		if (!blk_rq_tagged(rq))
+			blkdev_dequeue_request(rq);
+		else
+			blk_queue_end_tag(&drive->queue, rq);
 		HWGROUP(drive)->rq = NULL;
 		end_that_request_last(rq);
 		ret = 0;
@@ -1219,11 +1222,6 @@
 }
 
 
-/* Place holders for later expansion of functionality.
- */
-#define ata_pending_commands(drive)	(0)
-#define ata_can_queue(drive)		(1)
-
 /*
  * Feed commands to a drive until it barfs.  Called with ide_lock/DRIVE_LOCK
  * held and busy channel.
@@ -1263,7 +1261,7 @@
 		 * still a severe BUG!
 		 */
 		if (blk_queue_plugged(&drive->queue)) {
-			BUG();
+			BUG_ON(!drive->using_tcq);
 			break;
 		}
 
@@ -1675,7 +1673,8 @@
 		} else {
 			printk("%s: %s: huh? expected NULL handler on exit\n", drive->name, __FUNCTION__);
 		}
-	}
+	} else if (startstop == ide_released)
+		queue_commands(drive, ch->irq);
 
 out_lock:
 	spin_unlock_irqrestore(&ide_lock, flags);
@@ -3204,6 +3203,9 @@
 
 			drive->channel->udma(ide_dma_off_quietly, drive, NULL);
 			drive->channel->udma(ide_dma_check, drive, NULL);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
+			drive->channel->udma(ide_dma_queued_on, drive, NULL);
+#endif
 		}
 
 		/* Only CD-ROMs and tape drives support DSC overlap.  But only
diff -urN linux-2.5.13/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.13/drivers/ide/ide-disk.c	2002-05-03 16:09:02.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-05-03 16:09:15.000000000 +0200
@@ -99,6 +99,8 @@
 
 	if (lba48bit) {
 		if (cmd == READ) {
+			if (drive->using_tcq)
+				return WIN_READDMA_QUEUED_EXT;
 			if (drive->using_dma)
 				return WIN_READDMA_EXT;
 			else if (drive->mult_count)
@@ -106,6 +108,8 @@
 			else
 				return WIN_READ_EXT;
 		} else if (cmd == WRITE) {
+			if (drive->using_tcq)
+				return WIN_WRITEDMA_QUEUED_EXT;
 			if (drive->using_dma)
 				return WIN_WRITEDMA_EXT;
 			else if (drive->mult_count)
@@ -115,6 +119,8 @@
 		}
 	} else {
 		if (cmd == READ) {
+			if (drive->using_tcq)
+				return WIN_READDMA_QUEUED;
 			if (drive->using_dma)
 				return WIN_READDMA;
 			else if (drive->mult_count)
@@ -122,6 +128,8 @@
 			else
 				return WIN_READ;
 		} else if (cmd == WRITE) {
+			if (drive->using_tcq)
+				return WIN_WRITEDMA_QUEUED;
 			if (drive->using_dma)
 				return WIN_WRITEDMA;
 			else if (drive->mult_count)
@@ -149,7 +157,11 @@
 
 	memset(&args, 0, sizeof(args));
 
-	args.taskfile.sector_count = sectors;
+	if (blk_rq_tagged(rq)) {
+		args.taskfile.feature = sectors;
+		args.taskfile.sector_count = rq->tag << 3;
+	} else
+		args.taskfile.sector_count = sectors;
 
 	args.taskfile.sector_number = sect;
 	args.taskfile.low_cylinder = cyl;
@@ -185,7 +197,12 @@
 
 	memset(&args, 0, sizeof(args));
 
-	args.taskfile.sector_count = sectors;
+	if (blk_rq_tagged(rq)) {
+		args.taskfile.feature = sectors;
+		args.taskfile.sector_count = rq->tag << 3;
+	} else
+		args.taskfile.sector_count = sectors;
+
 	args.taskfile.sector_number = block;
 	args.taskfile.low_cylinder = (block >>= 8);
 
@@ -227,8 +244,14 @@
 
 	memset(&args, 0, sizeof(args));
 
-	args.taskfile.sector_count = sectors;
-	args.hobfile.sector_count = sectors >> 8;
+	if (blk_rq_tagged(rq)) {
+		args.taskfile.feature = sectors;
+		args.hobfile.feature = sectors >> 8;
+		args.taskfile.sector_count = rq->tag << 3;
+	} else {
+		args.taskfile.sector_count = sectors;
+		args.hobfile.sector_count = sectors >> 8;
+	}
 
 	args.taskfile.sector_number = block;		/* low lba */
 	args.taskfile.low_cylinder = (block >>= 8);	/* mid lba */
@@ -286,6 +309,30 @@
 		return promise_rw_disk(drive, rq, block);
 	}
 
+	/*
+	 * start a tagged operation
+	 */
+	if (drive->using_tcq) {
+		unsigned long flags;
+		int ret;
+
+		spin_lock_irqsave(&ide_lock, flags);
+
+		ret = blk_queue_start_tag(&drive->queue, rq);
+
+		if (ata_pending_commands(drive) > drive->max_depth)
+			drive->max_depth = ata_pending_commands(drive);
+		if (ata_pending_commands(drive) > drive->max_last_depth)
+			drive->max_last_depth = ata_pending_commands(drive);
+
+		spin_unlock_irqrestore(&ide_lock, flags);
+
+		if (ret) {
+			BUG_ON(!ata_pending_commands(drive));
+			return ide_started;
+		}
+	}
+
 	/* 48-bit LBA */
 	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
 		return lba48_do_request(drive, rq, block);
@@ -543,11 +590,61 @@
 	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+static int proc_idedisk_read_tcq
+	(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	ide_drive_t	*drive = (ide_drive_t *) data;
+	char		*out = page;
+	int		len, cmds, i;
+	unsigned long	flags;
+
+	if (!blk_queue_tagged(&drive->queue)) {
+		len = sprintf(out, "not configured\n");
+		PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	}
+
+	spin_lock_irqsave(&ide_lock, flags);
+
+	len = sprintf(out, "TCQ currently on:\t%s\n", drive->using_tcq ? "yes" : "no");
+	len += sprintf(out+len, "Max queue depth:\t%d\n",drive->queue_depth);
+	len += sprintf(out+len, "Max achieved depth:\t%d\n",drive->max_depth);
+	len += sprintf(out+len, "Max depth since last:\t%d\n",drive->max_last_depth);
+	len += sprintf(out+len, "Current depth:\t\t%d\n", ata_pending_commands(drive));
+	len += sprintf(out+len, "Active tags:\t\t[ ");
+	for (i = 0, cmds = 0; i < drive->queue_depth; i++) {
+		struct request *rq = blk_queue_tag_request(&drive->queue, i);
+
+		if (!rq)
+			continue;
+
+		len += sprintf(out+len, "%d, ", i);
+		cmds++;
+	}
+	len += sprintf(out+len, "]\n");
+
+	len += sprintf(out+len, "Queue:\t\t\treleased [ %lu ] - started [ %lu ]\n", drive->immed_rel, drive->immed_comp);
+
+	if (ata_pending_commands(drive) != cmds)
+		len += sprintf(out+len, "pending request and queue count mismatch (counted: %d)\n", cmds);
+
+	len += sprintf(out+len, "DMA status:\t\t%srunning\n", test_bit(IDE_DMA, &HWGROUP(drive)->flags) ? "" : "not ");
+
+	drive->max_last_depth = 0;
+
+	spin_unlock_irqrestore(&ide_lock, flags);
+	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+}
+#endif
+
 static ide_proc_entry_t idedisk_proc[] = {
 	{ "cache",		S_IFREG|S_IRUGO,	proc_idedisk_read_cache,		NULL },
 	{ "geometry",		S_IFREG|S_IRUGO,	proc_ide_read_geometry,			NULL },
 	{ "smart_values",	S_IFREG|S_IRUSR,	proc_idedisk_read_smart_values,		NULL },
 	{ "smart_thresholds",	S_IFREG|S_IRUSR,	proc_idedisk_read_smart_thresholds,	NULL },
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+	{ "tcq",		S_IFREG|S_IRUSR,	proc_idedisk_read_tcq,			NULL },
+#endif
 	{ NULL, 0, NULL, NULL }
 };
 
@@ -634,6 +731,32 @@
 	return 0;
 }
 
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+static int set_using_tcq(ide_drive_t *drive, int arg)
+{
+	if (!drive->driver)
+		return -EPERM;
+	if (!drive->channel->udma)
+		return -EPERM;
+	if (arg == drive->queue_depth && drive->using_tcq)
+		return 0;
+
+	/*
+	 * set depth, but check also id for max supported depth
+	 */
+	drive->queue_depth = arg ? arg : 1;
+	if (drive->id) {
+		if (drive->queue_depth > drive->id->queue_depth + 1)
+			drive->queue_depth = drive->id->queue_depth + 1;
+	}
+
+	if (drive->channel->udma(arg ? ide_dma_queued_on : ide_dma_queued_off, drive, NULL))
+		return -EIO;
+
+	return 0;
+}
+#endif
+
 static int probe_lba_addressing (ide_drive_t *drive, int arg)
 {
 	drive->addressing =  0;
@@ -665,6 +788,9 @@
 	ide_add_setting(drive,	"acoustic",		SETTING_RW,					HDIO_GET_ACOUSTIC,	HDIO_SET_ACOUSTIC,	TYPE_BYTE,	0,	254,				1,	1,	&drive->acoustic,		set_acoustic);
 	ide_add_setting(drive,	"failures",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	65535,				1,	1,	&drive->failures,		NULL);
 	ide_add_setting(drive,	"max_failures",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	65535,				1,	1,	&drive->max_failures,		NULL);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+	ide_add_setting(drive,	"using_tcq",		SETTING_RW,					HDIO_GET_QDMA,		HDIO_SET_QDMA,		TYPE_BYTE,	0,	IDE_MAX_TAG,			1,		1,		&drive->using_tcq,		set_using_tcq);
+#endif
 }
 
 static int idedisk_suspend(struct device *dev, u32 state, u32 level)
diff -urN linux-2.5.13/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.13/drivers/ide/ide-dma.c	2002-05-03 02:22:44.000000000 +0200
+++ linux/drivers/ide/ide-dma.c	2002-05-03 16:09:15.000000000 +0200
@@ -522,6 +522,32 @@
 	blk_queue_bounce_limit(&drive->queue, addr);
 }
 
+int ide_start_dma(ide_dma_action_t func, struct ata_device *drive)
+{
+	struct ata_channel *hwif = drive->channel;
+	unsigned long dma_base = hwif->dma_base;
+	unsigned int reading = 0;
+
+	if (rq_data_dir(HWGROUP(drive)->rq) == READ)
+		reading = 1 << 3;
+
+	/* active tuning based on IO direction */
+	if (hwif->rwproc)
+		hwif->rwproc(drive, func);
+
+	/*
+	 * try PIO instead of DMA
+	 */
+	if (!ide_build_dmatable(drive, func))
+		return 1;
+
+	outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
+	outb(reading, dma_base);		/* specify r/w */
+	outb(inb(dma_base+2)|6, dma_base+2);	/* clear INTR & ERROR flags */
+	drive->waiting_for_dma = 1;
+	return 0;
+}
+
 /*
  * This initiates/aborts DMA read/write operations on a drive.
  *
@@ -543,7 +569,7 @@
 	struct ata_channel *hwif = drive->channel;
 	unsigned long dma_base = hwif->dma_base;
 	byte unit = (drive->select.b.unit & 0x01);
-	unsigned int count, reading = 0, set_high = 1;
+	unsigned int reading = 0, set_high = 1;
 	byte dma_stat;
 
 	switch (func) {
@@ -552,27 +578,27 @@
 		case ide_dma_off_quietly:
 			set_high = 0;
 			outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+			hwif->udma(ide_dma_queued_off, drive, rq);
+#endif
 		case ide_dma_on:
 			ide_toggle_bounce(drive, set_high);
 			drive->using_dma = (func == ide_dma_on);
-			if (drive->using_dma)
+			if (drive->using_dma) {
 				outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
+				hwif->udma(ide_dma_queued_on, drive, rq);
+#endif
+			}
 			return 0;
 		case ide_dma_check:
 			return config_drive_for_dma (drive);
 		case ide_dma_read:
 			reading = 1 << 3;
 		case ide_dma_write:
-			/* active tuning based on IO direction */
-			if (hwif->rwproc)
-				hwif->rwproc(drive, func);
-
-			if (!(count = ide_build_dmatable(drive, func)))
-				return 1;	/* try PIO instead of DMA */
-			outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
-			outb(reading, dma_base);			/* specify r/w */
-			outb(inb(dma_base+2)|6, dma_base+2);		/* clear INTR & ERROR flags */
-			drive->waiting_for_dma = 1;
+			if (ide_start_dma(func, drive))
+				return 1;
+
 			if (drive->type != ATA_DISK)
 				return 0;
 
@@ -587,6 +613,14 @@
 				OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 			}
 			return drive->channel->udma(ide_dma_begin, drive, NULL);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+		case ide_dma_queued_on:
+		case ide_dma_queued_off:
+		case ide_dma_read_queued:
+		case ide_dma_write_queued:
+		case ide_dma_queued_start:
+			return ide_tcq_dmaproc(func, drive, rq);
+#endif
 		case ide_dma_begin:
 			/* Note that this is done *after* the cmd has
 			 * been issued to the drive, as per the BM-IDE spec.
diff -urN linux-2.5.13/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.13/drivers/ide/ide-probe.c	2002-05-03 16:09:02.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-05-03 16:48:59.000000000 +0200
@@ -199,6 +199,16 @@
 	if (drive->channel->quirkproc)
 		drive->quirk_list = drive->channel->quirkproc(drive);
 
+	/* Initialize queue depth settings */
+	drive->queue_depth = 1;
+#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEPTH
+	drive->queue_depth = CONFIG_BLK_DEV_IDE_TCQ_DEPTH;
+#else
+	drive->queue_depth = drive->id->queue_depth + 1;
+#endif
+	if (drive->queue_depth < 1 || drive->queue_depth > IDE_MAX_TAG)
+		drive->queue_depth = IDE_MAX_TAG;
+
 	return;
 
 err_misc:
@@ -566,34 +576,6 @@
 	__restore_flags(flags);
 }
 
-#if MAX_HWIFS > 1
-/*
- * This is used to simplify logic in init_irq() below.
- *
- * A loophole here is that we may not know about a particular hwif's irq until
- * after that hwif is actually probed/initialized..  This could be a problem
- * for the case where an hwif is on a dual interface that requires
- * serialization (eg. cmd640) and another hwif using one of the same irqs is
- * initialized beforehand.
- *
- * This routine detects and reports such situations, but does not fix them.
- */
-static struct ata_channel *save_match(struct ata_channel *ch, struct ata_channel *h,
-		struct ata_channel *match)
-{
-	if (match && match->hwgroup && match->hwgroup != h->hwgroup) {
-		if (!h->hwgroup)
-			return match;
-
-		printk("%s: potential irq problem with %s and %s\n", ch->name,h->name, match->name);
-	}
-	if (!match || match->irq != ch->irq) /* don't undo a prior perfect match */
-		match = h;
-
-	return match;
-}
-#endif
-
 /*
  * This routine sets up the irq for an ide interface, and creates a new hwgroup
  * for the irq/channel if none was previously assigned.
diff -urN linux-2.5.13/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.13/drivers/ide/ide-taskfile.c	2002-05-03 02:22:53.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-05-03 16:09:15.000000000 +0200
@@ -456,11 +456,39 @@
 		if (args->prehandler != NULL)
 			return args->prehandler(drive, rq);
 	} else {
-		/* for dma commands we down set the handler */
-		if (drive->using_dma &&
-		!(drive->channel->udma(((args->taskfile.command == WIN_WRITEDMA)
-					|| (args->taskfile.command == WIN_WRITEDMA_EXT))
-					? ide_dma_write : ide_dma_read, drive, rq)));
+		ide_dma_action_t dma_act;
+		int tcq = 0;
+
+		if (!drive->using_dma)
+			return ide_started;
+
+		/* for dma commands we don't set the handler */
+		if (args->taskfile.command == WIN_WRITEDMA || args->taskfile.command == WIN_WRITEDMA_EXT)
+			dma_act = ide_dma_write;
+		else if (args->taskfile.command == WIN_READDMA || args->taskfile.command == WIN_READDMA_EXT)
+			dma_act = ide_dma_read;
+		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT) {
+			tcq = 1;
+			dma_act = ide_dma_write_queued;
+		} else if (args->taskfile.command == WIN_READDMA_QUEUED || args->taskfile.command == WIN_READDMA_QUEUED_EXT) {
+			tcq = 1;
+			dma_act = ide_dma_read_queued;
+		} else {
+			printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
+			return ide_stopped;
+		}
+
+		/*
+		 * FIXME: this is a gross hack, need to unify tcq dma proc and
+		 * regular dma proc -- basically split stuff that needs to act
+		 * on a request from things like ide_dma_check etc.
+		 */
+		if (tcq)
+			return drive->channel->udma(dma_act, drive, rq);
+		else {
+			if (drive->channel->udma(dma_act, drive, rq))
+				return ide_stopped;
+		}
 	}
 
 	return ide_started;
@@ -523,7 +551,7 @@
 	ide__sti();	/* local CPU only */
 
 	if (!OK_STAT(stat = GET_STAT(), READY_STAT, BAD_STAT)) {
-		/* Keep quite for NOP becouse they are expected to fail. */
+		/* Keep quiet for NOP because it is expected to fail. */
 		if (args && args->taskfile.command != WIN_NOP)
 			return ide_error(drive, "task_no_data_intr", stat);
 	}
diff -urN linux-2.5.13/drivers/ide/Makefile linux/drivers/ide/Makefile
--- linux-2.5.13/drivers/ide/Makefile	2002-05-03 02:22:54.000000000 +0200
+++ linux/drivers/ide/Makefile	2002-05-03 16:10:14.000000000 +0200
@@ -44,6 +44,7 @@
 ide-obj-$(CONFIG_BLK_DEV_HT6560B)	+= ht6560b.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)	+= icside.o
 ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI)	+= ide-dma.o
+ide-obj-$(CONFIG_BLK_DEV_IDE_TCQ)	+= tcq.o
 ide-obj-$(CONFIG_BLK_DEV_IDEPCI)	+= ide-pci.o
 ide-obj-$(CONFIG_BLK_DEV_ISAPNP)	+= ide-pnp.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ide-pmac.o
diff -urN linux-2.5.13/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.13/drivers/ide/tcq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux/drivers/ide/tcq.c	2002-05-03 16:39:12.000000000 +0200
@@ -0,0 +1,642 @@
+/*
+ * Copyright (C) 2001, 2002 Jens Axboe <axboe@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Support for the DMA queued protocol, which enables ATA disk drives to
+ * use tagged command queueing.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ide.h>
+
+#include <asm/delay.h>
+
+/*
+ * warning: it will be _very_ verbose if defined
+ */
+#undef IDE_TCQ_DEBUG
+
+#ifdef IDE_TCQ_DEBUG
+#define TCQ_PRINTK printk
+#else
+#define TCQ_PRINTK(x...)
+#endif
+
+/*
+ * use nIEN or not
+ */
+#undef IDE_TCQ_NIEN
+
+/*
+ * We are leaving the SERVICE interrupt alone, IBM drives have it
+ * on per default and it can't be turned off. Doesn't matter, this
+ * is the sane config.
+ */
+#undef IDE_TCQ_FIDDLE_SI
+
+static ide_startstop_t ide_dmaq_intr(struct ata_device *drive, struct request *rq);
+static ide_startstop_t service(struct ata_device *drive);
+
+static inline void drive_ctl_nien(struct ata_device *drive, int set)
+{
+#ifdef IDE_TCQ_NIEN
+	if (IDE_CONTROL_REG) {
+		int mask = set ? 0x02 : 0x00;
+
+		OUT_BYTE(drive->ctl | mask, IDE_CONTROL_REG);
+	}
+#endif
+}
+
+static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request *rq)
+{
+	struct ata_taskfile *args = rq->special;
+
+	ide__sti();
+	ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
+	kfree(args);
+	return ide_stopped;
+}
+
+/*
+ * If we encounter _any_ error doing I/O to one of the tags, we must
+ * invalidate the pending queue. Clear the software busy queue and requeue
+ * on the request queue for restart. Issue a WIN_NOP to clear hardware queue.
+ */
+static void tcq_invalidate_queue(struct ata_device *drive)
+{
+	ide_hwgroup_t *hwgroup = HWGROUP(drive);
+	request_queue_t *q = &drive->queue;
+	struct ata_taskfile *args;
+	struct request *rq;
+	unsigned long flags;
+
+	printk(KERN_INFO "ATA: %s: invalidating pending queue (%d)\n", drive->name, ata_pending_commands(drive));
+
+	spin_lock_irqsave(&ide_lock, flags);
+
+	del_timer(&hwgroup->timer);
+
+	if (test_bit(IDE_DMA, &hwgroup->flags))
+		drive->channel->udma(ide_dma_end, drive, hwgroup->rq);
+
+	blk_queue_invalidate_tags(q);
+
+	drive->using_tcq = 0;
+	drive->queue_depth = 1;
+	clear_bit(IDE_BUSY, &hwgroup->flags);
+	clear_bit(IDE_DMA, &hwgroup->flags);
+	hwgroup->handler = NULL;
+
+	/*
+	 * Do some internal stuff -- we really need this command to be
+	 * executed before any new commands are started. issue a NOP
+	 * to clear internal queue on drive.
+	 */
+	args = kmalloc(sizeof(*args), GFP_ATOMIC);
+	if (!args) {
+		printk(KERN_ERR "ATA: %s: failed to issue NOP\n", drive->name);
+		goto out;
+	}
+
+	rq = blk_get_request(&drive->queue, READ, GFP_ATOMIC);
+	if (!rq)
+		rq = blk_get_request(&drive->queue, WRITE, GFP_ATOMIC);
+
+	/*
+	 * blk_queue_invalidate_tags() just added back at least one command
+	 * to the free list, so there _must_ be at least one free.
+	 */
+	BUG_ON(!rq);
+
+	rq->special = args;
+	args->taskfile.command = WIN_NOP;
+	args->handler = tcq_nop_handler;
+	args->command_type = IDE_DRIVE_TASK_NO_DATA;
+
+	rq->rq_dev = mk_kdev(drive->channel->major, (drive->select.b.unit)<<PARTN_BITS);
+	_elv_add_request(q, rq, 0, 0);
+
+	/*
+	 * make sure that nIEN is cleared
+	 */
+out:
+	drive_ctl_nien(drive, 0);
+
+	/*
+	 * start doing stuff again
+	 */
+	q->request_fn(q);
+	spin_unlock_irqrestore(&ide_lock, flags);
+	printk(KERN_DEBUG "ATA: tcq_invalidate_queue: done\n");
+}
+
+static void ata_tcq_irq_timeout(unsigned long data)
+{
+	struct ata_device *drive = (struct ata_device *) data;
+	ide_hwgroup_t *hwgroup = HWGROUP(drive);
+	unsigned long flags;
+
+	printk(KERN_ERR "ATA: %s: timeout waiting for interrupt...\n", __FUNCTION__);
+
+	spin_lock_irqsave(&ide_lock, flags);
+
+	if (test_and_set_bit(IDE_BUSY, &hwgroup->flags))
+		printk(KERN_ERR "ATA: %s: hwgroup not busy\n", __FUNCTION__);
+	if (hwgroup->handler == NULL)
+		printk(KERN_ERR "ATA: %s: missing isr!\n", __FUNCTION__);
+
+	spin_unlock_irqrestore(&ide_lock, flags);
+
+	/*
+	 * if pending commands, try service before giving up
+	 */
+	if (ata_pending_commands(drive) && (GET_STAT() & SERVICE_STAT))
+		if (service(drive) == ide_started)
+			return;
+
+	if (drive)
+		tcq_invalidate_queue(drive);
+}
+
+static void set_irq(struct ata_device *drive, ata_handler_t *handler)
+{
+	ide_hwgroup_t *hwgroup = HWGROUP(drive);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ide_lock, flags);
+
+	/*
+	 * always just bump the timer for now, the timeout handling will
+	 * have to be changed to be per-command
+	 */
+	hwgroup->timer.function = ata_tcq_irq_timeout;
+	hwgroup->timer.data = (unsigned long) hwgroup->XXX_drive;
+	mod_timer(&hwgroup->timer, jiffies + 5 * HZ);
+
+	hwgroup->handler = handler;
+	spin_unlock_irqrestore(&ide_lock, flags);
+}
+
+/*
+ * wait 400ns, then poll for busy_mask to clear from alt status
+ */
+#define IDE_TCQ_WAIT	(10000)
+static int wait_altstat(struct ata_device *drive, u8 *stat, u8 busy_mask)
+{
+	int i = 0;
+
+	udelay(1);
+
+	while ((*stat = GET_ALTSTAT()) & busy_mask) {
+		if (unlikely(i++ > IDE_TCQ_WAIT))
+			return 1;
+
+		udelay(10);
+	}
+
+	return 0;
+}
+
+/*
+ * issue SERVICE command to drive -- drive must have been selected first,
+ * and it must have reported a need for service (status has SERVICE_STAT set)
+ *
+ * Also, nIEN must be set as not to need protection against ide_dmaq_intr
+ */
+static ide_startstop_t service(struct ata_device *drive)
+{
+	struct request *rq;
+	u8 feat;
+	u8 stat;
+	int tag;
+
+	TCQ_PRINTK("%s: started service\n", drive->name);
+
+	/*
+	 * Could be called with IDE_DMA in-progress from invalidate
+	 * handler, refuse to do anything.
+	 */
+	if (test_bit(IDE_DMA, &HWGROUP(drive)->flags))
+		return ide_stopped;
+
+	/*
+	 * need to select the right drive first...
+	 */
+	if (drive != HWGROUP(drive)->XXX_drive) {
+		SELECT_DRIVE(drive->channel, drive);
+		udelay(10);
+	}
+
+	drive_ctl_nien(drive, 1);
+
+	/*
+	 * send SERVICE, wait 400ns, wait for BUSY_STAT to clear
+	 */
+	OUT_BYTE(WIN_QUEUED_SERVICE, IDE_COMMAND_REG);
+
+	if (wait_altstat(drive, &stat, BUSY_STAT)) {
+		printk(KERN_ERR"%s: BUSY clear took too long\n", __FUNCTION__);
+		ide_dump_status(drive, __FUNCTION__, stat);
+		tcq_invalidate_queue(drive);
+		return ide_stopped;
+	}
+
+	drive_ctl_nien(drive, 0);
+
+	/*
+	 * FIXME, invalidate queue
+	 */
+	if (stat & ERR_STAT) {
+		ide_dump_status(drive, __FUNCTION__, stat);
+		tcq_invalidate_queue(drive);
+		return ide_stopped;
+	}
+
+	/*
+	 * should not happen, a buggy device could introduce loop
+	 */
+	if ((feat = GET_FEAT()) & NSEC_REL) {
+		HWGROUP(drive)->rq = NULL;
+		printk("%s: release in service\n", drive->name);
+		return ide_stopped;
+	}
+
+	tag = feat >> 3;
+
+	TCQ_PRINTK("%s: stat %x, feat %x\n", __FUNCTION__, stat, feat);
+
+	rq = blk_queue_tag_request(&drive->queue, tag);
+	if (!rq) {
+		printk(KERN_ERR"%s: missing request for tag %d\n", __FUNCTION__, tag);
+		return ide_stopped;
+	}
+
+	HWGROUP(drive)->rq = rq;
+
+	/*
+	 * we'll start a dma read or write, device will trigger
+	 * interrupt to indicate end of transfer, release is not allowed
+	 */
+	TCQ_PRINTK("%s: starting command %x\n", __FUNCTION__, stat);
+	return drive->channel->udma(ide_dma_queued_start, drive, rq);
+}
+
+static ide_startstop_t check_service(struct ata_device *drive)
+{
+	u8 stat;
+
+	TCQ_PRINTK("%s: %s\n", drive->name, __FUNCTION__);
+
+	if (!ata_pending_commands(drive))
+		return ide_stopped;
+
+	if ((stat = GET_STAT()) & SERVICE_STAT)
+		return service(drive);
+
+	/*
+	 * we have pending commands, wait for interrupt
+	 */
+	set_irq(drive, ide_dmaq_intr);
+
+	return ide_started;
+}
+
+ide_startstop_t ide_dmaq_complete(struct ata_device *drive, struct request *rq, u8 stat)
+{
+	u8 dma_stat;
+
+	/*
+	 * transfer was in progress, stop DMA engine
+	 */
+	dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
+
+	/*
+	 * must be end of I/O, check status and complete as necessary
+	 */
+	if (unlikely(!OK_STAT(stat, READY_STAT, drive->bad_wstat | DRQ_STAT))) {
+		printk(KERN_ERR "%s: %s: error status %x\n", __FUNCTION__, drive->name,stat);
+		ide_dump_status(drive, __FUNCTION__, stat);
+		tcq_invalidate_queue(drive);
+		return ide_stopped;
+	}
+
+	if (dma_stat)
+		printk("%s: bad DMA status (dma_stat=%x)\n", drive->name, dma_stat);
+
+	TCQ_PRINTK("%s: ending %p, tag %d\n", __FUNCTION__, rq, rq->tag);
+	__ide_end_request(drive, rq, !dma_stat, rq->nr_sectors);
+
+	/*
+	 * we completed this command, check if we can service a new command
+	 */
+	return check_service(drive);
+}
+
+/*
+ * intr handler for queued dma operations. this can be entered for two
+ * reasons:
+ *
+ * 1) device has completed dma transfer
+ * 2) service request to start a command
+ *
+ * if the drive has an active tag, we first complete that request before
+ * processing any pending SERVICE.
+ */
+static ide_startstop_t ide_dmaq_intr(struct ata_device *drive, struct request *rq)
+{
+	u8 stat = GET_STAT();
+
+	TCQ_PRINTK("%s: stat=%x\n", __FUNCTION__, stat);
+
+	/*
+	 * if a command completion interrupt is pending, do that first and
+	 * check service afterwards
+	 */
+	if (rq)
+		return ide_dmaq_complete(drive, rq, stat);
+
+	/*
+	 * service interrupt
+	 */
+	if (stat & SERVICE_STAT) {
+		TCQ_PRINTK("%s: SERV (stat=%x)\n", __FUNCTION__, stat);
+		return service(drive);
+	}
+
+	printk("%s: stat=%x, not expected\n", __FUNCTION__, stat);
+	return check_service(drive);
+}
+
+/*
+ * Check if the ata adapter this drive is attached to supports the
+ * NOP auto-poll for multiple tcq enabled drives on one channel.
+ */
+static int check_autopoll(struct ata_device *drive)
+{
+	struct ata_channel *ch = drive->channel;
+	struct ata_taskfile args;
+	int drives = 0, i;
+
+	/*
+	 * only need to probe if both drives on a channel support tcq
+	 */
+	for (i = 0; i < MAX_DRIVES; i++)
+		if (drive->channel->drives[i].present &&drive->type == ATA_DISK)
+			drives++;
+
+	if (drives <= 1)
+		return 0;
+
+	memset(&args, 0, sizeof(args));
+
+	args.taskfile.feature = 0x01;
+	args.taskfile.command = WIN_NOP;
+	ide_cmd_type_parser(&args);
+
+	/*
+	 * do taskfile and check ABRT bit -- intelligent adapters will not
+	 * pass NOP with sub-code 0x01 to device, so the command will not
+	 * fail there
+	 */
+	ide_raw_taskfile(drive, &args, NULL);
+	if (args.taskfile.feature & ABRT_ERR)
+		return 1;
+
+	ch->auto_poll = 1;
+	printk("%s: NOP Auto-poll enabled\n", ch->name);
+	return 0;
+}
+
+/*
+ * configure the drive for tcq
+ */
+static int configure_tcq(struct ata_device *drive)
+{
+	int tcq_mask = 1 << 1 | 1 << 14;
+	int tcq_bits = tcq_mask | 1 << 15;
+	struct ata_taskfile args;
+
+	/*
+	 * bit 14 and 1 must be set in word 83 of the device id to indicate
+	 * support for dma queued protocol, and bit 15 must be cleared
+	 */
+	if ((drive->id->command_set_2 & tcq_bits) ^ tcq_mask)
+		return -EIO;
+
+	memset(&args, 0, sizeof(args));
+	args.taskfile.feature = SETFEATURES_EN_WCACHE;
+	args.taskfile.command = WIN_SETFEATURES;
+	ide_cmd_type_parser(&args);
+
+	if (ide_raw_taskfile(drive, &args, NULL)) {
+		printk("%s: failed to enable write cache\n", drive->name);
+		return 1;
+	}
+
+	/*
+	 * disable RELease interrupt, it's quicker to poll this after
+	 * having sent the command opcode
+	 */
+	memset(&args, 0, sizeof(args));
+	args.taskfile.feature = SETFEATURES_DIS_RI;
+	args.taskfile.command = WIN_SETFEATURES;
+	ide_cmd_type_parser(&args);
+
+	if (ide_raw_taskfile(drive, &args, NULL)) {
+		printk("%s: disabling release interrupt fail\n", drive->name);
+		return 1;
+	}
+
+#ifdef IDE_TCQ_FIDDLE_SI
+	/*
+	 * enable SERVICE interrupt
+	 */
+	memset(&args, 0, sizeof(args));
+	args.taskfile.feature = SETFEATURES_EN_SI;
+	args.taskfile.command = WIN_SETFEATURES;
+	ide_cmd_type_parser(&args);
+
+	if (ide_raw_taskfile(drive, &args, NULL)) {
+		printk("%s: enabling service interrupt fail\n", drive->name);
+		return 1;
+	}
+#endif
+
+	return 0;
+}
+
+/*
+ * for now assume that command list is always as big as we need and don't
+ * attempt to shrink it on tcq disable
+ */
+static int enable_queued(struct ata_device *drive, int on)
+{
+	int depth = drive->using_tcq ? drive->queue_depth : 0;
+
+	/*
+	 * disable or adjust queue depth
+	 */
+	if (!on) {
+		if (drive->using_tcq)
+			printk("%s: TCQ disabled\n", drive->name);
+		drive->using_tcq = 0;
+		return 0;
+	}
+
+	if (configure_tcq(drive)) {
+		drive->using_tcq = 0;
+		return 1;
+	}
+
+	/*
+	 * enable block tagging
+	 */
+	if (!blk_queue_tagged(&drive->queue))
+		blk_queue_init_tags(&drive->queue, IDE_MAX_TAG);
+
+	/*
+	 * check auto-poll support
+	 */
+	check_autopoll(drive);
+
+	if (depth != drive->queue_depth)
+		printk("%s: tagged command queueing enabled, command queue depth %d\n", drive->name, drive->queue_depth);
+
+	drive->using_tcq = 1;
+	return 0;
+}
+
+static int tcq_wait_dataphase(struct ata_device *drive)
+{
+	u8 stat;
+	int i;
+
+	while ((stat = GET_STAT()) & BUSY_STAT)
+		udelay(10);
+
+	if (OK_STAT(stat, READY_STAT | DRQ_STAT, drive->bad_wstat))
+		return 0;
+
+	i = 0;
+	udelay(1);
+	while (!OK_STAT(GET_STAT(), READY_STAT | DRQ_STAT, drive->bad_wstat)) {
+		if (unlikely(i++ > IDE_TCQ_WAIT))
+			return 1;
+
+		udelay(10);
+	}
+
+	return 0;
+}
+
+ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+{
+	struct ata_channel *hwif = drive->channel;
+	unsigned int enable_tcq = 1;
+	u8 stat;
+	u8 feat;
+
+	switch (func) {
+		/*
+		 * invoked from a SERVICE interrupt, command etc already known.
+		 * just need to start the dma engine for this tag
+		 */
+		case ide_dma_queued_start:
+			TCQ_PRINTK("ide_dma: setting up queued %d\n", rq->tag);
+			if (!test_bit(IDE_BUSY, &HWGROUP(drive)->flags))
+				printk("queued_rw: IDE_BUSY not set\n");
+
+			if (tcq_wait_dataphase(drive))
+				return ide_stopped;
+
+			if (ide_start_dma(func, drive))
+				return ide_stopped;
+
+			set_irq(drive, ide_dmaq_intr);
+			if (!hwif->udma(ide_dma_begin, drive, rq))
+				return ide_started;
+
+			return ide_stopped;
+
+			/*
+			 * start a queued command from scratch
+			 */
+		case ide_dma_read_queued:
+		case ide_dma_write_queued: {
+			struct ata_taskfile *args = rq->special;
+
+			TCQ_PRINTK("%s: start tag %d\n", drive->name, rq->tag);
+
+			/*
+			 * set nIEN, tag start operation will enable again when
+			 * it is safe
+			 */
+			drive_ctl_nien(drive, 1);
+
+			OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
+
+			if (wait_altstat(drive, &stat, BUSY_STAT)) {
+				ide_dump_status(drive, "queued start", stat);
+				tcq_invalidate_queue(drive);
+				return ide_stopped;
+			}
+
+			drive_ctl_nien(drive, 0);
+
+			if (stat & ERR_STAT) {
+				ide_dump_status(drive, "tcq_start", stat);
+				return ide_stopped;
+			}
+
+			/*
+			 * drive released the bus, clear active tag and
+			 * check for service
+			 */
+			if ((feat = GET_FEAT()) & NSEC_REL) {
+				drive->immed_rel++;
+				HWGROUP(drive)->rq = NULL;
+				set_irq(drive, ide_dmaq_intr);
+
+				TCQ_PRINTK("REL in queued_start\n");
+
+				if ((stat = GET_STAT()) & SERVICE_STAT)
+					return service(drive);
+
+				return ide_released;
+			}
+
+			TCQ_PRINTK("IMMED in queued_start\n");
+			drive->immed_comp++;
+			return hwif->udma(ide_dma_queued_start, drive, rq);
+			}
+
+		case ide_dma_queued_off:
+			enable_tcq = 0;
+		case ide_dma_queued_on:
+			if (enable_tcq && !drive->using_dma)
+				return 1;
+			return enable_queued(drive, enable_tcq);
+		default:
+			break;
+	}
+
+	return 1;
+}
diff -urN linux-2.5.13/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.13/include/linux/ide.h	2002-05-03 02:22:44.000000000 +0200
+++ linux/include/linux/ide.h	2002-05-03 16:48:10.000000000 +0200
@@ -298,6 +298,7 @@
 	u8 tune_req;			/* requested drive tuning setting */
 
 	byte     using_dma;		/* disk is using dma for read/write */
+	byte	 using_tcq;		/* disk is using queueing */
 	byte	 retry_pio;		/* retrying dma capable host in pio */
 	byte	 state;			/* retry state */
 	byte     dsc_overlap;		/* flag: DSC overlap */
@@ -360,9 +361,17 @@
 	byte		dn;		/* now wide spread use */
 	byte		wcache;		/* status of write cache */
 	byte		acoustic;	/* acoustic management */
+	byte		queue_depth;	/* max queue depth */
 	unsigned int	failures;	/* current failure count */
 	unsigned int	max_failures;	/* maximum allowed failure count */
 	struct device	device;		/* global device tree handle */
+	/*
+	 * tcq statistics
+	 */
+	unsigned long	immed_rel;	
+	unsigned long	immed_comp;
+	int		max_last_depth;
+	int		max_depth;
 } ide_drive_t;
 
 /*
@@ -381,7 +390,10 @@
 		ide_dma_off,	ide_dma_off_quietly,	ide_dma_test_irq,
 		ide_dma_bad_drive,			ide_dma_good_drive,
 		ide_dma_verbose,			ide_dma_retune,
-		ide_dma_lostirq,			ide_dma_timeout
+		ide_dma_lostirq,			ide_dma_timeout,
+		ide_dma_read_queued,			ide_dma_write_queued,
+		ide_dma_queued_start,			ide_dma_queued_on,
+		ide_dma_queued_off,
 } ide_dma_action_t;
 
 enum {
@@ -400,7 +412,7 @@
 #ifdef CONFIG_BLK_DEV_IDEPCI
 	struct pci_dev	*pci_dev;	/* for pci chipsets */
 #endif
-	ide_drive_t	drives[MAX_DRIVES];	/* drive info */
+	struct ata_device drives[MAX_DRIVES];	/* drive info */
 	struct gendisk	*gd;		/* gendisk structure */
 
 	/*
@@ -409,32 +421,32 @@
 	 * A value of 255 indicates that the function should choose the optimal
 	 * mode itself.
 	 */
-	void (*tuneproc) (ide_drive_t *, byte pio);
-	int (*speedproc) (ide_drive_t *, byte pio);
+	void (*tuneproc) (struct ata_device *, byte pio);
+	int (*speedproc) (struct ata_device *, byte pio);
 
 	/* tweaks hardware to select drive */
-	void (*selectproc) (ide_drive_t *);
+	void (*selectproc) (struct ata_device *);
 
 	/* routine to reset controller after a disk reset */
-	void (*resetproc) (ide_drive_t *);
+	void (*resetproc) (struct ata_device *);
 
 	/* special interrupt handling for shared pci interrupts */
-	void (*intrproc) (ide_drive_t *);
+	void (*intrproc) (struct ata_device *);
 
 	/* special host masking for drive selection */
-	void (*maskproc) (ide_drive_t *, int);
+	void (*maskproc) (struct ata_device *, int);
 
 	/* adjust timing based upon rq->cmd direction */
-	void (*rwproc) (ide_drive_t *, ide_dma_action_t);
+	void (*rwproc) (struct ata_device *, ide_dma_action_t);
 
 	/* check host's drive quirk list */
-	int (*quirkproc) (ide_drive_t *);
+	int (*quirkproc) (struct ata_device *);
 
 	/* CPU-polled transfer routines */
-	void (*ata_read)(ide_drive_t *, void *, unsigned int);
-	void (*ata_write)(ide_drive_t *, void *, unsigned int);
-	void (*atapi_read)(ide_drive_t *, void *, unsigned int);
-	void (*atapi_write)(ide_drive_t *, void *, unsigned int);
+	void (*ata_read)(struct ata_device *, void *, unsigned int);
+	void (*ata_write)(struct ata_device *, void *, unsigned int);
+	void (*atapi_read)(struct ata_device *, void *, unsigned int);
+	void (*atapi_write)(struct ata_device *, void *, unsigned int);
 
 	int (*udma)(ide_dma_action_t, struct ata_device *, struct request *); /* dma read/write/abort routine */
 	unsigned int	*dmatable_cpu;	/* dma physical region descriptor table (cpu view) */
@@ -462,6 +474,7 @@
 	unsigned highmem	: 1;	/* can do full 32-bit dma */
 	unsigned no_io_32bit	: 1;	/* disallow enabling 32bit I/O */
 	unsigned no_unmask	: 1;	/* disallow setting unmask bit */
+	unsigned auto_poll	: 1;	/* supports nop auto-poll */
 	byte		io_32bit;	/* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
 	byte		unmask;		/* flag: okay to unmask other irqs */
 	byte		slow;		/* flag: slow data port */
@@ -470,7 +483,7 @@
 	unsigned long	last_time;	/* time when previous rq was done */
 #endif
 	byte		straight8;	/* Alan's straight 8 check */
-	int (*busproc)(ide_drive_t *, int);	/* driver soft-power interface */
+	int (*busproc)(struct ata_device *, int);	/* driver soft-power interface */
 	byte		bus_state;	/* power state of the IDE bus */
 };
 
@@ -501,6 +514,29 @@
 #define IDE_SLEEP	1
 #define IDE_DMA		2	/* DMA in progress */
 
+#define IDE_MAX_TAG	32
+
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+static inline int ata_pending_commands(struct ata_device *drive)
+{
+	if (drive->using_tcq)
+		return blk_queue_tag_depth(&drive->queue);
+
+	return 0;
+}
+
+static inline int ata_can_queue(struct ata_device *drive)
+{
+	if (drive->using_tcq)
+		return blk_queue_tag_queue(&drive->queue);
+
+	return 1;
+}
+#else
+#define ata_pending_commands(drive)	(0)
+#define ata_can_queue(drive)		(1)
+#endif
+
 typedef struct hwgroup_s {
 	ide_startstop_t (*handler)(struct ata_device *, struct request *);	/* irq handler, if active */
 	unsigned long flags;		/* BUSY, SLEEPING */
@@ -746,14 +782,14 @@
 	ide_startstop_t (*handler)(struct ata_device *, struct request *);
 };
 
-extern void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount);
-extern void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount);
+extern void ata_read(struct ata_device *, void *, unsigned int);
+extern void ata_write(struct ata_device *, void *, unsigned int);
 
-extern void atapi_read(ide_drive_t *drive, void *buffer, unsigned int bytecount);
-extern void atapi_write(ide_drive_t *drive, void *buffer, unsigned int bytecount);
+extern void atapi_read(struct ata_device *, void *, unsigned int);
+extern void atapi_write(struct ata_device *, void *, unsigned int);
 
-extern ide_startstop_t ata_taskfile(ide_drive_t *drive,
-		struct ata_taskfile *args, struct request *rq);
+extern ide_startstop_t ata_taskfile(struct ata_device *,
+	struct ata_taskfile *, struct request *);
 
 /*
  * Special Flagged Register Validation Caller
@@ -838,9 +874,9 @@
 extern int idescsi_init (void);
 #endif
 
-ide_drive_t *ide_scan_devices (byte media, const char *name, struct ata_operations *driver, int n);
-extern int ide_register_subdriver(ide_drive_t *drive, struct ata_operations *driver);
-extern int ide_unregister_subdriver(ide_drive_t *drive);
+extern struct ata_device *ide_scan_devices(byte, const char *, struct ata_operations *, int);
+extern int ide_register_subdriver(struct ata_device *, struct ata_operations *);
+extern int ide_unregister_subdriver(struct ata_device *drive);
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
 # define ON_BOARD		1
@@ -854,21 +890,22 @@
 void __init ide_scan_pcibus(int scan_direction);
 #endif
 #ifdef CONFIG_BLK_DEV_IDEDMA
-int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func);
-void ide_destroy_dmatable (ide_drive_t *drive);
+extern int ide_build_dmatable(struct ata_device *, ide_dma_action_t);
+extern void ide_destroy_dmatable(struct ata_device *);
 extern ide_startstop_t ide_dma_intr(struct ata_device *, struct request *);
-int check_drive_lists (ide_drive_t *drive, int good_bad);
-int ide_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *);
-extern void ide_release_dma(struct ata_channel *hwif);
-extern void ide_setup_dma(struct ata_channel *hwif,
-		unsigned long dmabase, unsigned int num_ports) __init;
+extern int check_drive_lists(struct ata_device *, int good_bad);
+extern int ide_dmaproc(ide_dma_action_t func, struct ata_device *, struct request *);
+extern ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t, struct ata_device *, struct request *);
+extern void ide_release_dma(struct ata_channel *);
+extern void ide_setup_dma(struct ata_channel *,	unsigned long, unsigned int) __init;
+extern int ide_start_dma(ide_dma_action_t, struct ata_device *);
 #endif
 
 extern spinlock_t ide_lock;
 
 #define DRIVE_LOCK(drive)		((drive)->queue.queue_lock)
 
-extern int drive_is_ready(ide_drive_t *drive);
+extern int drive_is_ready(struct ata_device *drive);
 extern void revalidate_drives(void);
 
 #endif

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

* Re: [PATCH] 2.5.13 IDE 50
  2002-05-03 12:59 ` [PATCH] 2.5.13 IDE 50 Martin Dalecki
@ 2002-05-03 18:12   ` Tim Schmielau
  2002-05-04 23:53     ` Martin Dalecki
  0 siblings, 1 reply; 39+ messages in thread
From: Tim Schmielau @ 2002-05-03 18:12 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Andreas Dilger, Kernel Mailing List


> - Fix wrong usage of time_after in ide.c. This should cure the drive 
> seek
>    timeout problems some people where expierencing. This was clarified 
> to me by
>    Bartek, who apparently checked whatever the actual code is consistent 
> with the comments in front of it. Thank you Bartlomiej Zolnierkiewicz.
> 
>    I think now that we should have time_past(xxx) in <linux/timer.h>.

What would you suppose time_past(xxx) to do?

I agree this calls for some action to prevent confusion in the future.
However, I'm not sure how a new macro could help here.

Andreas Dilger once did a patch to clarify the documentation of
time_[before,after] a bit.
(http://www.lib.uaa.alaska.edu/linux-kernel/archive/2001-Week-45/0075.html)

> @@ -1258,7 +1172,7 @@
>  
>                         /* This device still wants to remain idle.
>                          */
> -                       if (drive->sleep && time_after(jiffies, drive->sleep))
> +                       if (drive->sleep && time_after(drive->sleep, jiffies))
>                                 continue;
>  
>                         /* Take this device, if there is no device choosen thus
> 

I think there is an implicit notational convention to have the volatile 
argument, i.e. jiffies, first. This would express that the condition 
evaluates as true *before* some fixed point in time:

   if (drive->sleep && time_before(jiffies, drive->sleep))

Maybe sticking to this convention would suffice to keep the 
semantics of the condition obvious.

Tim






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

* Re: [PATCH] 2.5.13 IDE 50
  2002-05-03 18:12   ` Tim Schmielau
@ 2002-05-04 23:53     ` Martin Dalecki
  2002-05-05 17:08       ` Denis Vlasenko
  0 siblings, 1 reply; 39+ messages in thread
From: Martin Dalecki @ 2002-05-04 23:53 UTC (permalink / raw)
  To: Tim Schmielau; +Cc: Andreas Dilger, Kernel Mailing List

Uz.ytkownik Tim Schmielau napisa?:
>>- Fix wrong usage of time_after in ide.c. This should cure the drive 
>>seek
>>   timeout problems some people where expierencing. This was clarified 
>>to me by
>>   Bartek, who apparently checked whatever the actual code is consistent 
>>with the comments in front of it. Thank you Bartlomiej Zolnierkiewicz.
>>
>>   I think now that we should have time_past(xxx) in <linux/timer.h>.
> 
> 
> What would you suppose time_past(xxx) to do?


Taking only a single parameter and telling whatever jiffies is bigger
then it. Just that. Becouse if you grep for time_after or time_before
you would realize immediately that nearly all of them take
the variable jiffies as parameter.



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

* Re: [PATCH] 2.5.13 IDE 50
  2002-05-04 23:53     ` Martin Dalecki
@ 2002-05-05 17:08       ` Denis Vlasenko
  0 siblings, 0 replies; 39+ messages in thread
From: Denis Vlasenko @ 2002-05-05 17:08 UTC (permalink / raw)
  To: Martin Dalecki, Tim Schmielau; +Cc: Andreas Dilger, Kernel Mailing List

On 4 May 2002 21:53, Martin Dalecki wrote:
> Uz.ytkownik Tim Schmielau napisa?:
> >>- Fix wrong usage of time_after in ide.c. This should cure the drive
> >>seek
> >>   timeout problems some people where expierencing. This was clarified
> >>to me by
> >>   Bartek, who apparently checked whatever the actual code is consistent
> >>with the comments in front of it. Thank you Bartlomiej Zolnierkiewicz.
> >>
> >>   I think now that we should have time_past(xxx) in <linux/timer.h>.
> >
> > What would you suppose time_past(xxx) to do?
>
> Taking only a single parameter and telling whatever jiffies is bigger
> then it. Just that. Becouse if you grep for time_after or time_before
> you would realize immediately that nearly all of them take
> the variable jiffies as parameter.

Just in case it will be done: call it
jiffies_before(x) and jiffies_after(x), this sounds unambiguous IMHO.
--
vda

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

end of thread, other threads:[~2002-05-05 12:06 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-18 20:47 Linux 2.5.7 Linus Torvalds
2002-03-18 21:57 ` Xavier Bestel
2002-03-28  9:21 ` [PATCH] 2.5.7 IDE 23 Martin Dalecki
2002-03-28  9:23 ` PATCH 2.5.7 IDE 24 Martin Dalecki
2002-03-28  9:29   ` Zwane Mwaikambo
2002-03-28  9:25 ` [PATCH] 2.5.7 IDE 25 Martin Dalecki
2002-03-28  9:29 ` [PATCH] 2.5.7 IDE 26 Martin Dalecki
2002-03-28 20:34   ` Vojtech Pavlik
2002-03-28 20:58     ` Anton Altaparmakov
2002-03-29 13:53       ` Martin Dalecki
2002-03-28  9:31 ` [PATCH] 2.5.7 IDE 27 Martin Dalecki
2002-03-28 18:01   ` Davide Libenzi
2002-03-29 13:49     ` Martin Dalecki
2002-03-29 20:39       ` Davide Libenzi
2002-03-28  9:32 ` [PATCH] 2.5.7 IDE 28a Martin Dalecki
2002-04-15  7:42 ` [PATCH] 2.5.8 IDE 34 Martin Dalecki
2002-04-15  8:51   ` Jens Axboe
2002-04-15  8:11     ` Martin Dalecki
2002-04-22 15:36 ` [PATCH] 2.5.8 IDE 40 Martin Dalecki
2002-04-25 14:32 ` [PATCH] 2.5.10 IDE 41 Martin Dalecki
2002-04-25 17:39   ` Jens Axboe
2002-04-25 17:18     ` Martin Dalecki
2002-04-29  8:21       ` Jens Axboe
2002-04-30  8:09 ` [PATCH] 2.5.11 IDE 46 Martin Dalecki
2002-04-30  8:11 ` Linux 2.5.7 Martin Dalecki
2002-04-30  8:45 ` [PATCH] 2.5.11 IDE 47 Martin Dalecki
2002-04-30 15:16 ` [PATCH] 2.5.11 IDE 48 Martin Dalecki
2002-05-02  8:39 ` [PATCH] 2.5.12 IDE 49 Martin Dalecki
2002-05-02  8:42 ` Linux 2.5.7 Martin Dalecki
2002-05-02 13:22   ` Dave Jones
2002-05-02 12:44     ` Martin Dalecki
2002-05-02 13:54       ` David Woodhouse
2002-05-02 13:02         ` Martin Dalecki
2002-05-02 14:06           ` David Woodhouse
2002-05-03 12:59 ` [PATCH] 2.5.13 IDE 50 Martin Dalecki
2002-05-03 18:12   ` Tim Schmielau
2002-05-04 23:53     ` Martin Dalecki
2002-05-05 17:08       ` Denis Vlasenko
2002-05-03 14:48 ` [PATCH] 2.5.13 IDE 51 Martin Dalecki

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