2002-03-18 20:49:28

by Linus Torvalds

[permalink] [raw]
Subject: Linux 2.5.7


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

<[email protected]> (02/03/16 1.522.1.1)
Link drivers/fc4/fc4.a only once.

<[email protected]> (02/03/16 1.522.1.2)
Descend into drivers/parport only if CONFIG_PARPORT is set.

<[email protected]> (02/03/16 1.522.1.3)
Descend into drivers/hotplug only if CONFIG_HOTPLUG_PCI is set.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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().

<[email protected]> (02/03/17 1.524.1.5)
USB HID driver

Workaround for the ATEN switches

<[email protected]> (02/03/17 1.524.1.6)
USB printer patch

added NEC printer to quirks list

<[email protected]> (02/03/17 1.526)
Switch cramfs and zisofs from zlib_fs to common zlib.
Remove remnants of zlib_fs.

<[email protected]> (02/03/17 1.384.4.15)
Fix netfilter IPv4 conntrack build.

<[email protected]> (02/03/17 1.384.4.16)
Make wanpipe build again after struct sock cleanups.
From Arnaldo Carvalho de Melo.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/18 1.524.2.5)
[PATCH] struct super_block cleanup - isofs

Seperates isofs_sb_info from struct super_block.

<[email protected]> (02/03/18 1.524.2.6)
[PATCH] struct super_block cleanup - udf

Seperates udf_sb_info from struct super_block.

<[email protected]> (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

<[email protected]> (02/03/18 1.528)
[PATCH] struct super_block cleanup - shmem

Seperates shmem_sb_info from struct super_block.

<[email protected]> (02/03/18 1.529)
[PATCH] struct super_block cleanup - hfs

Seperates hfs_sb_info from struct super_block.

<[email protected]> (02/03/18 1.530)
[PATCH] struct super_block cleanup - affs

Seperates affs_sb_info from struct super_block.

<[email protected]> (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).

<[email protected]> (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

<[email protected]> (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.

<[email protected]> (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__.

<[email protected]> (02/03/18 1.535)
[PATCH] cleanup FAT stuff (2/2)

This patch remove unused variable/function/define, and small indent
cleanup.

<[email protected]> (02/03/18 1.536)
Include <linux/completion.h> for completion user

<[email protected]> (02/03/18 1.537)
Update version


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

<[email protected]> (02/03/11 1.384.3.1)
pcnet32 net driver updates 1/6:
fix leak in pci memory space on machines with IOMMUs.

<[email protected]> (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

<[email protected]> (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

<[email protected]> (02/03/11 1.384.3.4)
pcnet32 net driver updates 4/6:
Increase device watchdog timeout, fix from Dave Engebretsen.

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (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.

<[email protected]> (02/03/11 1.375.25.4)
[PATCH] HP Sim config patch

Offer loopback driver and network block device support for HP Sim.

<[email protected]> (02/03/11 1.375.25.5)
siginfo.h:
Define SI_DETHREAD.

<[email protected]> (02/03/11 1.375.25.6)
smp.c:
Remove task-migration IPI. It's been replaced
by Ingo's migration threads.

<[email protected]> (02/03/11 1.375.25.7)
Sync with Linus' v2.5.6 tree.

<[email protected]> (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.

<[email protected]> (02/03/12 1.384.10.1)
e100 net driver updates from Intel:
* fix zerocopy
* add suspend/resume

<[email protected]> (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

<[email protected]> (02/03/12 1.388.2.2)
Increase eepro100 net driver tx/rx ring sizes, to be more appropriate for 100mbit.

<[email protected]> (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

<[email protected]> (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

<[email protected]> (02/03/12 1.388.2.5)
Update eepro100 net driver to enable/disable its software timer
at suspend/resume time.

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

<[email protected]> (02/03/12 1.388.2.7)
Move pci_enable_device and associated code above first PCI resource info access.

<[email protected]> (02/03/12 1.388.2.8)
Build fix: include linux/crc32.h in bmac net driver.

Noticed by Joshua Uziel.

<[email protected]> (02/03/12 1.420)
Update defconfig for VLAN and IDE changes

<[email protected]> (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.

<[email protected]> (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...

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (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

<[email protected]> (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

<[email protected]> (02/03/12 1.424)
[PATCH] struct super_block cleanup - ncpfs

Seperates ncp_sb_info from struct super_block.

<[email protected]> (02/03/12 1.425)
[PATCH] struct super_block cleanup - ext2

Abstract access to ext2_sb_info.

<[email protected]> (02/03/12 1.426)
[PATCH] struct super_block cleanup - ext2

Complete the ext2 superblock seperation.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (02/03/12 1.430)
[PATCH] (2/4) smarter nfs_get_sb()

Export sget(9), deactivate_super(9) and set_anon_sb(9)

<[email protected]> (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()

<[email protected]> (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.

<[email protected]> (02/03/12 1.433)
[PATCH] removal of ->u.romfs_i


<[email protected]> (02/03/12 1.434)
[PATCH] struct super_block cleanup - efs

Separates efs_sb_info from struct super_block.

<[email protected]> (02/03/12 1.415.2.1)
Make pdev_set_mwi static, at the request of David Miller.

<[email protected]> (02/03/13 1.415.1.2)
Fix e100 net driver typo, from last change.

Contributor: Eli Kupermann @ Intel

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/13 1.443)
[PATCH] v4l: maxiradio update

This patch updates the Maxi FM2000 Radio driver.

<[email protected]> (02/03/13 1.444)
[PATCH] v4l: maestro radio update

This patch updates the maestro radio driver.

<[email protected]> (02/03/13 1.445)
[PATCH] v4l: gemtek radio update

This patch updates the gemtek and gemtek pci radio drivers.

<[email protected]> (02/03/13 1.446)
[PATCH] v4l: cadet radio update

This is the cadet radio driver update.

<[email protected]> (02/03/13 1.447)
[PATCH] v4l: aimslab radio update

Here comes the aimslab radio driver update.

<[email protected]> (02/03/13 1.448)
[PATCH] v4l: aztech radio update

Here comes the aztech radio driver update.

<[email protected]> (02/03/13 1.449)
[PATCH] v4l: radiotrack driver update

This patch updates the radiotrack driver.

<[email protected]> (02/03/13 1.450)
[PATCH] v4l: sf16fm radio update

This patch updates the sf16fm radio driver.

<[email protected]> (02/03/13 1.451)
[PATCH] v4l: terratec radio update

This is the update for the terratec radio driver.

<[email protected]> (02/03/13 1.452)
[PATCH] v4l: typhoon radio update

This is the update for the typhoon radio driver.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/13 1.457)
[PATCH] v4l:

This patch adapts the se401 driver to the videodev changes and fixes the
unplug race.

<[email protected]> (02/03/13 1.458)
[PATCH] v4l: quickcam update

This patch updates the parallel port quickcam drivers (bw+color).

<[email protected]> (02/03/13 1.459)
[PATCH] v4l: saa5249 videotext driver update

This patch updates the saa5249 videotext driver.

<[email protected]> (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 ...

<[email protected]> (02/03/13 1.461)
[PATCH] v4l: trust radio update

This is the update for the trust radio driver.

<[email protected]> (02/03/13 1.462)
[PATCH] v4l: DSB usb radio driver update

This patch adapts the DSB usb radio driver to the videodev changes.

<[email protected]> (02/03/13 1.463)
[PATCH] v4l: mediavision pms update

This patch updates the mediavision pms video driver.

<[email protected]> (02/03/13 1.464)
[PATCH] v4l: w9966 update

This patch updates the Winbond w9966cf parport webcam driver.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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, ...

<[email protected]> (02/03/13 1.469)
[PATCH] v4l: bttv doc update

This patch updates the documentation for the bttv driver.

<[email protected]> (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.

<[email protected]> (02/03/13 1.388.1.19)
[PATCH] Fix ia64 perfmon for 2.5.6

Fix up earlier perfmon breakage.

<[email protected]> (02/03/13 1.415.3.2)
email address changes.

<[email protected]> (02/03/13 1.415.3.3)
USB pegasus driver

Elcon vendor/device support added.

<[email protected]> (02/03/13 1.415.3.4)
USB edgeport driver

Fixed bug that prevented multiple edgeport devices from working at once.

<[email protected]> (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

<[email protected]> (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

<[email protected]> (02/03/13 1.384.4.12)
Fix IPv4 multicast router build failure caused
by struct sock cleanups.

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/13 1.388.1.20)
offsets.h:
Update offsets.h
defconfig:
Update defconfig.

<[email protected]> (02/03/13 1.388.1.21)
[PATCH] More 2.5.6 sync up.

Take advantage of new per-CPU scheme.

<[email protected]> (02/03/13 1.384.7.16)
Sparc64 build fix:
Kill references to obsolete BLK{F}RA{SET,GET} ioctls.

<[email protected]> (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.

<[email protected]> (02/03/13 1.388.4.1)
[PATCH] More 2.5.6 sync up.

Take advantage of new per-CPU scheme.

<[email protected]> (02/03/13 1.384.7.17)
Stack overflow debugging support.
From Kanoj Sarcar.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/13 1.384.7.19)
On sparc64, do not put PAGE_OFFSET in g4 anymore,
put current task there instead.

<[email protected]> (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.

<[email protected]> (02/03/14 1.473.3.1)
Port the MotionEye driver to the new video4linux API.

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (02/03/15 1.473.4.3)
e100 net driver update 1/4:
- minor changes to the license from our technical writer [still GPL ;-)]

<[email protected]> (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

<[email protected]> (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.

<[email protected]> (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).

<[email protected]> (02/03/15 1.473.4.8)
acenic gige net driver updates:
* various small cleanups
* ETHTOOL_GDRVINFO support

<[email protected]> (02/03/15 1.473.4.9)
acenic gige net driver fixes:
* fix Tigon I support
* fix memory leak

<[email protected]> (02/03/15 1.473.4.10)
acenic gige net driver update: merge VLAN support from 2.4.x kernel

<[email protected]> (02/03/15 1.473.2.2)
clgenfb fixes for zorro bus. clgenfb should work again on m68k.

<[email protected]> (02/03/15 1.473.2.3)
Fix rocketport serial driver for kdev_t changes in early 2.5.x series.

<[email protected]> (02/03/15 1.473.2.4)
Janitor: request_region cleanups for stallion serial driver

<[email protected]> (02/03/15 1.473.4.11)
lance net driver update: mark lance_probe as __init

<[email protected]> (02/03/15 1.473.2.5)
Fix via audio recording, when frag size < page size.

<[email protected]> (02/03/15 1.473.2.6)
Add new slicecom/munish WAN driver.

<[email protected]> (02/03/15 1.473.4.12)
Convert hp100 net driver to PCI DMA mapping API. (fixes build)

<[email protected]> (02/03/15 1.473.4.13)
Don't include linux/delay.h twice in eepro100 net driver.

Noticed by Alan Cox.

<[email protected]> (02/03/15 1.473.4.14)
Fix e1000 net driver build with newer binutils.

<[email protected]> (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

<[email protected]> (02/03/15 1.473.2.7)
Add BK kernel howto text and some helper scripts to
new subdirectory linux/Documentation/BK-usage.

<[email protected]> (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.

<[email protected]> (02/03/15 1.473.6.1)
Fix drivers/pnp/Makefile to correctly list multi-part
objects in $(list-multi), instead of $(multi-objs)

<[email protected]> (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.


<[email protected]> (02/03/15 1.473.6.3)
Remove link rules for multi-part drivers in drivers/isdn/*/Makefile.

<[email protected]> (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.

<[email protected]> (02/03/15 1.484)
Cleanup: use list macros for task list

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/15 1.491)
[PATCH] fix for leaks in nfsd

Several exits in exp_export() forget to call path_release(). Fixed.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/15 1.494)
[PATCH] nfsd-as-fs NULL ptr fix

It needs the following patch

<[email protected]> (02/03/15 1.495)
Fix up architectures for task list changes

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/15 1.499)
[PATCH] struct super_block cleanup - smbfs

Seperates smb_sb_info from struct super_block.

<[email protected]> (02/03/15 1.500)
[PATCH] struct super_block cleanup - qnx4

Seperates qnx4_sb_info from struct super_block.

<[email protected]> (02/03/15 1.501)
[PATCH] struct super_block cleanup - msdos/vfat

Don't print out FAT superblock warnings if the IO failed.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/15 1.508)
[PATCH] ACPI patch 5/9

This is the update to the core interpreter code.

<[email protected]> (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.

<[email protected]> (02/03/15 1.510)
[PATCH] ACPI patch 7/9

This updates the Configure.help, both in arch/i386, and in drivers/acpi.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (02/03/15 1.517)
Trivial compile fix

<[email protected]> (02/03/15 1.518)
[PATCH] 2.5.7-pre1 Code cleanup for BSD accounting.

Clean up BSD accounting locking code..

<[email protected]> (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.

<[email protected]> (02/03/15 1.520)
Make sk_flags unsigned long, since we do bit operations on it

<[email protected]> (02/03/15 1.521)
Update kernel version

<[email protected]> (02/03/15 1.522)
update


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

<[email protected]> (02/03/08 1.385)
Fix parport_cs compile troubles

<[email protected]> (02/03/08 1.386)
Split out "msync" logic into a file of its own. No actual code
changes.

<[email protected]> (02/03/08 1.387)
msync cleanups

<[email protected]> (02/03/08 1.388)
mm cleanup: split out mincore() system call from filemap.c

<[email protected]> (02/03/08 1.389)
Fix missing '!' in set_fs_altroot()

<[email protected]> (02/03/09 1.369.15.1)
ia64-patches

<[email protected]> (02/03/09 1.369.15.2)
This patch got dropped from the VM_DATA_DEFAULT_FLAGS patch sent earlier.

<[email protected]> (02/03/09 1.369.15.3)
Update EFI RTC driver to version 0.3.

<[email protected]> (02/03/09 1.369.15.4)
Fix two typos in comments.

<[email protected]> (02/03/09 1.375.2.18)
[PATCH] 1033/1: latest 2.5.x badge4 def-config

<[email protected]> (02/03/09 1.369.15.5)
p4

<[email protected]> (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.

<[email protected]> (02/03/09 1.369.15.7)
as-flags.diff

<[email protected]> (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


<[email protected]> (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


<[email protected]> (02/03/09 1.384.1.1)
Update Makefile, sa1110 cpufreq code. Drop static flash mapping from
system3.c

<[email protected]> (02/03/09 1.375.25.2)
Fixup bad merge.

<[email protected]> (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 :)

<[email protected]> (02/03/09 1.375.25.3)
Fix formatting in Makefile.

<[email protected]> (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

<[email protected]> (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

<[email protected]> (02/03/10 1.384.2.1)
Make iq80310_gettimeoffset() return the currect time delta.
Remove redundant irq_enter/irq_exit calls.

<[email protected]> (02/03/10 1.384.2.2)
Fix up couple of bugs in Integrator PCI code.

<[email protected]> (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.


<[email protected]> (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.

<[email protected]> (02/03/10 1.384.2.4)
Split out copy_user_page/clear_user_page to allow more efficient
selection depending on processor features.

<[email protected]> (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).

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/11 1.384.4.4)
Do not report inode numbers as negative
in networking procfs nodes

<[email protected]> (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.

<[email protected]> (02/03/11 1.384.4.6)
Never set IP_DF for ICMP packets.

<[email protected]> (02/03/11 1.384.4.7)
RED packet scheduler bug fixes from
Jamal Hadi Salim.

<[email protected]> (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.

<[email protected]> (02/03/11 1.384.4.9)
sock_register inet6_family_ops before we do init
calls which might try to create ipv6 sockets.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/11 1.384.5.2)
Fix CAN_MIGRATE_TASK macro to use p arg it gets
instead of tmp explicitly.

<[email protected]> (02/03/11 1.384.5.3)
Use cpu_logical_map as appropriate.

<[email protected]> (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.

<[email protected]> (02/03/11 1.384.6.1)
Add back check_pgt_cache call.
Add nop definition for x86.

<[email protected]> (02/03/11 1.384.6.2)
Fix typos.

<[email protected]> (02/03/11 1.384.1.8)
Fix up spinlocking/IRQ handling in SCSI drivers for Acorn machines.

<[email protected]> (02/03/11 1.384.1.9)
Bug fixes for Acorn network drivers.

<[email protected]> (02/03/11 1.384.1.10)
Update Acorn serial drivers.

<[email protected]> (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

<[email protected]> (02/03/11 1.384.7.2)
Do not expand stack for non-faulting loads

<[email protected]> (02/03/11 1.384.7.3)
Fix PCI IRQ probing for some bridging situations.
Use PCI_SLOT instead of hard-coded shift.

<[email protected]> (02/03/11 1.384.7.4)
Use pci_memspace_mask instead of hard-coded
value 0xffffffff.

<[email protected]> (02/03/11 1.384.7.5)
Work around some hw bugs in Schizo PCI controllers.

<[email protected]> (02/03/11 1.384.7.6)
Use dma_addr_t for hblock_dvma.
Make device probe failure more robust.

<[email protected]> (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.

<[email protected]> (02/03/11 1.384.7.8)
Read lock around files->fd[] accesses.

<[email protected]> (02/03/11 1.384.7.9)
Add SI_DETHREAD

<[email protected]> (02/03/11 1.384.7.10)
Add per_cpu linker script bits for Sparc.

<[email protected]> (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.

<[email protected]> (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...

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/11 1.388.1.8)
[PATCH] 2.5.6-pre3 Fix BSD accounting rlimit

Fix rlimit on accounting file.

<[email protected]> (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.

<[email protected]> (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

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/11 1.388.1.14)
[PATCH] (3/4) ->kill_sb() switchover

The rest of nodev filesystems switched.

<[email protected]> (02/03/11 1.388.1.15)
[PATCH] (4/4) ->kill_sb() switchover

bdev filesystems switched. Changes documented in Locking and porting.

<[email protected]> (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.

<[email protected]> (02/03/12 1.384.1.11)
Add /dev/rtc support for Acorn machines.

<[email protected]> (02/03/12 1.384.1.12)
Update ARM tree for 2.5.6

<[email protected]> (02/03/11 1.384.7.11)
Update sparc64 defconfig.

<[email protected]> (02/03/11 1.384.7.12)
Add sys_sendfile64 to sparc syscall tables.

<[email protected]> (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.

<[email protected]> (02/03/12 1.384.7.13)
Fix sys32_sendfile64 implementation.

<[email protected]> (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 <[email protected]>

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).

<[email protected]> (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.

<[email protected]> (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().

<[email protected]> (02/03/12 1.396)
[PATCH] struct superblock cleanup - minixfs

Switch to using kmalloc to allocate the minix superblock structure.

<[email protected]> (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 <[email protected]>.

<[email protected]> (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.

<[email protected]> (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).

<[email protected]> (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().

<[email protected]> (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'.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (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().

<[email protected]> (02/03/12 1.408)
[PATCH] struct super_block cleanup - cramfs

Seperates cramfs_sb_info from struct super_block.

<[email protected]> (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.

<[email protected]> (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).

<[email protected]> (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.

<[email protected]> (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.

<[email protected]> (02/03/12 1.384.7.14)
Include asm/page.h in sparc64 thread_info.h

<[email protected]> (02/03/12 1.419)
Update kernel version



2002-03-18 21:56:26

by Xavier Bestel

[permalink] [raw]
Subject: Re: Linux 2.5.7

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


2002-03-28 09:26:05

by Martin Dalecki

[permalink] [raw]
Subject: PATCH 2.5.7 IDE 24

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);


Attachments:
ide-clean-24.diff (11.52 kB)

2002-03-28 09:24:15

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.7 IDE 23

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


Attachments:
ide-clean-23.diff (29.37 kB)

2002-03-28 09:27:46

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.7 IDE 25

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 <[email protected]>
*
* 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;


Attachments:
ide-clean-25.diff (28.36 kB)

2002-03-28 09:31:55

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.7 IDE 26

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.


Attachments:
ide-clean-26.diff.gz (29.69 kB)

2002-03-28 09:33:46

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.7 IDE 27

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 */
};

/*


Attachments:
ide-clean-27.diff (50.75 kB)

2002-03-28 09:35:07

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.7 IDE 28a

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;
};


Attachments:
ide-clean-28a.diff (32.19 kB)

2002-03-28 09:41:46

by Zwane Mwaikambo

[permalink] [raw]
Subject: Re: PATCH 2.5.7 IDE 24


But i haven't even tried 23 yet!!

--
http://function.linuxpower.ca


2002-03-28 17:56:06

by Davide Libenzi

[permalink] [raw]
Subject: Re: [PATCH] 2.5.7 IDE 27

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


2002-03-28 20:34:49

by Vojtech Pavlik

[permalink] [raw]
Subject: Re: [PATCH] 2.5.7 IDE 26

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

2002-03-28 20:59:00

by Anton Altaparmakov

[permalink] [raw]
Subject: Re: [PATCH] 2.5.7 IDE 26

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/

2002-03-29 13:51:09

by Martin Dalecki

[permalink] [raw]
Subject: Re: [PATCH] 2.5.7 IDE 27

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?

2002-03-29 13:55:39

by Martin Dalecki

[permalink] [raw]
Subject: Re: [PATCH] 2.5.7 IDE 26

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.

2002-03-29 20:34:41

by Davide Libenzi

[permalink] [raw]
Subject: Re: [PATCH] 2.5.7 IDE 27

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



2002-04-15 08:45:08

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.8 IDE 34

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 <[email protected]>
* Copyright (C) 1996-1998 Erik Andersen <[email protected]>
* Copyright (C) 1998-2000 Jens Axboe <[email protected]>
@@ -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 <[email protected]> for diagnosing this.
+ * showed up if the drive returned data in 512 byte
+ * blocks (like Pioneer drives). Thanks to
+ * Richard Hirst <[email protected]> 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 <[email protected]>).
+ * from Holger Dietze <[email protected]>).
* 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 <[email protected]>.)
* 3.15 July 2, 1996 -- Added support for Sanyo 3 CD changers
- * from Ben Galliart <[email protected]> with
- * special help from Jeff Lightfoot
- * <[email protected]>
+ * from Ben Galliart <[email protected]> with
+ * special help from Jeff Lightfoot
+ * <[email protected]>
* 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 <[email protected]>
+ * Erik B. Andersen <[email protected]>
* -- 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 <[email protected]>
- * 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 ([email protected])
+ * 4.04 Dec 29, 1996 -- Added CDROMREADRAW ioclt based on patch
+ * by Aleks Makarov ([email protected])
*
* 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
- * <[email protected]>, a patch for 2.0.33
- * by Toni Giorgino <[email protected]>, the SCSI
- * version, and my own efforts. -erik
+ * based on a patch for 2.0.33 by Jelle Foks
+ * <[email protected]>, a patch for 2.0.33
+ * by Toni Giorgino <[email protected]>, 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" <[email protected]>
+ * 4.15 Aug 25, 1998 -- Updated ide-cd.h to respect mechine endianess,
+ * patch thanks to "Eddie C. Dost" <[email protected]>
*
* 4.50 Oct 19, 1998 -- New maintainers!
- * Jens Axboe <[email protected]>
- * Chris Zwilling <[email protected]>
+ * Jens Axboe <[email protected]>
+ * Chris Zwilling <[email protected]>
*
* 4.51 Dec 23, 1998 -- Jens Axboe <[email protected]>
* - 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 <[email protected]>
*
*************************************************************************/
-
+
#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;
}


Attachments:
ide-clean-34.diff (51.06 kB)

2002-04-15 08:52:07

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] 2.5.8 IDE 34

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

2002-04-15 09:14:07

by Martin Dalecki

[permalink] [raw]
Subject: Re: [PATCH] 2.5.8 IDE 34

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".

2002-04-22 16:39:12

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.8 IDE 40

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
*/


Attachments:
ide-clean-40.diff (4.27 kB)

2002-04-25 15:35:04

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.10 IDE 41

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 <[email protected]>
- *
- * 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 */


Attachments:
ide-clean-41.diff (83.40 kB)

2002-04-25 17:39:08

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] 2.5.10 IDE 41

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

2002-04-25 18:21:24

by Martin Dalecki

[permalink] [raw]
Subject: Re: [PATCH] 2.5.10 IDE 41

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.

2002-04-29 08:21:42

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] 2.5.10 IDE 41

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

2002-04-30 16:19:55

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.11 IDE 48

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
*/


Attachments:
ide-clean-48.diff (20.76 kB)

2002-04-30 09:12:15

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.11 IDE 46


- 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.


Attachments:
ide-clean-46.diff.gz (29.19 kB)

2002-04-30 09:14:01

by Martin Dalecki

[permalink] [raw]
Subject: Re: Linux 2.5.7

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 */


Attachments:
ide-clean-47.diff (28.08 kB)

2002-04-30 09:48:33

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.11 IDE 47

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 */


Attachments:
ide-clean-47.diff (28.08 kB)